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.
- django_smartbase_admin/actions/admin_action_list.py +79 -38
- django_smartbase_admin/actions/advanced_filters.py +24 -1
- django_smartbase_admin/admin/admin_base.py +402 -97
- django_smartbase_admin/admin/site.py +93 -35
- django_smartbase_admin/admin/widgets.py +636 -26
- django_smartbase_admin/apps.py +2 -0
- django_smartbase_admin/engine/actions.py +34 -16
- django_smartbase_admin/engine/admin_base_view.py +252 -115
- django_smartbase_admin/engine/configuration.py +186 -4
- django_smartbase_admin/engine/const.py +6 -0
- django_smartbase_admin/engine/dashboard.py +49 -24
- django_smartbase_admin/engine/fake_inline.py +15 -11
- django_smartbase_admin/engine/field.py +42 -12
- django_smartbase_admin/engine/field_formatter.py +38 -14
- django_smartbase_admin/engine/filter_widgets.py +348 -24
- django_smartbase_admin/engine/menu_item.py +8 -5
- django_smartbase_admin/engine/modal_view.py +12 -7
- django_smartbase_admin/engine/request.py +2 -0
- django_smartbase_admin/integration/__init__.py +0 -0
- django_smartbase_admin/integration/django_cms.py +43 -0
- django_smartbase_admin/locale/sk/LC_MESSAGES/django.mo +0 -0
- django_smartbase_admin/locale/sk/LC_MESSAGES/django.po +268 -37
- django_smartbase_admin/migrations/0005_sbadminuserconfiguration.py +26 -0
- django_smartbase_admin/migrations/0006_alter_sbadminuserconfiguration_color_scheme.py +18 -0
- django_smartbase_admin/models.py +22 -0
- django_smartbase_admin/monkeypatch/admin_readonly_field_monkeypatch.py +96 -0
- django_smartbase_admin/monkeypatch/fake_inline_monkeypatch.py +1 -1
- django_smartbase_admin/querysets.py +3 -0
- django_smartbase_admin/services/configuration.py +30 -0
- django_smartbase_admin/services/thread_local.py +6 -19
- django_smartbase_admin/services/views.py +80 -13
- django_smartbase_admin/services/xlsx_export.py +6 -0
- django_smartbase_admin/static/sb_admin/build/tailwind.config.js +1 -0
- django_smartbase_admin/static/sb_admin/build/tailwind_config_partials/colors.js +4 -0
- django_smartbase_admin/static/sb_admin/build/tailwind_config_partials/spacing.js +1 -0
- django_smartbase_admin/static/sb_admin/build/webpack.common.js +11 -8
- django_smartbase_admin/static/sb_admin/css/ckeditor/ckeditor_content_dark.css +208 -0
- django_smartbase_admin/static/sb_admin/css/coloris/coloris.min.css +1 -0
- django_smartbase_admin/static/sb_admin/dist/calendar.js +1 -0
- django_smartbase_admin/static/sb_admin/dist/calendar_style.css +1 -0
- django_smartbase_admin/static/sb_admin/dist/calendar_style.js +0 -0
- django_smartbase_admin/static/sb_admin/dist/chart.js +1 -1
- django_smartbase_admin/static/sb_admin/dist/main.js +1 -1
- django_smartbase_admin/static/sb_admin/dist/main_style.css +1 -1
- django_smartbase_admin/static/sb_admin/dist/table.js +1 -1
- django_smartbase_admin/static/sb_admin/dist/tree_widget.js +1 -0
- django_smartbase_admin/static/sb_admin/dist/tree_widget_style.css +1 -0
- django_smartbase_admin/static/sb_admin/dist/tree_widget_style.js +0 -0
- django_smartbase_admin/static/sb_admin/fancytree/jquery.fancytree-all-deps.min.js +1 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-csv.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-doc.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-docx.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-other.svg +13 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-pdf.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-ppt.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-xls.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-xlsx.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-zip.svg +18 -0
- django_smartbase_admin/static/sb_admin/images/flags/de-at.png +0 -0
- django_smartbase_admin/static/sb_admin/images/flags/de-ch.png +0 -0
- django_smartbase_admin/static/sb_admin/images/logo_light.svg +21 -0
- django_smartbase_admin/static/sb_admin/js/coloris/coloris.min.js +6 -0
- django_smartbase_admin/static/sb_admin/js/fullcalendar.min.js +14804 -0
- django_smartbase_admin/static/sb_admin/js/sbadmin_prepopulated_fields_init.js +25 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Bolt-one.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Calendar.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Caution.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Electric-drill.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Fire-extinguisher.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Gas.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Lightning-fill.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Moon.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Phone-telephone.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Printer.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Pull.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Sun-one.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Time.svg +3 -0
- django_smartbase_admin/static/sb_admin/src/css/_base.css +5 -1
- django_smartbase_admin/static/sb_admin/src/css/_colors.css +257 -82
- django_smartbase_admin/static/sb_admin/src/css/_components.css +61 -13
- django_smartbase_admin/static/sb_admin/src/css/_datepicker.css +8 -1
- django_smartbase_admin/static/sb_admin/src/css/_filer.css +60 -0
- django_smartbase_admin/static/sb_admin/src/css/_inlines.css +51 -10
- django_smartbase_admin/static/sb_admin/src/css/_tabulator.css +8 -2
- django_smartbase_admin/static/sb_admin/src/css/calendar.css +162 -0
- django_smartbase_admin/static/sb_admin/src/css/components/_button.css +41 -1
- django_smartbase_admin/static/sb_admin/src/css/components/_dropdown.css +31 -7
- django_smartbase_admin/static/sb_admin/src/css/components/_input.css +62 -20
- django_smartbase_admin/static/sb_admin/src/css/components/_modal.css +1 -1
- django_smartbase_admin/static/sb_admin/src/css/components/_query-builder.css +21 -2
- django_smartbase_admin/static/sb_admin/src/css/components/_toggle.css +12 -1
- django_smartbase_admin/static/sb_admin/src/css/components/_tooltip.css +8 -22
- django_smartbase_admin/static/sb_admin/src/css/style.css +17 -0
- django_smartbase_admin/static/sb_admin/src/css/tree_widget.css +411 -0
- django_smartbase_admin/static/sb_admin/src/js/autocomplete.js +69 -11
- django_smartbase_admin/static/sb_admin/src/js/calendar.js +56 -0
- django_smartbase_admin/static/sb_admin/src/js/chart.js +8 -22
- django_smartbase_admin/static/sb_admin/src/js/choices.js +18 -8
- django_smartbase_admin/static/sb_admin/src/js/datepicker.js +97 -336
- django_smartbase_admin/static/sb_admin/src/js/datepicker_plugins.js +357 -0
- django_smartbase_admin/static/sb_admin/src/js/main.js +306 -31
- django_smartbase_admin/static/sb_admin/src/js/multiselect.js +50 -41
- django_smartbase_admin/static/sb_admin/src/js/radio.js +31 -0
- django_smartbase_admin/static/sb_admin/src/js/range.js +3 -2
- django_smartbase_admin/static/sb_admin/src/js/table.js +34 -5
- django_smartbase_admin/static/sb_admin/src/js/table_modules/advanced_filter_module.js +43 -20
- django_smartbase_admin/static/sb_admin/src/js/table_modules/data_edit_module.js +8 -10
- django_smartbase_admin/static/sb_admin/src/js/table_modules/detail_view_module.js +50 -1
- django_smartbase_admin/static/sb_admin/src/js/table_modules/filter_module.js +10 -3
- django_smartbase_admin/static/sb_admin/src/js/table_modules/header_tabs_module.js +11 -11
- django_smartbase_admin/static/sb_admin/src/js/table_modules/selection_module.js +28 -8
- django_smartbase_admin/static/sb_admin/src/js/table_modules/table_params_module.js +6 -0
- django_smartbase_admin/static/sb_admin/src/js/table_modules/views_module.js +6 -0
- django_smartbase_admin/static/sb_admin/src/js/tree_widget.js +406 -0
- django_smartbase_admin/static/sb_admin/src/js/utils.js +56 -21
- django_smartbase_admin/templates/sb_admin/actions/change_form.html +176 -116
- django_smartbase_admin/templates/sb_admin/actions/dashboard.html +2 -2
- django_smartbase_admin/templates/sb_admin/actions/list.html +79 -39
- django_smartbase_admin/templates/sb_admin/actions/partials/action_link.html +14 -0
- django_smartbase_admin/templates/sb_admin/actions/partials/tabulator_header_v2.html +2 -2
- django_smartbase_admin/templates/sb_admin/actions/tree_list.html +63 -0
- django_smartbase_admin/templates/sb_admin/authentification/login_base.html +5 -1
- django_smartbase_admin/templates/sb_admin/components/columns.html +1 -1
- django_smartbase_admin/templates/sb_admin/components/filters.html +1 -0
- django_smartbase_admin/templates/sb_admin/components/filters_v2.html +99 -85
- django_smartbase_admin/templates/sb_admin/dashboard/calendar_widget.html +69 -0
- django_smartbase_admin/templates/sb_admin/dashboard/chart_widget.html +21 -2
- django_smartbase_admin/templates/sb_admin/dashboard/list_widget.html +6 -0
- django_smartbase_admin/templates/sb_admin/dashboard/widget_base.html +1 -1
- django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/date_field.html +18 -8
- django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/multiple_choice_field.html +1 -1
- django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/tree_select_filter.html +2 -0
- django_smartbase_admin/templates/sb_admin/filter_widgets/boolean_field.html +1 -14
- django_smartbase_admin/templates/sb_admin/filter_widgets/date_field.html +18 -4
- django_smartbase_admin/templates/sb_admin/filter_widgets/multiple_choice_field.html +14 -0
- django_smartbase_admin/templates/sb_admin/filter_widgets/partials/clear.html +12 -6
- django_smartbase_admin/templates/sb_admin/filter_widgets/radio_choice_field.html +5 -3
- django_smartbase_admin/templates/sb_admin/filter_widgets/tree_select_filter.html +16 -0
- django_smartbase_admin/templates/sb_admin/includes/change_form_title.html +3 -1
- django_smartbase_admin/templates/sb_admin/includes/inline_fieldset.html +48 -39
- django_smartbase_admin/templates/sb_admin/includes/notifications.html +2 -1
- django_smartbase_admin/templates/sb_admin/includes/readonly_boolean_field.html +9 -0
- django_smartbase_admin/templates/sb_admin/includes/readonly_field.html +12 -0
- django_smartbase_admin/templates/sb_admin/includes/table_inline_delete_button.html +4 -5
- django_smartbase_admin/templates/sb_admin/inlines/stacked_inline.html +68 -40
- django_smartbase_admin/templates/sb_admin/inlines/table_inline.html +76 -34
- django_smartbase_admin/templates/sb_admin/integrations/filer/folder_list.html +18 -0
- django_smartbase_admin/templates/sb_admin/navigation.html +166 -158
- django_smartbase_admin/templates/sb_admin/partials/modal/modal_content.html +2 -6
- django_smartbase_admin/templates/sb_admin/sb_admin_base.html +49 -4
- django_smartbase_admin/templates/sb_admin/sb_admin_base_no_sidebar.html +27 -11
- django_smartbase_admin/templates/sb_admin/sb_admin_js_trans.html +3 -0
- django_smartbase_admin/templates/sb_admin/sprites/sb_admin.svg +1 -1
- django_smartbase_admin/templates/sb_admin/tailwind_whitelist.html +6 -3
- django_smartbase_admin/templates/sb_admin/widgets/array.html +0 -1
- django_smartbase_admin/templates/sb_admin/widgets/attributes.html +68 -0
- django_smartbase_admin/templates/sb_admin/widgets/autocomplete.html +13 -2
- django_smartbase_admin/templates/sb_admin/widgets/{checkbox_select.html → checkbox_dropdown.html} +2 -2
- django_smartbase_admin/templates/sb_admin/widgets/clearable_file_input.html +2 -2
- django_smartbase_admin/templates/sb_admin/widgets/color_field.html +30 -0
- django_smartbase_admin/templates/sb_admin/widgets/date.html +8 -1
- django_smartbase_admin/templates/sb_admin/widgets/filer_file.html +84 -0
- django_smartbase_admin/templates/sb_admin/widgets/includes/related_item_buttons.html +38 -0
- django_smartbase_admin/templates/sb_admin/widgets/multiwidget.html +1 -1
- django_smartbase_admin/templates/sb_admin/widgets/radio.html +3 -2
- django_smartbase_admin/templates/sb_admin/widgets/radio_dropdown.html +30 -0
- django_smartbase_admin/templates/sb_admin/widgets/read_only_password_hash.html +3 -0
- django_smartbase_admin/templates/sb_admin/widgets/time.html +8 -1
- django_smartbase_admin/templates/sb_admin/widgets/toggle.html +1 -1
- django_smartbase_admin/templates/sb_admin/widgets/tree_base.html +59 -0
- django_smartbase_admin/templates/sb_admin/widgets/tree_select.html +24 -0
- django_smartbase_admin/templates/sb_admin/widgets/tree_select_inline.html +12 -0
- django_smartbase_admin/templatetags/sb_admin_tags.py +115 -4
- django_smartbase_admin/utils.py +22 -3
- django_smartbase_admin/views/dashboard_view.py +6 -0
- django_smartbase_admin/views/global_filter_view.py +8 -2
- django_smartbase_admin/views/translations_view.py +12 -5
- django_smartbase_admin/views/user_config_view.py +52 -0
- django_smartbase_admin-1.0.42.dist-info/METADATA +166 -0
- {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/RECORD +182 -118
- {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/WHEEL +1 -1
- django_smartbase_admin/templates/sb_admin/integrations/sorting/change_list.html +0 -401
- django_smartbase_admin-0.2.54.dist-info/METADATA +0 -25
- {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/LICENSE.md +0 -0
|
@@ -24,31 +24,16 @@ class SBAdminChart {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
initChart() {
|
|
27
|
+
this.options.formId = this.options.formId || `${this.options.widgetId}-filter-form`
|
|
27
28
|
const ctx = document.getElementById(`${this.options.widgetId}-chart`)
|
|
28
29
|
this.chart = new Chart(ctx, {
|
|
29
30
|
type: this.options.chartType,
|
|
30
31
|
data: {},
|
|
31
|
-
options: {
|
|
32
|
-
|
|
33
|
-
x: {
|
|
34
|
-
ticks: {
|
|
35
|
-
font: {
|
|
36
|
-
weight: 600,
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
y: {
|
|
41
|
-
ticks: {
|
|
42
|
-
font: {
|
|
43
|
-
weight: 600,
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
32
|
+
options: this.options.chartOptions || {},
|
|
33
|
+
plugins: this.options.chartPlugins || []
|
|
49
34
|
})
|
|
50
35
|
this.refreshData()
|
|
51
|
-
document.addEventListener(
|
|
36
|
+
document.addEventListener(window.sb_admin_const.TABLE_RELOAD_DATA_EVENT_NAME, () => {
|
|
52
37
|
this.refreshData()
|
|
53
38
|
})
|
|
54
39
|
}
|
|
@@ -63,7 +48,7 @@ class SBAdminChart {
|
|
|
63
48
|
}
|
|
64
49
|
|
|
65
50
|
refreshData() {
|
|
66
|
-
const filterForm = document.
|
|
51
|
+
const filterForm = document.getElementById(this.options.formId)
|
|
67
52
|
const filterData = new FormData(filterForm).entries()
|
|
68
53
|
const filterDataNotEmpty = {}
|
|
69
54
|
for (const [key, value] of filterData) {
|
|
@@ -81,7 +66,7 @@ class SBAdminChart {
|
|
|
81
66
|
.then(res => {
|
|
82
67
|
this.chart.data.labels = res.data.main.labels
|
|
83
68
|
this.chart.data.datasets = this.processDatasets(res.data.main.datasets)
|
|
84
|
-
if (this.chart.data.labels.length
|
|
69
|
+
if (this.chart.data.labels.length >= 1) {
|
|
85
70
|
this.chart.canvas.classList.remove('!hidden')
|
|
86
71
|
} else {
|
|
87
72
|
this.chart.canvas.classList.add('!hidden')
|
|
@@ -112,11 +97,12 @@ class SBAdminChart {
|
|
|
112
97
|
}
|
|
113
98
|
})
|
|
114
99
|
}
|
|
100
|
+
this.chart.canvas.dispatchEvent(new CustomEvent('chartDataLoaded'))
|
|
115
101
|
})
|
|
116
102
|
}
|
|
117
103
|
|
|
118
104
|
initFilters() {
|
|
119
|
-
filterInputValueChangeListener(`[form="${this.options.
|
|
105
|
+
filterInputValueChangeListener(`[form="${this.options.formId}"]`, (event) => {
|
|
120
106
|
this.refreshData()
|
|
121
107
|
filterInputValueChangedUtil(event.target)
|
|
122
108
|
})
|
|
@@ -49,16 +49,29 @@ export const choicesJSOptions = (choiceInput) => ({
|
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
|
|
52
|
+
const getChoiceValueForInput = (currentValue) => {
|
|
53
|
+
let value = {
|
|
54
|
+
'value': currentValue.value,
|
|
55
|
+
'label': currentValue.label,
|
|
56
|
+
}
|
|
57
|
+
if(currentValue.customProperties?.create){
|
|
58
|
+
value['create'] = true
|
|
59
|
+
}
|
|
60
|
+
return value
|
|
61
|
+
}
|
|
62
|
+
|
|
52
63
|
export const choicesJSListeners = {
|
|
64
|
+
'selectItem': (item, inputEl) => {
|
|
65
|
+
if (!item) return
|
|
66
|
+
const choiceValue = [getChoiceValueForInput(item)]
|
|
67
|
+
inputEl.value = JSON.stringify(choiceValue)
|
|
68
|
+
},
|
|
53
69
|
'addItem': (choicesJS, inputEl) => {
|
|
54
70
|
const choiceValue = []
|
|
55
71
|
let choicesJSValue = choicesJS.getValue()
|
|
56
72
|
choicesJSValue = Array.isArray(choicesJSValue) ? choicesJSValue : [choicesJSValue]
|
|
57
73
|
choicesJSValue.forEach(function (currentValue) {
|
|
58
|
-
choiceValue.push(
|
|
59
|
-
'value': currentValue.value,
|
|
60
|
-
'label': currentValue.label,
|
|
61
|
-
})
|
|
74
|
+
choiceValue.push(getChoiceValueForInput(currentValue))
|
|
62
75
|
})
|
|
63
76
|
inputEl.value = JSON.stringify(choiceValue)
|
|
64
77
|
},
|
|
@@ -68,10 +81,7 @@ export const choicesJSListeners = {
|
|
|
68
81
|
if (choicesJSValue !== undefined) {
|
|
69
82
|
choicesJSValue = Array.isArray(choicesJSValue) ? choicesJSValue : [choicesJSValue]
|
|
70
83
|
choicesJSValue.forEach(function (currentValue) {
|
|
71
|
-
choiceValue.push(
|
|
72
|
-
'value': currentValue.value,
|
|
73
|
-
'label': currentValue.label,
|
|
74
|
-
})
|
|
84
|
+
choiceValue.push(getChoiceValueForInput(currentValue))
|
|
75
85
|
})
|
|
76
86
|
}
|
|
77
87
|
inputEl.value = JSON.stringify(choiceValue)
|
|
@@ -1,357 +1,133 @@
|
|
|
1
1
|
import flatpickr from "flatpickr"
|
|
2
|
-
import {monthToStr} from "flatpickr/dist/esm/utils/formatting"
|
|
3
2
|
import {createIcon} from "./utils"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import {
|
|
4
|
+
createRadioInput,
|
|
5
|
+
customActionsPlugin,
|
|
6
|
+
monthYearViewsPlugin
|
|
7
|
+
} from "./datepicker_plugins"
|
|
8
8
|
|
|
9
|
-
const customMonthsView = document.createElement('div')
|
|
10
|
-
customMonthsView.classList.add('flatpickr-custom-months-view', 'hidden')
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const yearScrollToElement = 106
|
|
20
|
-
|
|
21
|
-
let currentYearEl = null
|
|
22
|
-
|
|
23
|
-
const changeActiveView = (view) => {
|
|
24
|
-
switch (view) {
|
|
25
|
-
case 'months':
|
|
26
|
-
customMonthsView.classList.remove('hidden')
|
|
27
|
-
customYearsView.classList.add('hidden')
|
|
28
|
-
break
|
|
29
|
-
case 'years':
|
|
30
|
-
customMonthsView.classList.add('hidden')
|
|
31
|
-
customYearsView.classList.remove('hidden')
|
|
32
|
-
currentYearEl.parentNode.scrollTop = yearElHeight * yearScrollToElement
|
|
33
|
-
break
|
|
34
|
-
default:
|
|
35
|
-
customMonthsView.classList.add('hidden')
|
|
36
|
-
customYearsView.classList.add('hidden')
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const selectMonth = (e) => {
|
|
41
|
-
fp.changeMonth(parseInt(e.target.dataset.month), false)
|
|
42
|
-
buildMonths()
|
|
43
|
-
buildYears()
|
|
44
|
-
changeActiveView()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const selectYear = (e) => {
|
|
48
|
-
fp.changeYear(parseInt(e.target.dataset.year), false)
|
|
49
|
-
buildMonths()
|
|
50
|
-
buildYears()
|
|
51
|
-
changeActiveView("months")
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const yearInRange = (year, selectedYears) => {
|
|
55
|
-
if (selectedYears[0] && selectedYears[1]) {
|
|
56
|
-
return selectedYears[0] <= year && year <= selectedYears[1]
|
|
57
|
-
}
|
|
58
|
-
return selectedYears[0] === year
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const monthInRange = (monthIndex, selectedMonths, selectedYears) => {
|
|
62
|
-
//range
|
|
63
|
-
if (selectedYears[0] && selectedYears[1]) {
|
|
64
|
-
if (selectedYears[0] === selectedYears[1]) {
|
|
65
|
-
if (selectedYears[0] === fp.currentYear) {
|
|
66
|
-
return selectedMonths[0] <= monthIndex && monthIndex <= selectedMonths[1]
|
|
67
|
-
}
|
|
68
|
-
return false
|
|
69
|
-
}
|
|
70
|
-
if (selectedYears[0] === fp.currentYear && monthIndex >= selectedMonths[0]) {
|
|
71
|
-
return true
|
|
72
|
-
}
|
|
73
|
-
if (selectedYears[0] < fp.currentYear && fp.currentYear < selectedYears[1]) {
|
|
74
|
-
return true
|
|
75
|
-
}
|
|
76
|
-
if (selectedYears[1] === fp.currentYear && monthIndex <= selectedMonths[1]) {
|
|
77
|
-
return true
|
|
78
|
-
}
|
|
79
|
-
return false
|
|
10
|
+
export default class Datepicker {
|
|
11
|
+
constructor(target) {
|
|
12
|
+
target = target || document
|
|
13
|
+
let documentLocale = document.documentElement.lang || 'default'
|
|
14
|
+
documentLocale = documentLocale.split('-')[0]
|
|
15
|
+
if (documentLocale === 'en') {
|
|
16
|
+
documentLocale = 'default'
|
|
80
17
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
18
|
+
flatpickr.localize(this.getLocale(documentLocale))
|
|
19
|
+
this.initWidgets(target)
|
|
20
|
+
if(target === document) {
|
|
21
|
+
document.addEventListener('formset:added', (e) => {
|
|
22
|
+
this.initWidgets(e.target)
|
|
23
|
+
})
|
|
87
24
|
}
|
|
88
|
-
|
|
89
|
-
return false
|
|
90
25
|
}
|
|
91
26
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
fp._bind(back, 'click', (e) => {
|
|
97
|
-
e.preventDefault()
|
|
98
|
-
e.stopPropagation()
|
|
99
|
-
changeActiveView(backToView)
|
|
100
|
-
})
|
|
101
|
-
return back
|
|
27
|
+
getLocale(locale) {
|
|
28
|
+
// eslint-disable-next-line no-undef
|
|
29
|
+
const l = require(`flatpickr/dist/l10n/${locale}.js`)
|
|
30
|
+
return l.default[locale]
|
|
102
31
|
}
|
|
103
32
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
yearEl.innerHTML = fp.currentYear
|
|
109
|
-
fp._bind(yearEl, 'click', () => {
|
|
110
|
-
changeActiveView('years')
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
const prevYear = monthsHeader.querySelector('.flatpickr-prev-month')
|
|
114
|
-
const nextYear = monthsHeader.querySelector('.flatpickr-next-month')
|
|
115
|
-
|
|
116
|
-
prevYear.replaceChildren(createIcon('Left-small'))
|
|
117
|
-
nextYear.replaceChildren(createIcon('Right-small'))
|
|
118
|
-
|
|
119
|
-
fp._bind(prevYear, 'click', (e) => {
|
|
120
|
-
e.preventDefault()
|
|
121
|
-
e.stopPropagation()
|
|
122
|
-
fp.changeYear(fp.currentYear - 1)
|
|
123
|
-
buildMonths()
|
|
124
|
-
buildYears()
|
|
125
|
-
})
|
|
126
|
-
fp._bind(nextYear, 'click', (e) => {
|
|
127
|
-
e.preventDefault()
|
|
128
|
-
e.stopPropagation()
|
|
129
|
-
fp.changeYear(fp.currentYear + 1)
|
|
130
|
-
buildMonths()
|
|
131
|
-
buildYears()
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const monthsContent = fp.innerContainer.cloneNode(true)
|
|
136
|
-
monthsContent.querySelector('.flatpickr-weekdays').remove()
|
|
137
|
-
const monthsContainer = monthsContent.querySelector('.dayContainer')
|
|
138
|
-
monthsContainer.innerHTML = ''
|
|
139
|
-
|
|
140
|
-
const selectedMonths = fp.selectedDates.map(date => {
|
|
141
|
-
return date.getMonth()
|
|
142
|
-
})
|
|
143
|
-
const selectedYears = fp.selectedDates.map(date => {
|
|
144
|
-
return date.getFullYear()
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
for (let i = 0; i < 12; i++) {
|
|
148
|
-
const month = document.createElement('span')
|
|
149
|
-
month.classList.add('flatpickr-day', 'flatpickr-month')
|
|
150
|
-
if (i === fp.now.getMonth() && fp.currentYear === fp.now.getFullYear()) {
|
|
151
|
-
month.classList.add('today')
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (monthInRange(i, selectedMonths, selectedYears)) {
|
|
155
|
-
month.classList.add('selected')
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
month.textContent = monthToStr(i, fp.shorthand, fp.l10n)
|
|
159
|
-
month.dataset.month = i.toString()
|
|
160
|
-
month.addEventListener("click", selectMonth)
|
|
161
|
-
monthsContainer.appendChild(month)
|
|
33
|
+
initFlatPickr(datePickerEl, options={}, optionsOverride={}) {
|
|
34
|
+
let sbadminDatepickerData = {}
|
|
35
|
+
if(datePickerEl.dataset.sbadminDatepicker) {
|
|
36
|
+
sbadminDatepickerData = JSON.parse(datePickerEl.dataset.sbadminDatepicker)
|
|
162
37
|
}
|
|
163
38
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const buildYears = () => {
|
|
170
|
-
customYearsView.innerHTML = ''
|
|
171
|
-
const yearsHeader = fp.monthNav.cloneNode(true)
|
|
172
|
-
const yearEl = yearsHeader.querySelector('.flatpickr-current-month')
|
|
173
|
-
yearEl.innerHTML = fp.currentYear
|
|
174
|
-
|
|
175
|
-
yearsHeader.querySelector('.flatpickr-prev-month').remove()
|
|
176
|
-
yearsHeader.querySelector('.flatpickr-next-month').remove()
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const yearsContent = fp.innerContainer.cloneNode(true)
|
|
180
|
-
yearsContent.querySelector('.flatpickr-weekdays').remove()
|
|
181
|
-
yearsContent.querySelector('.flatpickr-days').classList.add('h-full', '-mr-8')
|
|
182
|
-
|
|
183
|
-
const yearsContainer = yearsContent.querySelector('.dayContainer')
|
|
184
|
-
yearsContainer.classList.add('overflow-auto', 'custom-scrollbar')
|
|
185
|
-
yearsContainer.innerHTML = ''
|
|
186
|
-
|
|
187
|
-
const currentYear = fp.now.getFullYear()
|
|
188
|
-
const selectedYears = fp.selectedDates.map(date => {
|
|
189
|
-
return date.getFullYear()
|
|
190
|
-
})
|
|
39
|
+
flatpickr(datePickerEl, {
|
|
40
|
+
onReady: (selectedDates, dateStr, instance) => {
|
|
41
|
+
instance.nextMonthNav?.replaceChildren(createIcon('Right-small'))
|
|
42
|
+
instance.prevMonthNav?.replaceChildren(createIcon('Left-small'))
|
|
191
43
|
|
|
192
|
-
|
|
193
|
-
const year = document.createElement('span')
|
|
194
|
-
year.classList.add('flatpickr-day', 'flatpickr-year')
|
|
44
|
+
const isInTable = datePickerEl.closest('[data-filter-input-name]')
|
|
195
45
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
year.classList.add('selected')
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
year.textContent = i.toString()
|
|
206
|
-
year.dataset.year = i.toString()
|
|
207
|
-
year.addEventListener("click", selectYear)
|
|
208
|
-
yearsContainer.appendChild(year)
|
|
209
|
-
}
|
|
46
|
+
// real input element should be present only in filters
|
|
47
|
+
const realInput = document.getElementById(datePickerEl.dataset.sbadminDatepickerRealInputId)
|
|
48
|
+
const mainInput = realInput || datePickerEl
|
|
49
|
+
mainInput.addEventListener('clear', () => {
|
|
50
|
+
instance.clear()
|
|
51
|
+
})
|
|
210
52
|
|
|
211
|
-
customYearsView.append(yearsHeader)
|
|
212
|
-
customYearsView.append(yearsContent)
|
|
213
|
-
customYearsView.append(buildBackButton("months"))
|
|
214
|
-
}
|
|
215
53
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
currentMonth.textContent = `${monthToStr(fp.currentMonth, fp.shorthand, fp.l10n)} ${fp.currentYear}`
|
|
220
|
-
return currentMonth
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const build = () => {
|
|
224
|
-
fp.monthNav.parentNode.insertBefore(customViewsWrapper, fp.monthNav)
|
|
54
|
+
if(!isInTable){
|
|
55
|
+
this.createClear(instance)
|
|
56
|
+
}
|
|
225
57
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
58
|
+
if(isInTable && realInput) {
|
|
59
|
+
// set initial value from real input to flatpickr
|
|
60
|
+
realInput.addEventListener('SBTableFilterFormLoad', () => {
|
|
61
|
+
if(!datePickerEl.value) {
|
|
62
|
+
instance.setDate(realInput.value, false, instance.config.dateFormat)
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
if(realInput) {
|
|
68
|
+
// advanced filters
|
|
69
|
+
instance.setDate(realInput.value, false, instance.config.dateFormat)
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
onClose: function(selectedDates, dateStr, instance) {
|
|
73
|
+
// fix single day range
|
|
74
|
+
if(instance.config.mode === "range" && selectedDates.length === 1){
|
|
75
|
+
instance.setDate([selectedDates[0],selectedDates[0]], true)
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
onChange: function(selectedDates, dateStr) {
|
|
79
|
+
const realInput = document.getElementById(datePickerEl.dataset.sbadminDatepickerRealInputId)
|
|
80
|
+
if(realInput) {
|
|
81
|
+
realInput.value = dateStr
|
|
82
|
+
realInput.removeAttribute('data-label')
|
|
83
|
+
realInput.dispatchEvent(new Event('change'))
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
...options,
|
|
87
|
+
...sbadminDatepickerData.flatpickrOptions,
|
|
88
|
+
...optionsOverride
|
|
230
89
|
})
|
|
231
|
-
|
|
232
|
-
buildMonths()
|
|
233
|
-
buildYears()
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return {
|
|
237
|
-
onReady: build,
|
|
238
|
-
onChange: [
|
|
239
|
-
replaceOriginalMonths,
|
|
240
|
-
buildMonths,
|
|
241
|
-
buildYears,
|
|
242
|
-
],
|
|
243
|
-
onMonthChange: replaceOriginalMonths,
|
|
244
|
-
onYearChange: replaceOriginalMonths
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// eslint-disable-next-line no-unused-vars
|
|
249
|
-
const customActionsPlugin = (fp) => {
|
|
250
|
-
|
|
251
|
-
const dateFormat = 'd/m/Y'
|
|
252
|
-
const createRadioInput = (id, name, value, label, checked) => {
|
|
253
|
-
const inputWrapperEl = document.createElement('label')
|
|
254
|
-
inputWrapperEl.classList.add('relative', 'block', 'px-12', 'py-8')
|
|
255
|
-
inputWrapperEl.setAttribute('for', id)
|
|
256
|
-
const labelEl = document.createElement('label')
|
|
257
|
-
labelEl.innerText = label
|
|
258
|
-
labelEl.setAttribute('for', id)
|
|
259
|
-
const inputEl = document.createElement('input')
|
|
260
|
-
inputEl.id = id
|
|
261
|
-
inputEl.name = name
|
|
262
|
-
inputEl.value = value
|
|
263
|
-
inputEl.type = 'radio'
|
|
264
|
-
inputEl.classList.add('radio')
|
|
265
|
-
inputEl.checked = checked
|
|
266
|
-
inputWrapperEl.append(inputEl)
|
|
267
|
-
inputWrapperEl.append(labelEl)
|
|
268
|
-
return inputWrapperEl
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const dateTimeReviver = (key, value) => {
|
|
272
|
-
if (key === 'value') {
|
|
273
|
-
const newValue = []
|
|
274
|
-
value.forEach((val) => {
|
|
275
|
-
newValue.push(new Date(val))
|
|
276
|
-
})
|
|
277
|
-
return newValue
|
|
278
|
-
}
|
|
279
|
-
return value
|
|
280
90
|
}
|
|
281
91
|
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
const
|
|
92
|
+
initShortcutsDropdown(datePickerEl) {
|
|
93
|
+
const realInput = document.getElementById(datePickerEl.dataset.sbadminDatepickerRealInputId)
|
|
94
|
+
const baseId = realInput.id
|
|
95
|
+
const baseValue = realInput.value
|
|
285
96
|
const el = document.createElement('div')
|
|
286
|
-
const shortcuts = JSON.parse(
|
|
287
|
-
el.classList.add('flatpickr-shortcuts')
|
|
97
|
+
const shortcuts = JSON.parse(datePickerEl.dataset.sbadminDatepickerShortcuts)
|
|
98
|
+
el.classList.add('flatpickr-shortcuts', 'dropdown-menu')
|
|
288
99
|
el.addEventListener('change', (e) => {
|
|
289
|
-
|
|
290
|
-
|
|
100
|
+
realInput.value = e.target.value
|
|
101
|
+
datePickerEl.value = e.target.nextElementSibling.innerText
|
|
291
102
|
})
|
|
292
103
|
|
|
293
104
|
shortcuts.forEach((shortcut, idx) => {
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
if (fromDateFormatted === toDateFormatted) {
|
|
298
|
-
shortcutValueStr = fromDateFormatted
|
|
299
|
-
} else {
|
|
300
|
-
shortcutValueStr = fromDateFormatted + fp.config.locale.rangeSeparator + toDateFormatted
|
|
105
|
+
const checked = JSON.stringify(shortcut.value) === baseValue
|
|
106
|
+
if(checked) {
|
|
107
|
+
datePickerEl.value = shortcut.label
|
|
301
108
|
}
|
|
302
109
|
el.append(createRadioInput(
|
|
303
110
|
`${baseId}_range${idx}`,
|
|
304
111
|
`${baseId}_shortcut`,
|
|
305
|
-
|
|
112
|
+
JSON.stringify(shortcut.value),
|
|
306
113
|
shortcut.label,
|
|
307
|
-
|
|
114
|
+
checked,
|
|
115
|
+
idx
|
|
308
116
|
))
|
|
309
117
|
})
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
return {
|
|
315
|
-
onReady: createShortcuts,
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
export default class Datepicker {
|
|
321
|
-
constructor() {
|
|
322
|
-
let documentLocale = document.documentElement.lang || 'default'
|
|
323
|
-
if (documentLocale === 'en') {
|
|
324
|
-
documentLocale = 'default'
|
|
325
|
-
}
|
|
326
|
-
flatpickr.localize(this.getLocale(documentLocale))
|
|
327
|
-
this.initWidgets()
|
|
328
|
-
|
|
329
|
-
document.addEventListener('formset:added', () => {
|
|
330
|
-
this.initWidgets()
|
|
331
|
-
})
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
getLocale(locale) {
|
|
335
|
-
// eslint-disable-next-line no-undef
|
|
336
|
-
const l = require(`flatpickr/dist/l10n/${locale}.js`)
|
|
337
|
-
return l.default[locale]
|
|
118
|
+
datePickerEl.parentElement.append(el)
|
|
119
|
+
datePickerEl.readOnly = true
|
|
120
|
+
datePickerEl.dataset['bsToggle'] = "dropdown"
|
|
121
|
+
new window.bootstrap5.Dropdown(datePickerEl)
|
|
338
122
|
}
|
|
339
123
|
|
|
340
124
|
initWidgets(parentEl=null) {
|
|
341
125
|
const datePickerSelector = {
|
|
342
126
|
'.js-datepicker': {
|
|
343
|
-
dateFormat: "d.m.Y",
|
|
344
|
-
allowInput: true,
|
|
345
|
-
plugins: [
|
|
346
|
-
monthYearViewsPlugin,
|
|
347
|
-
]
|
|
348
|
-
},
|
|
349
|
-
'.js-datepicker-not-inline': {
|
|
350
|
-
mode: "range",
|
|
351
127
|
allowInput: true,
|
|
352
128
|
plugins: [
|
|
353
129
|
monthYearViewsPlugin,
|
|
354
|
-
]
|
|
130
|
+
],
|
|
355
131
|
},
|
|
356
132
|
'.js-datepicker-range': {
|
|
357
133
|
inline: true,
|
|
@@ -360,14 +136,14 @@ export default class Datepicker {
|
|
|
360
136
|
plugins: [
|
|
361
137
|
monthYearViewsPlugin,
|
|
362
138
|
customActionsPlugin
|
|
363
|
-
]
|
|
139
|
+
],
|
|
364
140
|
},
|
|
365
141
|
'.js-timepicker': {
|
|
366
142
|
enableTime: true,
|
|
367
143
|
noCalendar: true,
|
|
368
144
|
dateFormat: "H:i",
|
|
369
145
|
allowInput: true,
|
|
370
|
-
time_24hr: true
|
|
146
|
+
time_24hr: true,
|
|
371
147
|
},
|
|
372
148
|
'.js-datetimepicker': {
|
|
373
149
|
enableTime: true,
|
|
@@ -376,7 +152,7 @@ export default class Datepicker {
|
|
|
376
152
|
time_24hr: true,
|
|
377
153
|
plugins: [
|
|
378
154
|
monthYearViewsPlugin,
|
|
379
|
-
]
|
|
155
|
+
],
|
|
380
156
|
}
|
|
381
157
|
}
|
|
382
158
|
if(!parentEl) {
|
|
@@ -384,26 +160,11 @@ export default class Datepicker {
|
|
|
384
160
|
}
|
|
385
161
|
|
|
386
162
|
Object.keys(datePickerSelector).forEach(selector => {
|
|
387
|
-
parentEl.querySelectorAll(selector).forEach(datePickerEl => {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
sbadminDatepickerData = JSON.parse(datePickerEl.dataset.sbadminDatepicker)
|
|
163
|
+
parentEl.querySelectorAll(`${selector}:not([type="hidden"])`).forEach(datePickerEl => {
|
|
164
|
+
if(datePickerEl.closest('.djn-empty-form')){
|
|
165
|
+
return
|
|
391
166
|
}
|
|
392
|
-
|
|
393
|
-
onReady: (selectedDates, dateStr, instance) => {
|
|
394
|
-
const isInTable = datePickerEl.closest('[data-filter-input-name]')
|
|
395
|
-
if(!isInTable) {
|
|
396
|
-
this.createClear(instance)
|
|
397
|
-
}
|
|
398
|
-
instance.nextMonthNav?.replaceChildren(createIcon('Right-small'))
|
|
399
|
-
instance.prevMonthNav?.replaceChildren(createIcon('Left-small'))
|
|
400
|
-
datePickerEl.addEventListener('clear', () => {
|
|
401
|
-
instance.clear()
|
|
402
|
-
})
|
|
403
|
-
},
|
|
404
|
-
...datePickerSelector[selector],
|
|
405
|
-
...sbadminDatepickerData.flatpickrOptions
|
|
406
|
-
})
|
|
167
|
+
this.initFlatPickr(datePickerEl, datePickerSelector[selector])
|
|
407
168
|
})
|
|
408
169
|
})
|
|
409
170
|
}
|