django-smartbase-admin 0.2.54__py3-none-any.whl → 1.0.42__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. django_smartbase_admin/actions/admin_action_list.py +79 -38
  2. django_smartbase_admin/actions/advanced_filters.py +24 -1
  3. django_smartbase_admin/admin/admin_base.py +402 -97
  4. django_smartbase_admin/admin/site.py +93 -35
  5. django_smartbase_admin/admin/widgets.py +636 -26
  6. django_smartbase_admin/apps.py +2 -0
  7. django_smartbase_admin/engine/actions.py +34 -16
  8. django_smartbase_admin/engine/admin_base_view.py +252 -115
  9. django_smartbase_admin/engine/configuration.py +186 -4
  10. django_smartbase_admin/engine/const.py +6 -0
  11. django_smartbase_admin/engine/dashboard.py +49 -24
  12. django_smartbase_admin/engine/fake_inline.py +15 -11
  13. django_smartbase_admin/engine/field.py +42 -12
  14. django_smartbase_admin/engine/field_formatter.py +38 -14
  15. django_smartbase_admin/engine/filter_widgets.py +348 -24
  16. django_smartbase_admin/engine/menu_item.py +8 -5
  17. django_smartbase_admin/engine/modal_view.py +12 -7
  18. django_smartbase_admin/engine/request.py +2 -0
  19. django_smartbase_admin/integration/__init__.py +0 -0
  20. django_smartbase_admin/integration/django_cms.py +43 -0
  21. django_smartbase_admin/locale/sk/LC_MESSAGES/django.mo +0 -0
  22. django_smartbase_admin/locale/sk/LC_MESSAGES/django.po +268 -37
  23. django_smartbase_admin/migrations/0005_sbadminuserconfiguration.py +26 -0
  24. django_smartbase_admin/migrations/0006_alter_sbadminuserconfiguration_color_scheme.py +18 -0
  25. django_smartbase_admin/models.py +22 -0
  26. django_smartbase_admin/monkeypatch/admin_readonly_field_monkeypatch.py +96 -0
  27. django_smartbase_admin/monkeypatch/fake_inline_monkeypatch.py +1 -1
  28. django_smartbase_admin/querysets.py +3 -0
  29. django_smartbase_admin/services/configuration.py +30 -0
  30. django_smartbase_admin/services/thread_local.py +6 -19
  31. django_smartbase_admin/services/views.py +80 -13
  32. django_smartbase_admin/services/xlsx_export.py +6 -0
  33. django_smartbase_admin/static/sb_admin/build/tailwind.config.js +1 -0
  34. django_smartbase_admin/static/sb_admin/build/tailwind_config_partials/colors.js +4 -0
  35. django_smartbase_admin/static/sb_admin/build/tailwind_config_partials/spacing.js +1 -0
  36. django_smartbase_admin/static/sb_admin/build/webpack.common.js +11 -8
  37. django_smartbase_admin/static/sb_admin/css/ckeditor/ckeditor_content_dark.css +208 -0
  38. django_smartbase_admin/static/sb_admin/css/coloris/coloris.min.css +1 -0
  39. django_smartbase_admin/static/sb_admin/dist/calendar.js +1 -0
  40. django_smartbase_admin/static/sb_admin/dist/calendar_style.css +1 -0
  41. django_smartbase_admin/static/sb_admin/dist/calendar_style.js +0 -0
  42. django_smartbase_admin/static/sb_admin/dist/chart.js +1 -1
  43. django_smartbase_admin/static/sb_admin/dist/main.js +1 -1
  44. django_smartbase_admin/static/sb_admin/dist/main_style.css +1 -1
  45. django_smartbase_admin/static/sb_admin/dist/table.js +1 -1
  46. django_smartbase_admin/static/sb_admin/dist/tree_widget.js +1 -0
  47. django_smartbase_admin/static/sb_admin/dist/tree_widget_style.css +1 -0
  48. django_smartbase_admin/static/sb_admin/dist/tree_widget_style.js +0 -0
  49. django_smartbase_admin/static/sb_admin/fancytree/jquery.fancytree-all-deps.min.js +1 -0
  50. django_smartbase_admin/static/sb_admin/images/file_types/file-csv.svg +11 -0
  51. django_smartbase_admin/static/sb_admin/images/file_types/file-doc.svg +11 -0
  52. django_smartbase_admin/static/sb_admin/images/file_types/file-docx.svg +11 -0
  53. django_smartbase_admin/static/sb_admin/images/file_types/file-other.svg +13 -0
  54. django_smartbase_admin/static/sb_admin/images/file_types/file-pdf.svg +11 -0
  55. django_smartbase_admin/static/sb_admin/images/file_types/file-ppt.svg +11 -0
  56. django_smartbase_admin/static/sb_admin/images/file_types/file-xls.svg +11 -0
  57. django_smartbase_admin/static/sb_admin/images/file_types/file-xlsx.svg +11 -0
  58. django_smartbase_admin/static/sb_admin/images/file_types/file-zip.svg +18 -0
  59. django_smartbase_admin/static/sb_admin/images/flags/de-at.png +0 -0
  60. django_smartbase_admin/static/sb_admin/images/flags/de-ch.png +0 -0
  61. django_smartbase_admin/static/sb_admin/images/logo_light.svg +21 -0
  62. django_smartbase_admin/static/sb_admin/js/coloris/coloris.min.js +6 -0
  63. django_smartbase_admin/static/sb_admin/js/fullcalendar.min.js +14804 -0
  64. django_smartbase_admin/static/sb_admin/js/sbadmin_prepopulated_fields_init.js +25 -0
  65. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Bolt-one.svg +3 -0
  66. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Calendar.svg +3 -0
  67. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Caution.svg +3 -0
  68. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Electric-drill.svg +3 -0
  69. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Fire-extinguisher.svg +3 -0
  70. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Gas.svg +3 -0
  71. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Lightning-fill.svg +3 -0
  72. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Moon.svg +3 -0
  73. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Phone-telephone.svg +3 -0
  74. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Printer.svg +3 -0
  75. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Pull.svg +3 -0
  76. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Sun-one.svg +3 -0
  77. django_smartbase_admin/static/sb_admin/sprites/sb_admin/Time.svg +3 -0
  78. django_smartbase_admin/static/sb_admin/src/css/_base.css +5 -1
  79. django_smartbase_admin/static/sb_admin/src/css/_colors.css +257 -82
  80. django_smartbase_admin/static/sb_admin/src/css/_components.css +61 -13
  81. django_smartbase_admin/static/sb_admin/src/css/_datepicker.css +8 -1
  82. django_smartbase_admin/static/sb_admin/src/css/_filer.css +60 -0
  83. django_smartbase_admin/static/sb_admin/src/css/_inlines.css +51 -10
  84. django_smartbase_admin/static/sb_admin/src/css/_tabulator.css +8 -2
  85. django_smartbase_admin/static/sb_admin/src/css/calendar.css +162 -0
  86. django_smartbase_admin/static/sb_admin/src/css/components/_button.css +41 -1
  87. django_smartbase_admin/static/sb_admin/src/css/components/_dropdown.css +31 -7
  88. django_smartbase_admin/static/sb_admin/src/css/components/_input.css +62 -20
  89. django_smartbase_admin/static/sb_admin/src/css/components/_modal.css +1 -1
  90. django_smartbase_admin/static/sb_admin/src/css/components/_query-builder.css +21 -2
  91. django_smartbase_admin/static/sb_admin/src/css/components/_toggle.css +12 -1
  92. django_smartbase_admin/static/sb_admin/src/css/components/_tooltip.css +8 -22
  93. django_smartbase_admin/static/sb_admin/src/css/style.css +17 -0
  94. django_smartbase_admin/static/sb_admin/src/css/tree_widget.css +411 -0
  95. django_smartbase_admin/static/sb_admin/src/js/autocomplete.js +69 -11
  96. django_smartbase_admin/static/sb_admin/src/js/calendar.js +56 -0
  97. django_smartbase_admin/static/sb_admin/src/js/chart.js +8 -22
  98. django_smartbase_admin/static/sb_admin/src/js/choices.js +18 -8
  99. django_smartbase_admin/static/sb_admin/src/js/datepicker.js +97 -336
  100. django_smartbase_admin/static/sb_admin/src/js/datepicker_plugins.js +357 -0
  101. django_smartbase_admin/static/sb_admin/src/js/main.js +306 -31
  102. django_smartbase_admin/static/sb_admin/src/js/multiselect.js +50 -41
  103. django_smartbase_admin/static/sb_admin/src/js/radio.js +31 -0
  104. django_smartbase_admin/static/sb_admin/src/js/range.js +3 -2
  105. django_smartbase_admin/static/sb_admin/src/js/table.js +34 -5
  106. django_smartbase_admin/static/sb_admin/src/js/table_modules/advanced_filter_module.js +43 -20
  107. django_smartbase_admin/static/sb_admin/src/js/table_modules/data_edit_module.js +8 -10
  108. django_smartbase_admin/static/sb_admin/src/js/table_modules/detail_view_module.js +50 -1
  109. django_smartbase_admin/static/sb_admin/src/js/table_modules/filter_module.js +10 -3
  110. django_smartbase_admin/static/sb_admin/src/js/table_modules/header_tabs_module.js +11 -11
  111. django_smartbase_admin/static/sb_admin/src/js/table_modules/selection_module.js +28 -8
  112. django_smartbase_admin/static/sb_admin/src/js/table_modules/table_params_module.js +6 -0
  113. django_smartbase_admin/static/sb_admin/src/js/table_modules/views_module.js +6 -0
  114. django_smartbase_admin/static/sb_admin/src/js/tree_widget.js +406 -0
  115. django_smartbase_admin/static/sb_admin/src/js/utils.js +56 -21
  116. django_smartbase_admin/templates/sb_admin/actions/change_form.html +176 -116
  117. django_smartbase_admin/templates/sb_admin/actions/dashboard.html +2 -2
  118. django_smartbase_admin/templates/sb_admin/actions/list.html +79 -39
  119. django_smartbase_admin/templates/sb_admin/actions/partials/action_link.html +14 -0
  120. django_smartbase_admin/templates/sb_admin/actions/partials/tabulator_header_v2.html +2 -2
  121. django_smartbase_admin/templates/sb_admin/actions/tree_list.html +63 -0
  122. django_smartbase_admin/templates/sb_admin/authentification/login_base.html +5 -1
  123. django_smartbase_admin/templates/sb_admin/components/columns.html +1 -1
  124. django_smartbase_admin/templates/sb_admin/components/filters.html +1 -0
  125. django_smartbase_admin/templates/sb_admin/components/filters_v2.html +99 -85
  126. django_smartbase_admin/templates/sb_admin/dashboard/calendar_widget.html +69 -0
  127. django_smartbase_admin/templates/sb_admin/dashboard/chart_widget.html +21 -2
  128. django_smartbase_admin/templates/sb_admin/dashboard/list_widget.html +6 -0
  129. django_smartbase_admin/templates/sb_admin/dashboard/widget_base.html +1 -1
  130. django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/date_field.html +18 -8
  131. django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/multiple_choice_field.html +1 -1
  132. django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/tree_select_filter.html +2 -0
  133. django_smartbase_admin/templates/sb_admin/filter_widgets/boolean_field.html +1 -14
  134. django_smartbase_admin/templates/sb_admin/filter_widgets/date_field.html +18 -4
  135. django_smartbase_admin/templates/sb_admin/filter_widgets/multiple_choice_field.html +14 -0
  136. django_smartbase_admin/templates/sb_admin/filter_widgets/partials/clear.html +12 -6
  137. django_smartbase_admin/templates/sb_admin/filter_widgets/radio_choice_field.html +5 -3
  138. django_smartbase_admin/templates/sb_admin/filter_widgets/tree_select_filter.html +16 -0
  139. django_smartbase_admin/templates/sb_admin/includes/change_form_title.html +3 -1
  140. django_smartbase_admin/templates/sb_admin/includes/inline_fieldset.html +48 -39
  141. django_smartbase_admin/templates/sb_admin/includes/notifications.html +2 -1
  142. django_smartbase_admin/templates/sb_admin/includes/readonly_boolean_field.html +9 -0
  143. django_smartbase_admin/templates/sb_admin/includes/readonly_field.html +12 -0
  144. django_smartbase_admin/templates/sb_admin/includes/table_inline_delete_button.html +4 -5
  145. django_smartbase_admin/templates/sb_admin/inlines/stacked_inline.html +68 -40
  146. django_smartbase_admin/templates/sb_admin/inlines/table_inline.html +76 -34
  147. django_smartbase_admin/templates/sb_admin/integrations/filer/folder_list.html +18 -0
  148. django_smartbase_admin/templates/sb_admin/navigation.html +166 -158
  149. django_smartbase_admin/templates/sb_admin/partials/modal/modal_content.html +2 -6
  150. django_smartbase_admin/templates/sb_admin/sb_admin_base.html +49 -4
  151. django_smartbase_admin/templates/sb_admin/sb_admin_base_no_sidebar.html +27 -11
  152. django_smartbase_admin/templates/sb_admin/sb_admin_js_trans.html +3 -0
  153. django_smartbase_admin/templates/sb_admin/sprites/sb_admin.svg +1 -1
  154. django_smartbase_admin/templates/sb_admin/tailwind_whitelist.html +6 -3
  155. django_smartbase_admin/templates/sb_admin/widgets/array.html +0 -1
  156. django_smartbase_admin/templates/sb_admin/widgets/attributes.html +68 -0
  157. django_smartbase_admin/templates/sb_admin/widgets/autocomplete.html +13 -2
  158. django_smartbase_admin/templates/sb_admin/widgets/{checkbox_select.html → checkbox_dropdown.html} +2 -2
  159. django_smartbase_admin/templates/sb_admin/widgets/clearable_file_input.html +2 -2
  160. django_smartbase_admin/templates/sb_admin/widgets/color_field.html +30 -0
  161. django_smartbase_admin/templates/sb_admin/widgets/date.html +8 -1
  162. django_smartbase_admin/templates/sb_admin/widgets/filer_file.html +84 -0
  163. django_smartbase_admin/templates/sb_admin/widgets/includes/related_item_buttons.html +38 -0
  164. django_smartbase_admin/templates/sb_admin/widgets/multiwidget.html +1 -1
  165. django_smartbase_admin/templates/sb_admin/widgets/radio.html +3 -2
  166. django_smartbase_admin/templates/sb_admin/widgets/radio_dropdown.html +30 -0
  167. django_smartbase_admin/templates/sb_admin/widgets/read_only_password_hash.html +3 -0
  168. django_smartbase_admin/templates/sb_admin/widgets/time.html +8 -1
  169. django_smartbase_admin/templates/sb_admin/widgets/toggle.html +1 -1
  170. django_smartbase_admin/templates/sb_admin/widgets/tree_base.html +59 -0
  171. django_smartbase_admin/templates/sb_admin/widgets/tree_select.html +24 -0
  172. django_smartbase_admin/templates/sb_admin/widgets/tree_select_inline.html +12 -0
  173. django_smartbase_admin/templatetags/sb_admin_tags.py +115 -4
  174. django_smartbase_admin/utils.py +22 -3
  175. django_smartbase_admin/views/dashboard_view.py +6 -0
  176. django_smartbase_admin/views/global_filter_view.py +8 -2
  177. django_smartbase_admin/views/translations_view.py +12 -5
  178. django_smartbase_admin/views/user_config_view.py +52 -0
  179. django_smartbase_admin-1.0.42.dist-info/METADATA +166 -0
  180. {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/RECORD +182 -118
  181. {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/WHEEL +1 -1
  182. django_smartbase_admin/templates/sb_admin/integrations/sorting/change_list.html +0 -401
  183. django_smartbase_admin-0.2.54.dist-info/METADATA +0 -25
  184. {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/LICENSE.md +0 -0
@@ -28,7 +28,8 @@
28
28
  }
29
29
  }
30
30
 
31
- .tooltip.bs-tooltip-top {
31
+ .tooltip.bs-tooltip-top,
32
+ .tooltip.bs-tooltip-auto[data-popper-placement^="top"] {
32
33
 
33
34
  .tooltip-arrow {
34
35
  bottom: 0;
@@ -41,7 +42,8 @@
41
42
  }
42
43
  }
43
44
 
44
- .tooltip.bs-tooltip-bottom {
45
+ .tooltip.bs-tooltip-bottom,
46
+ .tooltip.bs-tooltip-auto[data-popper-placement^="bottom"] {
45
47
 
46
48
  .tooltip-arrow {
47
49
  top: 0;
@@ -54,7 +56,8 @@
54
56
  }
55
57
  }
56
58
 
57
- .tooltip.bs-tooltip-end {
59
+ .tooltip.bs-tooltip-end,
60
+ .tooltip.bs-tooltip-auto[data-popper-placement^="right"] {
58
61
  padding: 0 .5rem;
59
62
 
60
63
  .tooltip-arrow {
@@ -72,7 +75,8 @@
72
75
 
73
76
 
74
77
 
75
- .tooltip.bs-tooltip-start {
78
+ .tooltip.bs-tooltip-start,
79
+ .tooltip.bs-tooltip-auto[data-popper-placement^="left"] {
76
80
  padding: 0 .5rem;
77
81
 
78
82
  .tooltip-arrow {
@@ -88,24 +92,6 @@
88
92
  }
89
93
  }
90
94
 
91
- .tooltip.bs-tooltip-auto {
92
- &[data-popper-placement^="top"] {
93
- @extend .tooltip.bs-tooltip-top;
94
- }
95
-
96
- &[data-popper-placement^="right"] {
97
- @extend .tooltip.bs-tooltip-end;
98
- }
99
-
100
- &[data-popper-placement^="bottom"] {
101
- @extend .tooltip.bs-tooltip-bottom;
102
- }
103
-
104
- &[data-popper-placement^="left"] {
105
- @extend .tooltip.bs-tooltip-start;
106
- }
107
- }
108
-
109
95
  .tooltip-inner {
110
96
  max-width: 200px;
111
97
  @apply p-8;
@@ -10,6 +10,7 @@
10
10
  @import "_utilities.css";
11
11
 
12
12
  @import "_choices.css";
13
+ @import "_filer.css";
13
14
 
14
15
  .js-ready {
15
16
  .sidebar,
@@ -18,5 +19,21 @@
18
19
  }
19
20
  }
20
21
 
22
+ .clr-field {
23
+ width: 100%;
21
24
 
25
+ > button {
26
+ z-index: 1 !important;
27
+ right: auto !important;
28
+ left: 4px !important;
29
+ top: 4px !important;
30
+ bottom: 4px !important;
31
+ height: auto !important;
32
+ transform: none !important;
33
+ @apply !rounded;
22
34
 
35
+ + input {
36
+ @apply !pl-40;
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,411 @@
1
+
2
+ .tree-widget-wrapper > .dropdown-menu {
3
+ min-width: 480px;
4
+ width: auto;
5
+ }
6
+
7
+ .fancytree-ext-table {
8
+ @apply text-14 h-full text-dark-900;
9
+ >thead {
10
+ @apply bg-dark-50 border-b border-dark-200;
11
+ }
12
+ > tbody {
13
+ > tr {
14
+ &.fancytree-selected,
15
+ &:hover,
16
+ &.fancytree-active,
17
+ &.fancytree-active:hover,
18
+ &.fancytree-selected:hover {
19
+ @apply bg-primary-50;
20
+ }
21
+ }
22
+ }
23
+ th {
24
+ @apply whitespace-nowrap p-8 bg-dark-50 text-dark-600 h-48 text-14 font-normal;
25
+ &:first-child {
26
+ @apply pl-16;
27
+ }
28
+ &:last-child {
29
+ @apply pr-16;
30
+ }
31
+ &:not(.text-right) {
32
+ @apply text-left;
33
+ }
34
+ }
35
+ td {
36
+ @apply px-8 py-0 relative;
37
+ &:not(.fancytree-checkbox-column):first-child {
38
+ width: 99%;
39
+ }
40
+ &:not(:first-child) {
41
+ @apply border-b border-dark-200;
42
+ }
43
+ &:first-child,
44
+ &.fancytree-checkbox-column + td {
45
+ overflow: hidden;
46
+ border: none;
47
+ width: 99%;
48
+ }
49
+ &.fancytree-checkbox-column {
50
+ @apply pr-0 w-32;
51
+ }
52
+ &:last-child {
53
+ @apply pr-16;
54
+ }
55
+ .fancytree-title {
56
+ @apply ml-40 whitespace-nowrap;
57
+ a {
58
+ @apply flex items-center px-8 py-4;
59
+ }
60
+ .inactive-title {
61
+ color: #8997AB;
62
+ transition: color 0.2s ease-in-out;
63
+ }
64
+ .inactive-badge {
65
+ border-radius: 4px;
66
+ background: #E2E3E7;
67
+ color: #4B5563 !important;
68
+ padding: 2px 8px;
69
+ font-size: 10px;
70
+ margin-left: 8px;
71
+ }
72
+ }
73
+ }
74
+ tr.fancytree-expanded td {
75
+ .fancytree-title a {
76
+ @apply font-semibold;
77
+ }
78
+ }
79
+ th.select-all-checkbox-wrapper{
80
+ padding-left: 8px;
81
+ }
82
+ }
83
+
84
+ .fancytree-node {
85
+ @apply flex items-center h-40 relative;
86
+ }
87
+
88
+ .fancytree-icon {
89
+ display: none;
90
+ }
91
+
92
+ .fancytree-checkbox {
93
+ @apply block relative cursor-pointer;
94
+ @apply left-0 bg-light border border-dark-300 rounded transition-colors shadow-xs;
95
+ @apply outline outline-transparent outline-2 outline-offset-2;
96
+ @apply w-20 h-20 top-0;
97
+ @apply rounded;
98
+ &:after {
99
+ content: '';
100
+ @apply block;
101
+ @apply transition-opacity;
102
+ @apply w-18 h-18;
103
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.7072 7.70712L10.7072 17.7071C10.3167 18.0976 9.68349 18.0976 9.29297 17.7071L4.29297 12.7071L5.70718 11.2929L10.0001 15.5858L19.293 6.29291L20.7072 7.70712Z' fill='%23E5E7EB' fill-rule='nonzero'/%3E%3C/svg%3E%0A");
104
+ width: 18px;
105
+ height: 18px;
106
+ top: 1px;
107
+ left: 1px;
108
+ opacity: 0;
109
+ }
110
+ &:hover {
111
+ @apply border-dark;
112
+ &:after {
113
+ opacity: 1;
114
+ }
115
+ }
116
+ }
117
+
118
+ .fancytree-selected {
119
+ opacity: 1;
120
+ .fancytree-checkbox {
121
+ @apply bg-primary border-primary;
122
+ &:after {
123
+ opacity: 1;
124
+ }
125
+ &:hover {
126
+ @apply bg-primary-600 border-primary-600;
127
+ }
128
+ }
129
+ }
130
+
131
+ .fancytree-partsel {
132
+ opacity: 1;
133
+ .fancytree-checkbox {
134
+ @apply bg-primary border-primary;
135
+ &:after {
136
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M19.25 13h-14v-2h14v2Z' fill='%23E5E7EB'/%3E%3C/svg%3E");
137
+ opacity: 1;
138
+ }
139
+ &:hover {
140
+ @apply bg-primary-600 border-primary-600;
141
+ }
142
+ }
143
+ }
144
+
145
+ .fancytree-title {
146
+ @apply relative flex items-center h-24;
147
+ }
148
+
149
+ .expander-border {
150
+ @apply absolute left-0 bottom-0 right-0;
151
+ &:after {
152
+ content: '';
153
+ @apply block absolute bottom-0 left-full;
154
+ right: -100vw;
155
+ @apply border-b border-dark-200;
156
+ }
157
+ }
158
+
159
+ .fancytree-expander {
160
+ @apply w-32 h-full;
161
+ @apply flex items-center justify-center;
162
+ background-size: 16px;
163
+ position: absolute;
164
+ --expander-border: 2px solid var(--color-dark-400);
165
+ >div {
166
+ @apply w-20 h-20;
167
+ background-position: center;
168
+ position: relative;
169
+ z-index: 1;
170
+ }
171
+ &:before,
172
+ &:after {
173
+ content: '';
174
+ @apply block absolute;
175
+ }
176
+ &:before {
177
+ border-bottom: var(--expander-border);
178
+ top: 50%;
179
+ left: -50%;
180
+ right: 0;
181
+ @apply mr-16;
182
+ }
183
+ &:after {
184
+ border-left: var(--expander-border);
185
+ left: 50%;
186
+ }
187
+ &.level-1 {
188
+ &:before,
189
+ &:after {
190
+ content: none;
191
+ }
192
+ }
193
+ &.expanded-parent {
194
+ .expander-additional {
195
+ position: absolute;
196
+ top: 0;
197
+ bottom: 0;
198
+ &:before {
199
+ content: '';
200
+ display: block;
201
+ position: absolute;
202
+ border-left: var(--expander-border);
203
+ top: 0;
204
+ bottom: 0;
205
+ }
206
+ }
207
+ }
208
+ &:hover {
209
+ >div {
210
+ filter: brightness(0.5);
211
+ }
212
+ }
213
+ }
214
+
215
+ tr.fancytree-has-children span.fancytree-expander:before {
216
+ right: 50%;
217
+ }
218
+
219
+ .fancytree-ico-e {
220
+ .fancytree-expander {
221
+ &:before {
222
+ bottom: 50%;
223
+ }
224
+ &:after {
225
+ top: 50%;
226
+ bottom: 0;
227
+ @apply mt-16;
228
+ }
229
+ }
230
+ }
231
+
232
+ .fancytree-ico-c {
233
+ .fancytree-expander {
234
+ &:before {
235
+
236
+ }
237
+ &:after {
238
+ left: -50%;
239
+ }
240
+ }
241
+ }
242
+
243
+ .fancytree-lastsib span.fancytree-expander.expanded-parent .expander-additional-last:before {
244
+ bottom: 50% !important;
245
+ }
246
+
247
+ .fancytree-exp-c, .fancytree-exp-e {
248
+ &:first-child .fancytree-expander:after {
249
+ top: 50%;
250
+ }
251
+ }
252
+
253
+ .fancytree-exp-cl span.fancytree-expander:after {
254
+ bottom: 50%;
255
+ }
256
+
257
+ .fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander {
258
+ visibility: visible;
259
+ }
260
+
261
+ .fancytree-exp-n, .fancytree-exp-nl {
262
+ .fancytree-expander {
263
+ > div {
264
+ display: none;
265
+ }
266
+ &:before {
267
+ @apply mr-8;
268
+ }
269
+ }
270
+ }
271
+
272
+ .fancytree-exp-nl .fancytree-expander:after {
273
+ bottom: 50%;
274
+ }
275
+
276
+ .fancytree-exp-c, .fancytree-exp-cl {
277
+ .fancytree-expander > div {
278
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12ZM12 3C7.02943 3 3 7.02943 3 12C3 16.9706 7.02943 21 12 21C16.9706 21 21 16.9706 21 12C21 7.02943 16.9706 3 12 3ZM11 11V8H13V11H16V13H13V16H11V13H8V11H11Z' fill='%236B7280'/%3E%3C/svg%3E");
279
+ }
280
+ }
281
+
282
+ .fancytree-exp-e, .fancytree-exp-ed, .fancytree-exp-edl, .fancytree-exp-el {
283
+ .fancytree-expander > div {
284
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1ZM3 12C3 7.02943 7.02943 3 12 3C16.9706 3 21 7.02943 21 12C21 16.9706 16.9706 21 12 21C7.02943 21 3 16.9706 3 12ZM8 13H16V11H8V13Z' fill='%236B7280'/%3E%3C/svg%3E");
285
+ }
286
+ }
287
+
288
+ .fancytree-hide {
289
+ @apply hidden;
290
+ }
291
+
292
+ .fancytree-submatch:not(.fancytree-match) > *{
293
+ opacity: 0.5;
294
+ }
295
+
296
+ .fancytree-status-merged {
297
+ @apply h-40;
298
+ }
299
+
300
+ .fancytree-statusnode-loading,
301
+ .fancytree-statusnode-error {
302
+ pointer-events: none;
303
+ }
304
+
305
+ .filter-wrapper .fancytree-ext-table {
306
+ > thead {
307
+ @apply hidden;
308
+ }
309
+ .fancytree-checkbox-column {
310
+ @apply pl-12 pr-4;
311
+ @apply sticky left-0 bg-light z-1;
312
+ + td {
313
+ @apply pl-0 isolate;
314
+ }
315
+ }
316
+
317
+ > tbody > tr {
318
+ &.fancytree-selected,
319
+ &:hover,
320
+ &.fancytree-active,
321
+ &.fancytree-active:hover,
322
+ &.fancytree-selected:hover {
323
+ > .fancytree-checkbox-column {
324
+ @apply bg-primary-50;
325
+ }
326
+ }
327
+ }
328
+ }
329
+
330
+ #fancytree-drop-marker {
331
+ height: 42px;
332
+ width: 100%;
333
+ position: absolute;
334
+ margin: 0;
335
+
336
+ &:before {
337
+ content: '';
338
+ display: block;
339
+ position: absolute;
340
+ left: 0;
341
+ top: 0;
342
+ width: 100%;
343
+ height: 100%;
344
+
345
+ }
346
+
347
+ &:after {
348
+ content: '';
349
+ display: block;
350
+ position: absolute;
351
+ top: 0;
352
+ bottom: 0;
353
+ right: 100%;
354
+ width: 28px;
355
+ @apply bg-no-repeat;
356
+ }
357
+ }
358
+
359
+ #fancytree-drop-marker.fancytree-drop-before {
360
+ &:before {
361
+ @apply border-t-2 border-primary;
362
+ margin-top: 12px;
363
+ }
364
+
365
+ &:after {
366
+ background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5859 10L15.293 7.70711L16.7072 6.29289L20.7072 10.2929C21.0977 10.6834 21.0977 11.3166 20.7072 11.7071L16.7072 15.7071L15.293 14.2929L17.5859 12H5.5C5.22385 12 5 12.2238 5 12.5V19H3V12.5C3 11.1193 4.1193 10 5.5 10H17.5859Z" fill="%2300959D"/></svg>');
367
+ background-position: top right;
368
+ top: 2px;
369
+ right: calc(100% + 27px);
370
+ }
371
+ }
372
+
373
+ #fancytree-drop-marker.fancytree-drop-after {
374
+ &:before {
375
+ @apply border-b-2 border-primary;
376
+ margin-top: -12px;
377
+ }
378
+
379
+ &:after {
380
+ bottom: 2px;
381
+ transform: rotateX(180deg);
382
+ background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5859 10L15.293 7.70711L16.7072 6.29289L20.7072 10.2929C21.0977 10.6834 21.0977 11.3166 20.7072 11.7071L16.7072 15.7071L15.293 14.2929L17.5859 12H5.5C5.22385 12 5 12.2238 5 12.5V19H3V12.5C3 11.1193 4.1193 10 5.5 10H17.5859Z" fill="%2300959D"/></svg>');
383
+ background-position: top right;
384
+ right: calc(100% + 27px);
385
+
386
+ }
387
+ }
388
+
389
+ #fancytree-drop-marker.fancytree-drop-over {
390
+ &:before {
391
+ @apply border-y-2 border-primary;
392
+ }
393
+
394
+ &:after {
395
+ background-position: center left 2px;
396
+ top: 10px;
397
+ bottom: 10px;
398
+ background-color: white;
399
+ background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12ZM12 3C7.02943 3 3 7.02943 3 12C3 16.9706 7.02943 21 12 21C16.9706 21 21 16.9706 21 12C21 7.02943 16.9706 3 12 3ZM13.8315 13.25H7.24609V11.25H13.8315L11.0386 8.45711L12.4528 7.04289L16.9528 11.5429C17.3433 11.9334 17.3433 12.5666 16.9528 12.9571L12.4528 17.4571L11.0386 16.0429L13.8315 13.25Z" fill="%2300959D"/></svg>');
400
+ }
401
+ }
402
+
403
+ span.fancytree-drag-source.fancytree-drag-remove {
404
+ opacity: 0.5;
405
+ }
406
+
407
+ .fancytree-ext-table:active {
408
+ > tbody > tr.fancytree-active {
409
+ background-color: transparent;
410
+ }
411
+ }
@@ -5,10 +5,6 @@ import debounce from "lodash/debounce"
5
5
 
6
6
  export default class Autocomplete {
7
7
  constructor() {
8
- const choiceElements = document.querySelectorAll('.js-autocomplete')
9
- choiceElements.forEach((choiceInput) => {
10
- this.initAutocomplete(choiceInput)
11
- })
12
8
  document.addEventListener('formset:added', (event) => {
13
9
  const totalFormsCount = document.querySelector(`#id_${event.detail.formsetName}-TOTAL_FORMS`).value - 1
14
10
  const formsetElements = document.querySelectorAll(`#${event.target.id} *`)
@@ -21,17 +17,21 @@ export default class Autocomplete {
21
17
  const choiceElementsInline = document.querySelectorAll(`#${event.target.id} [data-autocomplete-data-id]`)
22
18
  choiceElementsInline.forEach((choiceInput) => {
23
19
  choiceInput.setAttribute('data-autocomplete-data-id', choiceInput.getAttribute('data-autocomplete-data-id').replace('__prefix__', totalFormsCount))
24
- this.initAutocomplete(choiceInput, totalFormsCount)
25
20
  })
26
- this.handleDynamiclyAddedAutocomplete(event.target)
27
- })
28
- document.body.addEventListener('SBModalShown', () => {
29
- this.handleDynamiclyAddedAutocomplete(document.getElementById('sb-admin-modal'))
21
+ this.handleDynamiclyAddedAutocomplete(event.target, totalFormsCount)
30
22
  })
31
23
  this.handleDynamiclyAddedAutocomplete(document)
24
+ document.body.addEventListener('sbadmin:modal-change-form-response', (event) => {
25
+ const {field, id, label} = event.detail
26
+ this.selectAutocompleteItem(field, id, label)
27
+ })
32
28
  }
33
29
 
34
- handleDynamiclyAddedAutocomplete(el) {
30
+ handleDynamiclyAddedAutocomplete(el, totalFormsCount) {
31
+ const choiceElements = el.querySelectorAll('.js-autocomplete')
32
+ choiceElements.forEach((choiceInput) => {
33
+ this.initAutocomplete(choiceInput, totalFormsCount)
34
+ })
35
35
  el.querySelectorAll('.js-autocomplete-detail').forEach(item => {
36
36
  filterInputValueChangedUtil(item)
37
37
  item.addEventListener('SBAutocompleteChange', (e) => {
@@ -41,6 +41,10 @@ export default class Autocomplete {
41
41
  }
42
42
 
43
43
  initAutocomplete(choiceInput, totalFormsCount = null) {
44
+ if (choiceInput.closest('.choices')) {
45
+ console.warn('Attempted to initialize already initialized autocomplete!', choiceInput)
46
+ return
47
+ }
44
48
  const dataEl = document.getElementById(choiceInput.dataset.autocompleteDataId)
45
49
  const autocompleteData = JSON.parse(dataEl.textContent)
46
50
  let inputElId = autocompleteData.input_id
@@ -88,6 +92,13 @@ export default class Autocomplete {
88
92
  choicesJS.SBhasNextPage = true
89
93
  this.search(choicesJS.SBcurrentSearchTerm, choicesJS, inputEl, autocompleteData, choicesJS.SBcurrentPage)
90
94
  }, 200))
95
+
96
+ choiceInput.addEventListener('selectItem', (event) => {
97
+ if(!event.target.hasAttribute('multiple')) {
98
+ this.updateEditButtonUrl(event)
99
+ }
100
+ choicesJSListeners.selectItem(event.detail, inputEl)
101
+ })
91
102
  choiceInput.addEventListener('addItem', () => {
92
103
  choicesJSListeners.addItem(choicesJS, inputEl)
93
104
  })
@@ -97,6 +108,7 @@ export default class Autocomplete {
97
108
  choiceInput.addEventListener('change', (e) => {
98
109
  if(!e.target.hasAttribute('multiple')) {
99
110
  choicesJS.SBwrapperElButton.click()
111
+ this.updateEditButtonUrl(e)
100
112
  }
101
113
  inputEl.dispatchEvent(new CustomEvent('SBAutocompleteChange'))
102
114
  })
@@ -123,7 +135,14 @@ export default class Autocomplete {
123
135
  })
124
136
  addNewButton?.addEventListener('click', (event) => {
125
137
  choicesJS.clearStore()
126
- choicesJS.setValue([event.currentTarget.dataset.value])
138
+ choicesJS.setValue([
139
+ {
140
+ value:event.currentTarget.dataset.value,
141
+ customProperties: {
142
+ create: true
143
+ }
144
+ }
145
+ ])
127
146
  choicesJS.SBwrapperElButton.click()
128
147
  filterInputValueChangedUtil(inputEl)
129
148
  })
@@ -247,6 +266,7 @@ export default class Autocomplete {
247
266
  choicesJSChoices.push({
248
267
  value: value.value,
249
268
  label: value.label,
269
+ customProperties: value.customProperties,
250
270
  selected: true
251
271
  })
252
272
  })
@@ -277,4 +297,42 @@ export default class Autocomplete {
277
297
  choicesJS.SBcurrentPage = requestedPage
278
298
  })
279
299
  }
300
+
301
+ selectAutocompleteItem(field, id, label) {
302
+ const selectEl = document.querySelector(`select.js-autocomplete[data-autocomplete-data-id="${field}_data"]`)
303
+ if (selectEl) {
304
+ selectEl.dispatchEvent(new CustomEvent('selectItem', {
305
+ detail: {value: id, label: label},
306
+ }))
307
+ document.getElementById(`${field}-value`).textContent = label
308
+ }
309
+ }
310
+
311
+ updateEditButtonUrl(event) {
312
+ const group = event.srcElement.dataset.autocompleteDataId?.replace("_data", "-wrapper")
313
+ if (!group) return
314
+
315
+ const wrapper = document.getElementById(group)
316
+ const editButton = wrapper?.querySelector('.edit-button')
317
+ const value = event.detail?.value
318
+
319
+ if (editButton && value) {
320
+ let originalUrl = editButton.getAttribute('hx-get') || editButton.dataset.addUrl || ''
321
+ if (!originalUrl) return
322
+
323
+ const newUrl = originalUrl
324
+ .replace(/\/add\/\?/, `/${value}/change/?`)
325
+ .replace(/\/\d+\/change\/\?/, `/${value}/change/?`)
326
+
327
+ const newEditButton = editButton.cloneNode(true)
328
+ newEditButton.setAttribute('hx-get', newUrl)
329
+ newEditButton.classList.remove('hidden')
330
+
331
+ editButton.replaceWith(newEditButton)
332
+ window.htmx.process(newEditButton)
333
+ }
334
+ }
335
+
336
+
337
+
280
338
  }
@@ -0,0 +1,56 @@
1
+ import {filterInputValueChangedUtil, filterInputValueChangeListener} from "./utils"
2
+
3
+ class SBAdminCalendar {
4
+ constructor(options) {
5
+ this.options = options
6
+ this.calendar = null
7
+ this.options['calendarOptions'] = this.options['calendarOptions'] || {}
8
+
9
+ if(!Object.hasOwn(this.options.calendarOptions, "events") || !this.options.calendarOptions.events) {
10
+ throw Error('Missing events property!')
11
+ }
12
+ if(typeof this.options.calendarOptions.events === 'string') {
13
+ this.options.calendarOptions.events = {
14
+ url: this.options.calendarOptions.events
15
+ }
16
+ }
17
+ this.options.calendarOptions.events['extraParams'] = this.options.calendarOptions.events['extraParams'] || {}
18
+ this.options.calendarOptions.events.extraParams = () => {
19
+ return {
20
+ ...this.options.calendarOptions.events['extraParams'] || {},
21
+ ...this.getFilterData()
22
+ }
23
+ }
24
+ this.initCalendar()
25
+ this.initFilters()
26
+ }
27
+
28
+ initCalendar() {
29
+ const calendarEl = document.getElementById(`${this.options.widgetId}-calendar`)
30
+
31
+ // eslint-disable-next-line no-undef
32
+ this.calendar = new FullCalendar.Calendar(calendarEl, this.options.calendarOptions || {})
33
+ this.calendar.render()
34
+ }
35
+
36
+ getFilterData() {
37
+ const filterForm = document.querySelector(`#${this.options.widgetId}-filter-form`)
38
+ const filterData = new FormData(filterForm).entries()
39
+ const filterDataNotEmpty = {}
40
+ for (const [key, value] of filterData) {
41
+ if (value) {
42
+ filterDataNotEmpty[key] = value
43
+ }
44
+ }
45
+ return filterDataNotEmpty
46
+ }
47
+
48
+ initFilters() {
49
+ filterInputValueChangeListener(`[form="${this.options.widgetId}-filter-form"]`, (event) => {
50
+ this.calendar.refetchEvents()
51
+ filterInputValueChangedUtil(event.target)
52
+ })
53
+ }
54
+ }
55
+
56
+ window.SBAdminCalendarClass = SBAdminCalendar