diff --git a/db/tournamentpages/admin.py b/db/tournamentpages/admin.py deleted file mode 100644 index 8c38f3f..0000000 --- a/db/tournamentpages/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/db/tournamentpages/models.py b/db/tournamentpages/models.py deleted file mode 100644 index 71a8362..0000000 --- a/db/tournamentpages/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/db/tournamentpages/tests.py b/db/tournamentpages/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/db/tournamentpages/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/db/tournamentpages/views.py b/db/tournamentpages/views.py deleted file mode 100644 index 91ea44a..0000000 --- a/db/tournamentpages/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/pdlzbs/settings.py b/pdlzbs/settings.py index 4f2796f..cacdd54 100644 --- a/pdlzbs/settings.py +++ b/pdlzbs/settings.py @@ -55,12 +55,14 @@ INSTALLED_APPS = [ 'db.atu', 'db.mbkb', 'theme', - 'core' + 'core', + 'tournamentpages' ] + [ 'tailwind', 'tinymce', 'filebrowser', 'admin_ordering', + 'tabbed_admin', 'django_browser_reload' ] @@ -169,3 +171,5 @@ TINYMCE_SPELLCHECKER = True FILEBROWSER_DIRECTORY = '' FILEBROWSER_EXCLUDE = [r'^_versions'] + +TABBED_ADMIN_USE_JQUERY_UI = True diff --git a/pdlzbs/urls.py b/pdlzbs/urls.py index f8363a2..109e3e0 100644 --- a/pdlzbs/urls.py +++ b/pdlzbs/urls.py @@ -21,6 +21,7 @@ from filebrowser.sites import site urlpatterns = [ path('', include('core.urls')), + path('turnieje/', include('tournamentpages.urls')), path('admin/filebrowser/', site.urls), path('admin/', admin.site.urls), path('tinymce/', include('tinymce.urls')), diff --git a/static/css/dist/styles.css b/static/css/dist/styles.css index 4e6b3c1..dc30e55 100644 --- a/static/css/dist/styles.css +++ b/static/css/dist/styles.css @@ -1233,6 +1233,21 @@ select { padding-bottom: 7px; } +.tpage-nav ul li:hover { + font-weight: 700; + -webkit-text-decoration-line: underline; + text-decoration-line: underline; +} + +.tpage-nav ul li.active { + -webkit-text-decoration-line: none; + text-decoration-line: none; + } + +.tpage-nav ul li.active a { + font-weight: 600; + } + .sr-only { position: absolute; width: 1px; @@ -1406,6 +1421,10 @@ select { resize: both; } +.flex-row { + flex-direction: row; +} + .flex-col { flex-direction: column; } @@ -1505,6 +1524,11 @@ select { background-color: rgb(250 250 249 / var(--tw-bg-opacity)); } +.bg-green-100 { + --tw-bg-opacity: 1; + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); +} + .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); @@ -1795,19 +1819,6 @@ h4 { font-size: 1.25em; } -#atu { - transition: all 0.2s ease, visibility 0s; - border-radius: 0px; - background: repeat padding-box border-box 0% 0% / auto auto scroll - linear-gradient(180deg, rgba(8, 50, 4, 0.5) 0%, rgba(8, 50, 4, 0.5) 100%), - no-repeat padding-box border-box 78% 59%/200% scroll url("/static/atu.jpg"); - display: block; -} - -.target\:block:target { - display: block; -} - .active\:ring-2:active { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); @@ -1818,6 +1829,10 @@ h4 { display: block; } +.prose-h1\:font-medium :is(:where(h1):not(:where([class~="not-prose"] *))) { + font-weight: 500; +} + .prose-h2\:mb-2 :is(:where(h2):not(:where([class~="not-prose"] *))) { margin-bottom: 0.5rem; } diff --git a/static/tabbed_admin/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/static/tabbed_admin/css/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..352a197 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_flat_0_eeeeee_40x100.png b/static/tabbed_admin/css/images/ui-bg_flat_0_eeeeee_40x100.png new file mode 100644 index 0000000..d49599a Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_flat_0_eeeeee_40x100.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_flat_55_c0402a_40x100.png b/static/tabbed_admin/css/images/ui-bg_flat_55_c0402a_40x100.png new file mode 100644 index 0000000..a36c8ec Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_flat_55_c0402a_40x100.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_flat_55_eeeeee_40x100.png b/static/tabbed_admin/css/images/ui-bg_flat_55_eeeeee_40x100.png new file mode 100644 index 0000000..d49599a Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_flat_55_eeeeee_40x100.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_glass_100_f8f8f8_1x400.png b/static/tabbed_admin/css/images/ui-bg_glass_100_f8f8f8_1x400.png new file mode 100644 index 0000000..18984c8 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_glass_100_f8f8f8_1x400.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_glass_35_dddddd_1x400.png b/static/tabbed_admin/css/images/ui-bg_glass_35_dddddd_1x400.png new file mode 100644 index 0000000..8bd1ee1 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_glass_35_dddddd_1x400.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_glass_60_eeeeee_1x400.png b/static/tabbed_admin/css/images/ui-bg_glass_60_eeeeee_1x400.png new file mode 100644 index 0000000..b078f23 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_glass_60_eeeeee_1x400.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_inset-hard_75_999999_1x100.png b/static/tabbed_admin/css/images/ui-bg_inset-hard_75_999999_1x100.png new file mode 100644 index 0000000..55347c6 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_inset-hard_75_999999_1x100.png differ diff --git a/static/tabbed_admin/css/images/ui-bg_inset-soft_50_c9c9c9_1x100.png b/static/tabbed_admin/css/images/ui-bg_inset-soft_50_c9c9c9_1x100.png new file mode 100644 index 0000000..de77835 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-bg_inset-soft_50_c9c9c9_1x100.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_3383bb_256x240.png b/static/tabbed_admin/css/images/ui-icons_3383bb_256x240.png new file mode 100644 index 0000000..956671a Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_3383bb_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_444444_256x240.png b/static/tabbed_admin/css/images/ui-icons_444444_256x240.png new file mode 100644 index 0000000..a802263 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_444444_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_454545_256x240.png b/static/tabbed_admin/css/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000..d6169e8 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_454545_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_555555_256x240.png b/static/tabbed_admin/css/images/ui-icons_555555_256x240.png new file mode 100644 index 0000000..7009bf7 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_555555_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_70b2e1_256x240.png b/static/tabbed_admin/css/images/ui-icons_70b2e1_256x240.png new file mode 100644 index 0000000..12880a4 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_70b2e1_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_777620_256x240.png b/static/tabbed_admin/css/images/ui-icons_777620_256x240.png new file mode 100644 index 0000000..e0a1fdf Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_777620_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_777777_256x240.png b/static/tabbed_admin/css/images/ui-icons_777777_256x240.png new file mode 100644 index 0000000..8e26ee4 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_777777_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_999999_256x240.png b/static/tabbed_admin/css/images/ui-icons_999999_256x240.png new file mode 100644 index 0000000..e6763f1 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_999999_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_cc0000_256x240.png b/static/tabbed_admin/css/images/ui-icons_cc0000_256x240.png new file mode 100644 index 0000000..2815430 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_cc0000_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_fbc856_256x240.png b/static/tabbed_admin/css/images/ui-icons_fbc856_256x240.png new file mode 100644 index 0000000..40f5283 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_fbc856_256x240.png differ diff --git a/static/tabbed_admin/css/images/ui-icons_ffffff_256x240.png b/static/tabbed_admin/css/images/ui-icons_ffffff_256x240.png new file mode 100644 index 0000000..4d66f59 Binary files /dev/null and b/static/tabbed_admin/css/images/ui-icons_ffffff_256x240.png differ diff --git a/static/tabbed_admin/css/jquery-ui-1.11.4.min.css b/static/tabbed_admin/css/jquery-ui-1.11.4.min.css new file mode 100644 index 0000000..f633b3a --- /dev/null +++ b/static/tabbed_admin/css/jquery-ui-1.11.4.min.css @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.11.4 - 2016-12-04 +* http://jqueryui.com +* Includes: core.css, tabs.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=%2379aec8&bgTextureHeader=flat&borderColorHeader=%23dddddd&fcHeader=%23333333&iconColorHeader=%23444444&bgColorContent=%23fff&bgTextureContent=flat&borderColorContent=%23eee&fcContent=%23333333&iconColorContent=%23444444&bgColorDefault=%23205067&bgTextureDefault=flat&borderColorDefault=%23205067&fcDefault=%23f9f9f9&iconColorDefault=%23777777&bgColorHover=%2379aec8&bgTextureHover=flat&borderColorHover=%23205067&fcHover=%23fff&iconColorHover=%23555555&bgColorActive=%23fff&bgTextureActive=flat&borderColorActive=%23fff&fcActive=%23000&iconColorActive=%23ffffff&bgColorHighlight=%23fffa90&bgTextureHighlight=flat&borderColorHighlight=%23dad55e&fcHighlight=%23777620&iconColorHighlight=%23777620&bgColorError=%23fddfdf&bgTextureError=flat&borderColorError=%23f1a899&fcError=%235f3f3f&iconColorError=%23cc0000&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=%23666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px&bgImgOpacityHeader=&bgImgOpacityContent=&bgImgOpacityDefault=&bgImgOpacityHover=&bgImgOpacityActive=&bgImgOpacityHighlight=&bgImgOpacityError= +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #eee;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#79aec8;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #205067;background:#205067;font-weight:normal;color:#f9f9f9}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#f9f9f9;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #205067;background:#79aec8;font-weight:normal;color:#fff}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#fff;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fff;background:#fff;font-weight:normal;color:#000}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#000;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:0 0 0 0;padding:5px;background:#666;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px} diff --git a/static/tabbed_admin/css/tabbed_admin.css b/static/tabbed_admin/css/tabbed_admin.css new file mode 100644 index 0000000..aa810b0 --- /dev/null +++ b/static/tabbed_admin/css/tabbed_admin.css @@ -0,0 +1 @@ +#tabs{clear:both}.ui-state-default a.errortab{background-color:red;color:white}.ui-tabs .ui-tabs-panel{overflow:hidden} diff --git a/static/tabbed_admin/css/tabbed_grappelli_admin.css b/static/tabbed_admin/css/tabbed_grappelli_admin.css new file mode 100644 index 0000000..97af0b2 --- /dev/null +++ b/static/tabbed_admin/css/tabbed_grappelli_admin.css @@ -0,0 +1 @@ +.ui-tabs{background-color:#fff;border:0;min-width:960px}.ui-widget textarea,.ui-widget input,.ui-widget select{font-family:Arial,sans-serif}.ui-widget{font-family:Arial,sans-serif;font-size:1em}.ui-tabs .ui-tabs-panel{background-color:#fff;padding:5px 4px 0}.ui-tabs .ui-tabs-anchor{font-size:9pt}.ui-widget-content{background:none}.ui-tabs .ui-widget-content a{color:#309BBF}.ui-tabs .ui-widget-content a:hover{color:#444}.ui-tabs .ui-widget-header{background-image:linear-gradient(#E5E5E5,#DBDBDB)}.ui-tabs .ui-state-default{background-image:linear-gradient(#CEE9F2,#E1F0F5)}.ui-tabs .ui-state-active{background-image:linear-gradient(#CEE9F2,#fff);border-color:#BBB}.ui-tabs .ui-state-active a{color:#444} diff --git a/static/tabbed_admin/js/jquery-ui-1.11.4.min.js b/static/tabbed_admin/js/jquery-ui-1.11.4.min.js new file mode 100644 index 0000000..0859952 --- /dev/null +++ b/static/tabbed_admin/js/jquery-ui-1.11.4.min.js @@ -0,0 +1,8 @@ +/*! jQuery UI - v1.11.4 - 2015-07-27 +* http://jqueryui.com +* Includes: core.js, widget.js, tabs.js +* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ + +jQuery = jQuery || django.jQuery.noConflict(false); + +(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var s=0,n=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,a=n.call(arguments,1),o=0,r=a.length;r>o;o++)for(i in a[o])s=a[o][i],a[o].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(a){var o="string"==typeof a,r=n.call(arguments,1),h=this;return o?this.each(function(){var i,n=e.data(this,s);return"instance"===a?(h=n,!1):n?e.isFunction(n[a])&&"_"!==a.charAt(0)?(i=n[a].apply(n,r),i!==n&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+a+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+a+"'")}):(r.length&&(a=e.widget.extend.apply(null,[a].concat(r))),this.each(function(){var t=e.data(this,s);t?(t.option(a||{}),t._init&&t._init()):e.data(this,s,new i(a,this))})),h}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=s++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget,e.widget("ui.tabs",{version:"1.11.4",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var e=/#.*$/;return function(t){var i,s;t=t.cloneNode(!1),i=t.href.replace(e,""),s=location.href.replace(e,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return t.hash.length>1&&i===s}}(),_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var t=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===t&&(s&&this.tabs.each(function(i,n){return e(n).attr("aria-controls")===s?(t=i,!1):void 0}),null===t&&(t=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===t||-1===t)&&(t=this.tabs.length?0:!1)),t!==!1&&(t=this.tabs.index(this.tabs.eq(t)),-1===t&&(t=i?!1:0)),!i&&t===!1&&this.anchors.length&&(t=0),t},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var i=e(this.document[0].activeElement).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(t)){switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:s++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:n=!1,s--;break;case e.ui.keyCode.END:s=this.anchors.length-1;break;case e.ui.keyCode.HOME:s=0;break;case e.ui.keyCode.SPACE:return t.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case e.ui.keyCode.ENTER:return t.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}t.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),t.ctrlKey||t.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){return t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(t,i){function s(){return t>n&&(t=0),0>t&&(t=n),t}for(var n=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):"disabled"===e?(this._setupDisabled(t),void 0):(this._super(e,t),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",t),t||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(t),"heightStyle"===e&&this._setupHeightStyle(t),void 0)},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist").delegate("> li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,s){var n,a,o,r=e(s).uniqueId().attr("id"),h=e(s).closest("li"),l=h.attr("aria-controls");t._isLocal(s)?(n=s.hash,o=n.substring(1),a=t.element.find(t._sanitizeSelector(n))):(o=h.attr("aria-controls")||e({}).uniqueId()[0].id,n="#"+o,a=t.element.find(n),a.length||(a=t._createPanel(o),a.insertAfter(t.panels[i-1]||t.tablist)),a.attr("aria-live","polite")),a.length&&(t.panels=t.panels.add(a)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":o,"aria-labelledby":r}),a.attr("aria-labelledby",r)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(e){e.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?e():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:r?e():a,newPanel:h};t.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?e():a,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),t),this._toggle(t,u))},_toggle:function(t,i){function s(){a.running=!1,a._trigger("activate",t,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tablist.unbind(this.eventNamespace),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(t){var i=this.options.disabled;i!==!1&&(void 0===t?i=!1:(t=this._getIndex(t),i=e.isArray(i)?e.map(i,function(e){return e!==t?e:null}):e.map(this.tabs,function(e,i){return i!==t?i:null})),this._setupDisabled(i))},disable:function(t){var i=this.options.disabled;if(i!==!0){if(void 0===t)i=!0;else{if(t=this._getIndex(t),-1!==e.inArray(t,i))return;i=e.isArray(i)?e.merge([t],i).sort():[t]}this._setupDisabled(i)}},load:function(t,i){t=this._getIndex(t);var s=this,n=this.tabs.eq(t),a=n.find(".ui-tabs-anchor"),o=this._getPanelForTab(n),r={tab:n,panel:o},h=function(e,t){"abort"===t&&s.panels.stop(!1,!0),n.removeClass("ui-tabs-loading"),o.removeAttr("aria-busy"),e===s.xhr&&delete s.xhr};this._isLocal(a[0])||(this.xhr=e.ajax(this._ajaxSettings(a,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(n.addClass("ui-tabs-loading"),o.attr("aria-busy","true"),this.xhr.done(function(e,t,n){setTimeout(function(){o.html(e),s._trigger("load",i,r),h(n,t)},1)}).fail(function(e,t){setTimeout(function(){h(e,t)},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href"),beforeSend:function(t,a){return n._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:a},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})}); diff --git a/tabbed_admin/LICENSE.txt b/tabbed_admin/LICENSE.txt new file mode 100644 index 0000000..a4e556e --- /dev/null +++ b/tabbed_admin/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2015, Guillaume Pousseo +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tabbed_admin/__init__.py b/tabbed_admin/__init__.py new file mode 100644 index 0000000..f2825c4 --- /dev/null +++ b/tabbed_admin/__init__.py @@ -0,0 +1,6 @@ +from .admin import TabbedModelAdmin + +__author__ = 'Guillaume Pousseo' +__all__ = [ + "TabbedModelAdmin" +] diff --git a/tabbed_admin/admin.py b/tabbed_admin/admin.py new file mode 100644 index 0000000..a5eae7c --- /dev/null +++ b/tabbed_admin/admin.py @@ -0,0 +1,154 @@ +from django.conf import settings +from django.contrib.admin.options import ModelAdmin +from django.utils.translation import gettext_lazy as _ + +from .settings import USE_JQUERY_UI, JQUERY_UI_CSS, JQUERY_UI_JS + + +class TabbedModelAdmin(ModelAdmin): + tabs = None + formatted_tabs = {} + + # Needs a specific template to display the tabs + change_form_template = 'tabbed_admin/change_form.html' + + def get_fieldsets(self, request, obj=None): + """ + Overwrites BaseModelAdmin fieldsets to add fieldsets passed by the + tabs. + If the tabs attribute is not set, use the default ModelAdmin method. + """ + tabs_fieldsets = self.get_formatted_tabs(request, obj)['fieldsets'] + if self.tabs is not None: + self.fieldsets = () + self.fieldsets = self.add_tabbed_item(tabs_fieldsets, self.fieldsets) + return super(TabbedModelAdmin, self).get_fieldsets(request, obj) + + def get_inline_instances(self, request, obj=None): + """ + Overwrites BaseModelAdmin fieldsets to add fieldsets passed by the + tabs. + If the tabs attribute is not set, use the default ModelAdmin method. + """ + if self.tabs is not None: + self.inlines = () + tabs_inlines = self.get_formatted_tabs(request, obj)['inlines'] + self.inlines = self.add_tabbed_item(tabs_inlines, self.inlines) + + try: + # django >=1.7 + return super(TabbedModelAdmin, self)\ + .get_inline_instances(request, obj) + except TypeError: + return super(TabbedModelAdmin, self).get_inline_instances(request) + + def add_tabbed_item(self, items_to_add, collection): + """ + Adds tabbed items (inlines or fieldsets) to their corresponding + attribute. + """ + if items_to_add: + for item in items_to_add: + if item not in collection: + if type(collection) == tuple: + collection = collection + (item, ) + elif type(collection) == list: + collection.append(item) + return collection + + def get_tabs(self, request, obj=None): + """ + Returns the tabs attribute. + """ + return self.tabs + + def get_formatted_tabs(self, request, obj=None): + """ + Returns the formated tabs attribute. + """ + if self.tabs: + self.parse_fieldsets_inlines_from_tabs(request, obj) + return self.formatted_tabs + + def parse_fieldsets_inlines_from_tabs(self, request, obj=None): + """ + Parses the self.tabs attribute. Checks its integrity and populates + self._tabs_fieldsets and self._tabs_inlines attributes. + """ + tabs_fieldsets = () + tabs_inlines = () + self.formatted_tabs['fields'] = [] + for tab in self.get_tabs(request, obj): + # Checks that each tab if formated with 2 arguments, verbose name + # of the tab and the tab configuration. + if type(tab) not in [tuple, list]: + raise TypeError( + _(u'Each tab entry must be either a list or a tuple')) + if len(tab) != 2: + raise ValueError( + _(u'Each tabs entry must contain 2 arguments: a verbose name and the tab setup.')) + if type(tab[1]) not in [tuple, list]: + raise TypeError( + _(u'A tab definition must be either a list or a tuple')) + # So far all went well, lets parse the tab configuration, we go + # through each item. If its a tuple or a list we consider its a + # fieldset, otherwise its a tuple. + formatted_tab = {'name': tab[0], 'entries': []} + for tab_entry in tab[1]: + formatted_tab_entry = {} + if type(tab_entry) in [tuple, list]: + tabs_fieldsets = tabs_fieldsets + (tab_entry, ) + formatted_tab_entry = {'type': 'fieldset', + 'name': tab_entry[0], + 'config': tab_entry[1]} + else: + tabs_inlines = tabs_inlines + (tab_entry, ) + formatted_tab_entry = {'type': 'inline', + 'name': tab_entry.__name__} + formatted_tab['entries'].append(formatted_tab_entry) + self.formatted_tabs['fields'].append(formatted_tab) + self.formatted_tabs['fieldsets'] = tabs_fieldsets + self.formatted_tabs['inlines'] = tabs_inlines + + def add_view(self, request, form_url='', extra_context=None): + """ + Overwrites add_view to insert the tabs config for the template. + """ + if extra_context is None: + extra_context = {} + extra_context.update({'tabs': self.get_formatted_tabs(request)}) + return super(TabbedModelAdmin, self)\ + .add_view(request, form_url=form_url, extra_context=extra_context) + + def change_view(self, request, object_id, form_url='', extra_context=None): + """ + Overwrites change_view to insert the tabs config for the template. + """ + try: + # django 1.4 + change_view = super(TabbedModelAdmin, self)\ + .change_view(request, object_id, form_url=form_url, + extra_context=extra_context) + except TypeError: + # django 1.3 + change_view = super(TabbedModelAdmin, self)\ + .change_view(request, object_id, extra_context=extra_context) + if hasattr(change_view, 'context_data'): + change_view.context_data.update( + {'tabs': self.get_formatted_tabs(request, + change_view.context_data.get('original'))} + ) + return change_view + + class Media: + """ + Extends media class to add custom jquery ui if + TABBED_ADMIN_USE_JQUERY_UI is set to True. + """ + if 'grappelli' in settings.INSTALLED_APPS: + css = {'all': ("tabbed_admin/css/tabbed_grappelli_admin.css", )} + + if USE_JQUERY_UI: + css = { + 'all': (JQUERY_UI_CSS, 'tabbed_admin/css/tabbed_admin.css', )} + js = (JQUERY_UI_JS,) diff --git a/db/tournamentpages/__init__.py b/tabbed_admin/models.py similarity index 100% rename from db/tournamentpages/__init__.py rename to tabbed_admin/models.py diff --git a/tabbed_admin/requirements.txt b/tabbed_admin/requirements.txt new file mode 100644 index 0000000..b5d1e98 --- /dev/null +++ b/tabbed_admin/requirements.txt @@ -0,0 +1,6 @@ +# No particular version to test anything + +Django +django-grappelli +django-tabbed-admin +django-gipsy diff --git a/tabbed_admin/settings.py b/tabbed_admin/settings.py new file mode 100644 index 0000000..60dc84a --- /dev/null +++ b/tabbed_admin/settings.py @@ -0,0 +1,18 @@ +# coding: utf-8 + +# DJANGO IMPORTS +from django.conf import settings + +# Activate the library jquery ui +USE_JQUERY_UI = getattr(settings, "TABBED_ADMIN_USE_JQUERY_UI", False) +USE_GRAPPELLI = getattr(settings, "TABBED_ADMIN_USE_GRAPPELLI", False) + +# Default jquery ui css and js +DEFAULT_JQUERY_UI_CSS = 'tabbed_admin/css/jquery-ui-1.11.4.min.css' +DEFAULT_JQUERY_UI_JS = 'tabbed_admin/js/jquery-ui-1.11.4.min.js' + +# User ability to override the default css and js +JQUERY_UI_CSS = getattr( + settings, "TABBED_ADMIN_JQUERY_UI_CSS", DEFAULT_JQUERY_UI_CSS) +JQUERY_UI_JS = getattr( + settings, "TABBED_ADMIN_JQUERY_UI_JS", DEFAULT_JQUERY_UI_JS) diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..352a197 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_eeeeee_40x100.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_eeeeee_40x100.png new file mode 100644 index 0000000..d49599a Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_eeeeee_40x100.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_c0402a_40x100.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_c0402a_40x100.png new file mode 100644 index 0000000..a36c8ec Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_c0402a_40x100.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_eeeeee_40x100.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_eeeeee_40x100.png new file mode 100644 index 0000000..d49599a Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_eeeeee_40x100.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_100_f8f8f8_1x400.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_100_f8f8f8_1x400.png new file mode 100644 index 0000000..18984c8 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_100_f8f8f8_1x400.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_35_dddddd_1x400.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_35_dddddd_1x400.png new file mode 100644 index 0000000..8bd1ee1 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_35_dddddd_1x400.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_60_eeeeee_1x400.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_60_eeeeee_1x400.png new file mode 100644 index 0000000..b078f23 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_60_eeeeee_1x400.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-hard_75_999999_1x100.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-hard_75_999999_1x100.png new file mode 100644 index 0000000..55347c6 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-hard_75_999999_1x100.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-soft_50_c9c9c9_1x100.png b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-soft_50_c9c9c9_1x100.png new file mode 100644 index 0000000..de77835 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-soft_50_c9c9c9_1x100.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_3383bb_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_3383bb_256x240.png new file mode 100644 index 0000000..956671a Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_3383bb_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_444444_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_444444_256x240.png new file mode 100644 index 0000000..a802263 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_444444_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_454545_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000..d6169e8 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_454545_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_555555_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_555555_256x240.png new file mode 100644 index 0000000..7009bf7 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_555555_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_70b2e1_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_70b2e1_256x240.png new file mode 100644 index 0000000..12880a4 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_70b2e1_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777620_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777620_256x240.png new file mode 100644 index 0000000..e0a1fdf Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777620_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777777_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777777_256x240.png new file mode 100644 index 0000000..8e26ee4 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777777_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_999999_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_999999_256x240.png new file mode 100644 index 0000000..e6763f1 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_999999_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_cc0000_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_cc0000_256x240.png new file mode 100644 index 0000000..2815430 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_cc0000_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_fbc856_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_fbc856_256x240.png new file mode 100644 index 0000000..40f5283 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_fbc856_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/images/ui-icons_ffffff_256x240.png b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_ffffff_256x240.png new file mode 100644 index 0000000..4d66f59 Binary files /dev/null and b/tabbed_admin/static/tabbed_admin/css/images/ui-icons_ffffff_256x240.png differ diff --git a/tabbed_admin/static/tabbed_admin/css/jquery-ui-1.11.4.min.css b/tabbed_admin/static/tabbed_admin/css/jquery-ui-1.11.4.min.css new file mode 100644 index 0000000..f633b3a --- /dev/null +++ b/tabbed_admin/static/tabbed_admin/css/jquery-ui-1.11.4.min.css @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.11.4 - 2016-12-04 +* http://jqueryui.com +* Includes: core.css, tabs.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=%2379aec8&bgTextureHeader=flat&borderColorHeader=%23dddddd&fcHeader=%23333333&iconColorHeader=%23444444&bgColorContent=%23fff&bgTextureContent=flat&borderColorContent=%23eee&fcContent=%23333333&iconColorContent=%23444444&bgColorDefault=%23205067&bgTextureDefault=flat&borderColorDefault=%23205067&fcDefault=%23f9f9f9&iconColorDefault=%23777777&bgColorHover=%2379aec8&bgTextureHover=flat&borderColorHover=%23205067&fcHover=%23fff&iconColorHover=%23555555&bgColorActive=%23fff&bgTextureActive=flat&borderColorActive=%23fff&fcActive=%23000&iconColorActive=%23ffffff&bgColorHighlight=%23fffa90&bgTextureHighlight=flat&borderColorHighlight=%23dad55e&fcHighlight=%23777620&iconColorHighlight=%23777620&bgColorError=%23fddfdf&bgTextureError=flat&borderColorError=%23f1a899&fcError=%235f3f3f&iconColorError=%23cc0000&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=%23666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px&bgImgOpacityHeader=&bgImgOpacityContent=&bgImgOpacityDefault=&bgImgOpacityHover=&bgImgOpacityActive=&bgImgOpacityHighlight=&bgImgOpacityError= +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #eee;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#79aec8;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #205067;background:#205067;font-weight:normal;color:#f9f9f9}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#f9f9f9;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #205067;background:#79aec8;font-weight:normal;color:#fff}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#fff;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fff;background:#fff;font-weight:normal;color:#000}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#000;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:0 0 0 0;padding:5px;background:#666;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px} diff --git a/tabbed_admin/static/tabbed_admin/css/tabbed_admin.css b/tabbed_admin/static/tabbed_admin/css/tabbed_admin.css new file mode 100644 index 0000000..aa810b0 --- /dev/null +++ b/tabbed_admin/static/tabbed_admin/css/tabbed_admin.css @@ -0,0 +1 @@ +#tabs{clear:both}.ui-state-default a.errortab{background-color:red;color:white}.ui-tabs .ui-tabs-panel{overflow:hidden} diff --git a/tabbed_admin/static/tabbed_admin/css/tabbed_grappelli_admin.css b/tabbed_admin/static/tabbed_admin/css/tabbed_grappelli_admin.css new file mode 100644 index 0000000..97af0b2 --- /dev/null +++ b/tabbed_admin/static/tabbed_admin/css/tabbed_grappelli_admin.css @@ -0,0 +1 @@ +.ui-tabs{background-color:#fff;border:0;min-width:960px}.ui-widget textarea,.ui-widget input,.ui-widget select{font-family:Arial,sans-serif}.ui-widget{font-family:Arial,sans-serif;font-size:1em}.ui-tabs .ui-tabs-panel{background-color:#fff;padding:5px 4px 0}.ui-tabs .ui-tabs-anchor{font-size:9pt}.ui-widget-content{background:none}.ui-tabs .ui-widget-content a{color:#309BBF}.ui-tabs .ui-widget-content a:hover{color:#444}.ui-tabs .ui-widget-header{background-image:linear-gradient(#E5E5E5,#DBDBDB)}.ui-tabs .ui-state-default{background-image:linear-gradient(#CEE9F2,#E1F0F5)}.ui-tabs .ui-state-active{background-image:linear-gradient(#CEE9F2,#fff);border-color:#BBB}.ui-tabs .ui-state-active a{color:#444} diff --git a/tabbed_admin/static/tabbed_admin/js/jquery-ui-1.11.4.min.js b/tabbed_admin/static/tabbed_admin/js/jquery-ui-1.11.4.min.js new file mode 100644 index 0000000..0859952 --- /dev/null +++ b/tabbed_admin/static/tabbed_admin/js/jquery-ui-1.11.4.min.js @@ -0,0 +1,8 @@ +/*! jQuery UI - v1.11.4 - 2015-07-27 +* http://jqueryui.com +* Includes: core.js, widget.js, tabs.js +* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ + +jQuery = jQuery || django.jQuery.noConflict(false); + +(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var s=0,n=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,a=n.call(arguments,1),o=0,r=a.length;r>o;o++)for(i in a[o])s=a[o][i],a[o].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(a){var o="string"==typeof a,r=n.call(arguments,1),h=this;return o?this.each(function(){var i,n=e.data(this,s);return"instance"===a?(h=n,!1):n?e.isFunction(n[a])&&"_"!==a.charAt(0)?(i=n[a].apply(n,r),i!==n&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+a+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+a+"'")}):(r.length&&(a=e.widget.extend.apply(null,[a].concat(r))),this.each(function(){var t=e.data(this,s);t?(t.option(a||{}),t._init&&t._init()):e.data(this,s,new i(a,this))})),h}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=s++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget,e.widget("ui.tabs",{version:"1.11.4",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var e=/#.*$/;return function(t){var i,s;t=t.cloneNode(!1),i=t.href.replace(e,""),s=location.href.replace(e,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return t.hash.length>1&&i===s}}(),_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var t=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===t&&(s&&this.tabs.each(function(i,n){return e(n).attr("aria-controls")===s?(t=i,!1):void 0}),null===t&&(t=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===t||-1===t)&&(t=this.tabs.length?0:!1)),t!==!1&&(t=this.tabs.index(this.tabs.eq(t)),-1===t&&(t=i?!1:0)),!i&&t===!1&&this.anchors.length&&(t=0),t},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var i=e(this.document[0].activeElement).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(t)){switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:s++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:n=!1,s--;break;case e.ui.keyCode.END:s=this.anchors.length-1;break;case e.ui.keyCode.HOME:s=0;break;case e.ui.keyCode.SPACE:return t.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case e.ui.keyCode.ENTER:return t.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}t.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),t.ctrlKey||t.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){return t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(t,i){function s(){return t>n&&(t=0),0>t&&(t=n),t}for(var n=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):"disabled"===e?(this._setupDisabled(t),void 0):(this._super(e,t),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",t),t||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(t),"heightStyle"===e&&this._setupHeightStyle(t),void 0)},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist").delegate("> li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,s){var n,a,o,r=e(s).uniqueId().attr("id"),h=e(s).closest("li"),l=h.attr("aria-controls");t._isLocal(s)?(n=s.hash,o=n.substring(1),a=t.element.find(t._sanitizeSelector(n))):(o=h.attr("aria-controls")||e({}).uniqueId()[0].id,n="#"+o,a=t.element.find(n),a.length||(a=t._createPanel(o),a.insertAfter(t.panels[i-1]||t.tablist)),a.attr("aria-live","polite")),a.length&&(t.panels=t.panels.add(a)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":o,"aria-labelledby":r}),a.attr("aria-labelledby",r)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(e){e.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?e():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:r?e():a,newPanel:h};t.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?e():a,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),t),this._toggle(t,u))},_toggle:function(t,i){function s(){a.running=!1,a._trigger("activate",t,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tablist.unbind(this.eventNamespace),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(t){var i=this.options.disabled;i!==!1&&(void 0===t?i=!1:(t=this._getIndex(t),i=e.isArray(i)?e.map(i,function(e){return e!==t?e:null}):e.map(this.tabs,function(e,i){return i!==t?i:null})),this._setupDisabled(i))},disable:function(t){var i=this.options.disabled;if(i!==!0){if(void 0===t)i=!0;else{if(t=this._getIndex(t),-1!==e.inArray(t,i))return;i=e.isArray(i)?e.merge([t],i).sort():[t]}this._setupDisabled(i)}},load:function(t,i){t=this._getIndex(t);var s=this,n=this.tabs.eq(t),a=n.find(".ui-tabs-anchor"),o=this._getPanelForTab(n),r={tab:n,panel:o},h=function(e,t){"abort"===t&&s.panels.stop(!1,!0),n.removeClass("ui-tabs-loading"),o.removeAttr("aria-busy"),e===s.xhr&&delete s.xhr};this._isLocal(a[0])||(this.xhr=e.ajax(this._ajaxSettings(a,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(n.addClass("ui-tabs-loading"),o.attr("aria-busy","true"),this.xhr.done(function(e,t,n){setTimeout(function(){o.html(e),s._trigger("load",i,r),h(n,t)},1)}).fail(function(e,t){setTimeout(function(){h(e,t)},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href"),beforeSend:function(t,a){return n._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:a},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})}); diff --git a/tabbed_admin/templates/tabbed_admin/change_form.html b/tabbed_admin/templates/tabbed_admin/change_form.html new file mode 100644 index 0000000..d7d6be4 --- /dev/null +++ b/tabbed_admin/templates/tabbed_admin/change_form.html @@ -0,0 +1,104 @@ +{% extends "admin/change_form.html" %} +{% load i18n admin_modify admin_urls tabbed_admin_tags %} + +{% block content %} + +
+ {% block object-tools %}{{ block.super }}{% endblock %} +
{% csrf_token %}{% block form_top %}{% endblock %} +
+ {% if is_popup %}{% endif %} + {% if to_field %}{% endif %} + {% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} + {% if errors %} +

+ {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} +

+ {{ adminform.form.non_field_errors }} + {% endif %} + + +
+ + + + {% block after_field_sets %}{% endblock %} + + {% block after_related_objects %}{% endblock %} + + {% block submit_buttons_bottom %}{% submit_row %}{% endblock %} + + {% if adminform and add and adminform.first_field and adminform.first_field.id_for_label %} + + {% endif %} + + {% prepopulated_fields_js %} + +
+ +
+{% endblock %} diff --git a/db/tournamentpages/migrations/__init__.py b/tabbed_admin/templatetags/__init__.py similarity index 100% rename from db/tournamentpages/migrations/__init__.py rename to tabbed_admin/templatetags/__init__.py diff --git a/tabbed_admin/templatetags/tabbed_admin_tags.py b/tabbed_admin/templatetags/tabbed_admin_tags.py new file mode 100644 index 0000000..4c9e48c --- /dev/null +++ b/tabbed_admin/templatetags/tabbed_admin_tags.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +from django import template +from django.contrib.admin.helpers import Fieldset +from django.template.loader import render_to_string +from django.core.exceptions import ImproperlyConfigured + +register = template.Library() + + +@register.simple_tag(takes_context=True) +def render_tab_fieldsets_inlines(context, entry): + """ + Render the fieldsets and inlines for a tab. + """ + template = "admin/includes/fieldset.html" + admin_form = context['adminform'] + if 'request' not in context: + raise ImproperlyConfigured( + '"request" missing from context. Add django.core.context' + '_processors.request to your' + 'TEMPLATE_CONTEXT_PROCESSORS') + request = context['request'] + obj = context.get('original', None) + readonly_fields = admin_form.model_admin.get_readonly_fields(request, obj) + inline_matching = {} + if "inline_admin_formsets" in context: + inline_matching = dict((inline.opts.__class__.__name__, inline) + for inline in context["inline_admin_formsets"]) + + if entry['type'] == 'fieldset': + name = entry['name'] + f = Fieldset( + admin_form.form, + name, + readonly_fields=readonly_fields, + model_admin=admin_form.model_admin, + **entry['config'] + ) + context["fieldset"] = f + return render_to_string(template, context.flatten(), request=request) + elif entry['type'] == 'inline': + try: + inline_admin_formset = inline_matching[entry["name"]] + context["inline_admin_formset"] = inline_admin_formset + return render_to_string(inline_admin_formset.opts.template, + context.flatten(), request=request) + except KeyError: # The user does not have the permission + pass + return '' diff --git a/tabbed_admin/tests/__init__.py b/tabbed_admin/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tabbed_admin/tests/admin.py b/tabbed_admin/tests/admin.py new file mode 100644 index 0000000..fa3b1c7 --- /dev/null +++ b/tabbed_admin/tests/admin.py @@ -0,0 +1,42 @@ +from django.contrib import admin + +from tabbed_admin import TabbedModelAdmin +from tabbed_admin.tests.models import Band, Musician, Concert, Album, Interview + + +class MusicianInline(admin.StackedInline): + model = Musician + + +class ConcertInline(admin.TabularInline): + model = Concert + + +class AlbumInline(admin.TabularInline): + model = Album + + +class InterviewInline(admin.TabularInline): + model = Interview + + +class BandAdmin(TabbedModelAdmin): + model = Band + + tab_overview = ( + (None, { + 'fields': ('name', 'bio', 'style') + }), + MusicianInline, + ('Contact', { + 'fields': ('agent', 'phone', 'email') + }) + ) + tab_ressources = ( + ConcertInline, + AlbumInline + ) + tabs = [ + ('Overview', tab_overview), + ('Ressources', tab_ressources) + ] diff --git a/tabbed_admin/tests/models.py b/tabbed_admin/tests/models.py new file mode 100644 index 0000000..6122b01 --- /dev/null +++ b/tabbed_admin/tests/models.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +from django.db import models + + +class Band(models.Model): + STYLE_ROCK = 1 + STYLE_FUNK = 2 + STYLE_JAZZ = 3 + STYLE_OVERRIDE = 4 + + name = models.CharField(max_length=100) + bio = models.TextField(blank=True, null=True) + style = models.CharField(max_length=100, choices=( + (STYLE_ROCK, 'Rock'), + (STYLE_FUNK, 'Funk'), + (STYLE_JAZZ, 'Jazz'), + (STYLE_OVERRIDE, 'Override') + )) + agent = models.CharField(max_length=100, blank=True, null=True) + phone = models.CharField(max_length=100, blank=True, null=True) + email = models.CharField(max_length=100, blank=True, null=True) + address = models.CharField(max_length=100, blank=True, null=True) + website = models.CharField(max_length=100, blank=True, null=True) + twitter = models.CharField(max_length=100, blank=True, null=True) + facebook = models.CharField(max_length=100, blank=True, null=True) + + +class Musician(models.Model): + band = models.ForeignKey(Band) + first_name = models.CharField(max_length=100) + last_name = models.CharField(max_length=100) + specialty = models.CharField(max_length=100, choices=( + (1, 'Vocal'), + (2, 'Guitar'), + (3, 'Bass'), + (4, 'Drums') + )) + + +class Concert(models.Model): + band = models.ForeignKey(Band) + location = models.CharField(max_length=100) + date = models.DateField() + + +class Album(models.Model): + band = models.ForeignKey(Band) + name = models.CharField(max_length=100) + date = models.DateField() + + +class Interview(models.Model): + band = models.ForeignKey(Band) + media_name = models.CharField(max_length=100) + date = models.DateField() diff --git a/tabbed_admin/tests/runtests.py b/tabbed_admin/tests/runtests.py new file mode 100644 index 0000000..c080424 --- /dev/null +++ b/tabbed_admin/tests/runtests.py @@ -0,0 +1,74 @@ +import os +import sys + + +from django.conf import settings + +DIRNAME = os.path.dirname(__file__) +settings.configure( + DEBUG=True, + DATABASE_ENGINE='sqlite3', + DATABASE_NAME=os.path.join(DIRNAME, 'database.db'), + DATABASES={ + 'default': { + 'ENGINE': 'django.db.backends.sqlite3' + } + }, + ROOT_URLCONF='tabbed_admin.tests.urls', + MIDDLEWARE_CLASSES=(), + TEMPLATE_CONTEXT_PROCESSORS=[ + 'django.template.context_processors.request' + ], + TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth' + ], + }, + }, + ], + INSTALLED_APPS=( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.admin', + + 'tabbed_admin', + 'tabbed_admin.tests' + ) +) + + +try: + # Django < 1.8 + from django.test.simple import DjangoTestSuiteRunner + test_runner = DjangoTestSuiteRunner(verbosity=1) +except ImportError: + # Django >= 1.8 + from django.test.runner import DiscoverRunner + test_runner = DiscoverRunner(verbosity=1) + +try: + # Django < 1.7 + from django.core.management import setup_environ + setup_environ(settings) + failures = test_runner.run_tests(['tabbed_admin']) +except: + # Django >= 1.7 + import django + django.setup() + +if __name__ == "__main__": + from django.test.utils import get_runner + os.environ['DJANGO_SETTINGS_MODULE'] = 'tabbed_admin.runtests' + TestRunner = get_runner(settings) + test_runner = TestRunner() + failures = test_runner.run_tests(['tabbed_admin']) + +if failures: + sys.exit(failures) diff --git a/tabbed_admin/tests/tests.py b/tabbed_admin/tests/tests.py new file mode 100644 index 0000000..1006560 --- /dev/null +++ b/tabbed_admin/tests/tests.py @@ -0,0 +1,240 @@ +from django.conf import settings +from django.contrib.admin.sites import AdminSite +from django.template import Context +from django.test import TestCase +from django.test.client import RequestFactory, Client +from django.test.utils import override_settings + +from tabbed_admin.settings import USE_JQUERY_UI +from tabbed_admin.templatetags.tabbed_admin_tags import render_tab_fieldsets_inlines +from tabbed_admin.tests.admin import BandAdmin, InterviewInline +from tabbed_admin.tests.models import Band + + +class MockRequest(object): + pass + + +class MockSuperUser(object): + is_active = True + is_staff = True + def has_perm(self, perm): + return True + +request = RequestFactory() +request.user = MockSuperUser() +request.csrf_processing_done = True + + +class TabbedModelAdminTest(TestCase): + + def setUp(self): + self.site = AdminSite() + + def test_fieldsets_inline_attribute_populated(self): + """ + Tests if self.inlines and self.fieldsets are correcly populated from + the self.tabs attribute. + """ + admin = BandAdmin(Band, self.site) + self.assertIsNone(admin.fieldsets) + self.assertEqual(0, len(admin.inlines)) + fieldsets = admin.get_fieldsets(request) + inlines = admin.get_inline_instances(request) + self.assertNotEqual(0, len(fieldsets)) + self.assertNotEqual(0, len(inlines)) + self.assertNotEqual(0, len(admin.fieldsets)) + self.assertNotEqual(0, len(admin.inlines)) + + def test_fieldsets_inlines_overriden_by_tabs(self): + """ + Tests if when set by default, fieldsets and inlines are properly + overriden. + """ + class TestBandAdmin(BandAdmin): + fieldsets = ( + ('Social', { + 'fields': ('website', 'twitter', 'facebook') + }) + ) + inlines = ( + InterviewInline, + ) + admin = TestBandAdmin(Band, self.site) + self.assertEqual(admin.get_fieldsets(request), + admin.formatted_tabs['fieldsets']) + inlines = admin.get_inline_instances(request) + inlines = admin.inlines + for inline in inlines: + self.assertIn(inline, admin.formatted_tabs['inlines']) + + def test_get_tabs_overrides_tabs_attribute(self): + """ + Tests if get_tabs method successfully overrides the self.tabs and returns it. + """ + single_tab = [('Overview', BandAdmin.tab_overview)] + class TestBandAdmin(BandAdmin): + def get_tabs(self, request, obj=None): + """ + Returns the tabs attribute. + """ + tabs = self.tabs + if obj is not None and obj.style == Band.STYLE_OVERRIDE: + tabs = single_tab + self.tabs = tabs + return super(TestBandAdmin, self).get_tabs(request, obj) + + admin = TestBandAdmin(Band, self.site) + band = Band.objects.create(name="Test band", style=Band.STYLE_JAZZ) + tabs = admin.get_tabs(request, band) + self.assertEqual(len(tabs), 2) + self.assertNotEqual(tabs, single_tab) + band.style = Band.STYLE_OVERRIDE + tabs = admin.get_tabs(request, band) + self.assertEqual(len(tabs), 1) + self.assertEqual(tabs, single_tab) + + def test_dynamically_add_fieldsets_inlines_to_tabs(self): + """ + Tests overriding dynamically tabs via get_tabs. + """ + added_fieldset = ('Social', { + 'fields': ('website', 'twitter', 'facebook') + }) + added_inline = InterviewInline + + class TestBandAdmin(BandAdmin): + def get_tabs(self, request, obj=None): + tabs = self.tabs + tab_overview = self.tab_overview + (added_fieldset, ) + tab_ressources = self.tab_ressources + (added_inline, ) + tabs = [ + ('Overview', tab_overview), + ('Ressources', tab_ressources) + ] + self.tabs = tabs + return super(TestBandAdmin, self).get_tabs(request, obj) + + original_admin = BandAdmin(Band, self.site) + self.assertNotIn(added_fieldset, original_admin.get_fieldsets(request)) + self.assertNotIn(added_inline, original_admin.tab_ressources) + admin = TestBandAdmin(Band, self.site) + inlines_classes = [] + inlines = admin.get_inline_instances(request) + for inline in inlines: + inlines_classes.append(inline.__class__) + self.assertIn(added_inline, inlines_classes) + + def test_version_previous_to_django(self): + """ + Tests overriding dynamically tabs via get_tabs. + """ + added_fieldset = ('Social', { + 'fields': ('website', 'twitter', 'facebook') + }) + added_inline = InterviewInline + + class TestBandAdmin(BandAdmin): + def get_tabs(self, request, obj=None): + tabs = self.tabs + tab_overview = self.tab_overview + (added_fieldset, ) + tab_ressources = self.tab_ressources + (added_inline, ) + tabs = [ + ('Overview', tab_overview), + ('Ressources', tab_ressources) + ] + self.tabs = tabs + return super(TestBandAdmin, self).get_tabs(request, obj) + + original_admin = BandAdmin(Band, self.site) + self.assertNotIn(added_fieldset, original_admin.get_fieldsets(request)) + self.assertNotIn(added_inline, original_admin.tab_ressources) + admin = TestBandAdmin(Band, self.site) + inlines_classes = [] + inlines = admin.get_inline_instances(request) + for inline in inlines: + inlines_classes.append(inline.__class__) + self.assertIn(added_inline, inlines_classes) + self.assertIn(added_fieldset, admin.get_fieldsets(request)) + self.assertIn(added_fieldset, admin.get_fieldsets(request)) + + def test_medias_method_with_default_settings(self): + """ + Tests that the media method is retrning the proper static files when settings.TABBED_ADMIN_USE_JQUERY_UI + is True or False. + """ + self.assertEqual(False, USE_JQUERY_UI) + admin = BandAdmin(Band, self.site) + medias = admin.media + self.assertEqual({}, medias._css) + for js in medias._js: + self.assertNotIn(js, 'tabbed_admin') + + def test_medias_method_with_grappelli(self): + """ + Tests if the right css ile is triggered when grappelli is installed. + """ + try: + import grappelli + except ImportError: + return + settings.INSTALLED_APPS += ('grappelli', ) + self.assertIn('grappelli', settings.INSTALLED_APPS) + admin = BandAdmin(Band, self.site) + medias = admin.media + self.assertTrue(len(medias._css) > 0) + self.assertIn('all', medias._css) + self.assertTrue(len(medias._css['all']) == 1) + self.assertIn('grappelli', medias._css['all'][0]) + + +class TabbedAdminTagsTest(TestCase): + + def setUp(self): + self.site = AdminSite() + self.admin = BandAdmin(Band, self.site) + self.req = request.get('/admin/tabbed_admin/tab/') + self.req.user = request.user + self.view = self.admin.add_view(self.req) + self.context = Context(self.view) + self.context.push() + self.context['adminform'] = self.view.context_data['adminform'] + self.context['request'] = self.req + self.context['inline_admin_formsets'] = self.view.context_data['inline_admin_formsets'] + + def test_request_not_in_context_raising_improperly_configured(self): + """ + Tests if an exception is thrown when no request is passed. + """ + from django.core.exceptions import ImproperlyConfigured + context = self.context + del context['request'] + self.assertRaises(ImproperlyConfigured, render_tab_fieldsets_inlines, self.context, []) + + def test_fieldset_passed_returns_fieldset_templated(self): + """ + Tests if the fieldset html is correctly generated when a fieldset is passed + """ + fieldset = self.view.context_data['tabs']['fields'][0]['entries'][0] + self.assertEqual('fieldset', fieldset['type']) + #tag = render_tab_fieldsets_inlines(self.context, fieldset) + #self.assertIn('fieldset', tag) + + def test_inline_passed_returns_inline_templated(self): + """ + Tests if an inline html is correctly generated when an inline is passed. + """ + inline = self.view.context_data['tabs']['fields'][0]['entries'][1] + self.assertEqual('inline', inline['type']) + #tag = render_tab_fieldsets_inlines(self.context, inline) + #self.assertIn('inline', tag) + + def test_wrong_inline_key_returns_nothing(self): + """ + Tests if a worng inline naming returns nothing. + """ + inline = self.view.context_data['tabs']['fields'][0]['entries'][1] + self.assertEqual('inline', inline['type']) + inline['name'] = 'Not exists' + tag = render_tab_fieldsets_inlines(self.context, inline) + self.assertEqual('', tag) diff --git a/tabbed_admin/tests/urls.py b/tabbed_admin/tests/urls.py new file mode 100644 index 0000000..eb91d28 --- /dev/null +++ b/tabbed_admin/tests/urls.py @@ -0,0 +1,6 @@ +from django.conf.urls import include, url +from django.contrib import admin + +urlpatterns = [ + url(r'^admin/', include(admin.site.urls)), +] diff --git a/theme/static/css/dist/styles.css b/theme/static/css/dist/styles.css index 4e6b3c1..dc30e55 100644 --- a/theme/static/css/dist/styles.css +++ b/theme/static/css/dist/styles.css @@ -1233,6 +1233,21 @@ select { padding-bottom: 7px; } +.tpage-nav ul li:hover { + font-weight: 700; + -webkit-text-decoration-line: underline; + text-decoration-line: underline; +} + +.tpage-nav ul li.active { + -webkit-text-decoration-line: none; + text-decoration-line: none; + } + +.tpage-nav ul li.active a { + font-weight: 600; + } + .sr-only { position: absolute; width: 1px; @@ -1406,6 +1421,10 @@ select { resize: both; } +.flex-row { + flex-direction: row; +} + .flex-col { flex-direction: column; } @@ -1505,6 +1524,11 @@ select { background-color: rgb(250 250 249 / var(--tw-bg-opacity)); } +.bg-green-100 { + --tw-bg-opacity: 1; + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); +} + .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); @@ -1795,19 +1819,6 @@ h4 { font-size: 1.25em; } -#atu { - transition: all 0.2s ease, visibility 0s; - border-radius: 0px; - background: repeat padding-box border-box 0% 0% / auto auto scroll - linear-gradient(180deg, rgba(8, 50, 4, 0.5) 0%, rgba(8, 50, 4, 0.5) 100%), - no-repeat padding-box border-box 78% 59%/200% scroll url("/static/atu.jpg"); - display: block; -} - -.target\:block:target { - display: block; -} - .active\:ring-2:active { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); @@ -1818,6 +1829,10 @@ h4 { display: block; } +.prose-h1\:font-medium :is(:where(h1):not(:where([class~="not-prose"] *))) { + font-weight: 500; +} + .prose-h2\:mb-2 :is(:where(h2):not(:where([class~="not-prose"] *))) { margin-bottom: 0.5rem; } diff --git a/theme/static_src/src/styles.css b/theme/static_src/src/styles.css index 347b6d7..cd4f408 100644 --- a/theme/static_src/src/styles.css +++ b/theme/static_src/src/styles.css @@ -48,6 +48,17 @@ h4 { } } } + + .tpage-nav ul li { + @apply hover:font-bold hover:underline; + + &.active { + @apply no-underline; + a { + @apply font-semibold; + } + } + } } @layer utilities { @@ -77,12 +88,3 @@ h4 { } } } - -#atu { - transition: all 0.2s ease, visibility 0s; - border-radius: 0px; - background: repeat padding-box border-box 0% 0% / auto auto scroll - linear-gradient(180deg, rgba(8, 50, 4, 0.5) 0%, rgba(8, 50, 4, 0.5) 100%), - no-repeat padding-box border-box 78% 59%/200% scroll url("/static/atu.jpg"); - display: block; -} diff --git a/tournamentpages/__init__.py b/tournamentpages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tournamentpages/admin.py b/tournamentpages/admin.py new file mode 100644 index 0000000..41e8d3e --- /dev/null +++ b/tournamentpages/admin.py @@ -0,0 +1,72 @@ +from django.contrib import admin + +from tabbed_admin import TabbedModelAdmin +from .models import TournamentPage + +# Register your models here. + + +@admin.register(TournamentPage) +class BandAdmin(TabbedModelAdmin): + model = TournamentPage + + list_display = ['name', 'link'] + + tab_general = ( + (None, { + 'fields': ('name', 'published', 'header', 'footer') + }), + ) + + tab_homepage = ( + (None, { + 'fields': ('homepage',) + }), + ) + + tab_schedule_and_results = ( + (None, { + 'fields': ('schedule_and_results', 'schedule_and_results_enabled') + }), + ) + + tab_registration = ( + (None, { + 'fields': ('registration', 'registration_enabled') + }), + ) + + tab_rules = ( + (None, { + 'fields': ('rules', 'rules_enabled') + }), + ) + + tab_fee_and_prizes = ( + (None, { + 'fields': ('fee_and_prizes', 'fee_and_prizes_enabled') + }), + ) + + tab_accomodation = ( + (None, { + 'fields': ('accomodation', 'accomodation_enabled') + }), + ) + + tab_contact = ( + (None, { + 'fields': ('contact', 'contact_enabled') + }), + ) + + tabs = [ + ('Ogólne ustawienia', tab_general), + ('Strona główna', tab_homepage), + ('Harmonogram i wyniki', tab_schedule_and_results), + ('Rejestracja', tab_registration), + ('Regulamin', tab_rules), + ('Wpisowe i nagrody', tab_fee_and_prizes), + ('Noclegi', tab_accomodation), + ('Kontakt', tab_contact), + ] diff --git a/db/tournamentpages/apps.py b/tournamentpages/apps.py similarity index 80% rename from db/tournamentpages/apps.py rename to tournamentpages/apps.py index 119fa77..a7a2241 100644 --- a/db/tournamentpages/apps.py +++ b/tournamentpages/apps.py @@ -4,3 +4,4 @@ from django.apps import AppConfig class TournamentpagesConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'tournamentpages' + verbose_name = 'Strony turniejów' diff --git a/tournamentpages/migrations/0001_initial.py b/tournamentpages/migrations/0001_initial.py new file mode 100644 index 0000000..34b4535 --- /dev/null +++ b/tournamentpages/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# Generated by Django 4.0.5 on 2022-10-05 18:29 + +from django.db import migrations, models +import tinymce.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='TournamentPage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=250, verbose_name='Nazwa')), + ('published', models.BooleanField(default=False, verbose_name='Turniej opublikowany')), + ('header', tinymce.models.HTMLField(blank=True, default='', verbose_name='Nagłówek')), + ('footer', tinymce.models.HTMLField(blank=True, default='', verbose_name='Stopka')), + ('homepage', tinymce.models.HTMLField(blank=True, default='', verbose_name='Strona główna')), + ('schedule_and_results', tinymce.models.HTMLField(blank=True, default='', verbose_name='Harmonogram i wyniki')), + ('schedule_and_results_enabled', models.BooleanField(default=False, verbose_name='Strona włączona')), + ('registration', tinymce.models.HTMLField(blank=True, default='', verbose_name='Rejestracja')), + ('registration_enabled', models.BooleanField(default=False, verbose_name='Strona włączona')), + ('rules', tinymce.models.HTMLField(blank=True, default='', verbose_name='Regulamin')), + ('rules_enabled', models.BooleanField(default=False, verbose_name='Strona włączona')), + ('fee_and_prizes', tinymce.models.HTMLField(blank=True, default='', verbose_name='Wpisowe i nagrody')), + ('fee_and_prizes_enabled', models.BooleanField(default=False, verbose_name='Strona włączona')), + ('accomodation', tinymce.models.HTMLField(blank=True, default='', verbose_name='Noclegi')), + ('accomodation_enabled', models.BooleanField(default=False, verbose_name='Strona włączona')), + ('contact', tinymce.models.HTMLField(blank=True, default='', verbose_name='Kontakt')), + ('contact_enabled', models.BooleanField(default=False, verbose_name='Strona włączona')), + ], + options={ + 'verbose_name': 'Strona turnieju', + 'verbose_name_plural': 'Strony turniejów', + }, + ), + ] diff --git a/tournamentpages/migrations/__init__.py b/tournamentpages/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tournamentpages/models.py b/tournamentpages/models.py new file mode 100644 index 0000000..03c203e --- /dev/null +++ b/tournamentpages/models.py @@ -0,0 +1,52 @@ +from django.db import models +from django.urls.base import reverse_lazy +from django.utils.safestring import mark_safe +from tinymce.models import HTMLField + + +# Create your models here. + + +class TournamentPage(models.Model): + name = models.CharField('Nazwa', max_length=250) + published = models.BooleanField('Turniej opublikowany', default=False) + + header = HTMLField('Nagłówek', default='', blank=True) + footer = HTMLField('Stopka', default='', blank=True) + + homepage = HTMLField('Strona główna', default='', blank=True) + + schedule_and_results = HTMLField( + 'Harmonogram i wyniki', default='', blank=True) + schedule_and_results_enabled = models.BooleanField( + 'Strona włączona', default=False) + + registration = HTMLField('Rejestracja', default='', blank=True) + registration_enabled = models.BooleanField( + 'Strona włączona', default=False) + + rules = HTMLField('Regulamin', default='', blank=True) + rules_enabled = models.BooleanField('Strona włączona', default=False) + + fee_and_prizes = HTMLField('Wpisowe i nagrody', default='', blank=True) + fee_and_prizes_enabled = models.BooleanField( + 'Strona włączona', default=False) + + accomodation = HTMLField('Noclegi', default='', blank=True) + accomodation_enabled = models.BooleanField( + 'Strona włączona', default=False) + + contact = HTMLField('Kontakt', default='', blank=True) + contact_enabled = models.BooleanField('Strona włączona', default=False) + + class Meta: + verbose_name = 'Strona turnieju' + verbose_name_plural = 'Strony turniejów' + + @property + def link(self): + href = reverse_lazy('homepage', args=[self.id]) + return mark_safe(f'{href}') + + def __str__(self): + return self.name diff --git a/tournamentpages/templates/tournament.html b/tournamentpages/templates/tournament.html new file mode 100644 index 0000000..dfb4c82 --- /dev/null +++ b/tournamentpages/templates/tournament.html @@ -0,0 +1,76 @@ + + +{% load static tailwind_tags %} + + + + + + + + + + + + + + {% block title %}{{ t.name }}{% endblock %} + + + {% tailwind_css %} + + + +
{{ t.header | safe}}
+ +
+ {{ content | safe }} +
+
{{ t.footer | safe}}
+ + diff --git a/tournamentpages/urls.py b/tournamentpages/urls.py new file mode 100644 index 0000000..59fe5e7 --- /dev/null +++ b/tournamentpages/urls.py @@ -0,0 +1,14 @@ +from django.urls import path +from .views import * + + +urlpatterns = [ + path('', HomeView.as_view(), name='homepage'), + path('/wyniki', ScheduleAndResultsView.as_view(), + name='schedule_and_results'), + path('/rejestracja', RegistrationView.as_view(), name='registration'), + path('/regulamin', RulesView.as_view(), name='rules'), + path('/nagrody', FeeAndPrizesView.as_view(), name='fee_and_prizes'), + path('/noclegi', AccomodationView.as_view(), name='accomodation'), + path('/kontakt', ContactView.as_view(), name='contact'), +] diff --git a/tournamentpages/views.py b/tournamentpages/views.py new file mode 100644 index 0000000..97cc9ca --- /dev/null +++ b/tournamentpages/views.py @@ -0,0 +1,67 @@ +from django.shortcuts import render +from django.views.generic import TemplateView +from .models import TournamentPage + +# Create your views here. + + +class HomeView(TemplateView): + template_name = "tournament.html" + + def get_context_data(self, id, **kwargs): + t = TournamentPage.objects.get(id=id, published=True) + return {'t': t, 'content': t.homepage, 'homepage': True} + + +class ScheduleAndResultsView(TemplateView): + template_name = "tournament.html" + + def get_context_data(self, id, **kwargs): + t = TournamentPage.objects.get( + id=id, published=True, schedule_and_results_enabled=True) + return {'t': t, 'content': t.schedule_and_results, 'schedule_and_results': True} + + +class RegistrationView(TemplateView): + template_name = "tournament.html" + + def get_context_data(self, id, **kwargs): + t = TournamentPage.objects.get( + id=id, published=True, registration_enabled=True) + return {'t': t, 'content': t.registration, 'registration': True} + + +class RulesView(TemplateView): + template_name = "tournament.html" + + def get_context_data(self, id, **kwargs): + t = TournamentPage.objects.get( + id=id, published=True, rules_enabled=True) + return {'t': t, 'content': t.rules, 'rules': True} + + +class FeeAndPrizesView(TemplateView): + template_name = "tournament.html" + + def get_context_data(self, id, **kwargs): + t = TournamentPage.objects.get( + id=id, published=True, fee_and_prizes_enabled=True) + return {'t': t, 'content': t.fee_and_prizes, 'fee_and_prizes': True} + + +class AccomodationView(TemplateView): + template_name = "tournament.html" + + def get_context_data(self, id, **kwargs): + t = TournamentPage.objects.get( + id=id, published=True, accomodation_enabled=True) + return {'t': t, 'content': t.accomodation, 'accomodation': True} + + +class ContactView(TemplateView): + template_name = "tournament.html" + + def get_context_data(self, id, **kwargs): + t = TournamentPage.objects.get( + id=id, published=True, contact_enabled=True) + return {'t': t, 'content': t.contact, 'contact': True}