overview-components 1.1.160 → 1.1.161
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.
- package/LICENSE +7 -0
- package/README.md +82 -0
- package/dist/icons.js +692 -0
- package/dist/index.js +19890 -7
- package/dist/shared/lit-icon.d.ts.map +1 -1
- package/package.json +58 -21
- package/dist/assets/generated/locales/de.js +0 -269
- package/dist/assets/generated/locales/de.js.map +0 -1
- package/dist/assets/generated/locales/en.js +0 -269
- package/dist/assets/generated/locales/en.js.map +0 -1
- package/dist/assets/generated/locales/fr.js +0 -269
- package/dist/assets/generated/locales/fr.js.map +0 -1
- package/dist/assets/generated/locales/hr.js +0 -269
- package/dist/assets/generated/locales/hr.js.map +0 -1
- package/dist/assets/generated/locales/it.js +0 -269
- package/dist/assets/generated/locales/it.js.map +0 -1
- package/dist/assets/generated/locales/pl.js +0 -269
- package/dist/assets/generated/locales/pl.js.map +0 -1
- package/dist/assets/generated/locales/ro.js +0 -269
- package/dist/assets/generated/locales/ro.js.map +0 -1
- package/dist/assets/generated/locales/sk.js +0 -269
- package/dist/assets/generated/locales/sk.js.map +0 -1
- package/dist/assets/generated/locales/sr.js +0 -269
- package/dist/assets/generated/locales/sr.js.map +0 -1
- package/dist/assets/icons/iconGlyphs.js +0 -691
- package/dist/assets/icons/iconGlyphs.js.map +0 -1
- package/dist/assets/illustration/aichatbot-illustration.js +0 -144
- package/dist/assets/illustration/aichatbot-illustration.js.map +0 -1
- package/dist/assets/illustration/delete-illustration.js +0 -88
- package/dist/assets/illustration/delete-illustration.js.map +0 -1
- package/dist/assets/illustration/no-content.js +0 -159
- package/dist/assets/illustration/no-content.js.map +0 -1
- package/dist/assets/illustration/no-preview.js +0 -125
- package/dist/assets/illustration/no-preview.js.map +0 -1
- package/dist/assets/illustration/not-found.js +0 -98
- package/dist/assets/illustration/not-found.js.map +0 -1
- package/dist/assets/illustration/settings-illustration.js +0 -168
- package/dist/assets/illustration/settings-illustration.js.map +0 -1
- package/dist/components/components-settings/attachments-tab-settings.js +0 -318
- package/dist/components/components-settings/attachments-tab-settings.js.map +0 -1
- package/dist/components/components-settings/data-grid-settings.js +0 -553
- package/dist/components/components-settings/data-grid-settings.js.map +0 -1
- package/dist/components/components-settings/section-tab-settings.js +0 -719
- package/dist/components/components-settings/section-tab-settings.js.map +0 -1
- package/dist/components/components-settings/tabs-overview-settings.js +0 -421
- package/dist/components/components-settings/tabs-overview-settings.js.map +0 -1
- package/dist/components/index.js +0 -30
- package/dist/components/index.js.map +0 -1
- package/dist/components/lit-ai-filter-assistant.js +0 -443
- package/dist/components/lit-ai-filter-assistant.js.map +0 -1
- package/dist/components/lit-attachments-tab.js +0 -2044
- package/dist/components/lit-attachments-tab.js.map +0 -1
- package/dist/components/lit-badge.js +0 -124
- package/dist/components/lit-badge.js.map +0 -1
- package/dist/components/lit-case-variables-tab.js +0 -3718
- package/dist/components/lit-case-variables-tab.js.map +0 -1
- package/dist/components/lit-chart.js +0 -727
- package/dist/components/lit-chart.js.map +0 -1
- package/dist/components/lit-data-grid-tanstack.js +0 -2550
- package/dist/components/lit-data-grid-tanstack.js.map +0 -1
- package/dist/components/lit-filter-builder.js +0 -701
- package/dist/components/lit-filter-builder.js.map +0 -1
- package/dist/components/lit-filter-modal.js +0 -349
- package/dist/components/lit-filter-modal.js.map +0 -1
- package/dist/components/lit-multiselect-item.js +0 -707
- package/dist/components/lit-multiselect-item.js.map +0 -1
- package/dist/components/lit-section-tab.js +0 -268
- package/dist/components/lit-section-tab.js.map +0 -1
- package/dist/components/lit-tabs-overview.js +0 -356
- package/dist/components/lit-tabs-overview.js.map +0 -1
- package/dist/components/modals/lit-confirm-modal.js +0 -121
- package/dist/components/modals/lit-confirm-modal.js.map +0 -1
- package/dist/components/modals/lit-delete-modal.js +0 -131
- package/dist/components/modals/lit-delete-modal.js.map +0 -1
- package/dist/components/react-wrappers/ai-filter-assistant.js +0 -9
- package/dist/components/react-wrappers/ai-filter-assistant.js.map +0 -1
- package/dist/components/react-wrappers/attachments-tab.js +0 -9
- package/dist/components/react-wrappers/attachments-tab.js.map +0 -1
- package/dist/components/react-wrappers/badge.js +0 -9
- package/dist/components/react-wrappers/badge.js.map +0 -1
- package/dist/components/react-wrappers/button.js +0 -9
- package/dist/components/react-wrappers/button.js.map +0 -1
- package/dist/components/react-wrappers/calendar.js +0 -9
- package/dist/components/react-wrappers/calendar.js.map +0 -1
- package/dist/components/react-wrappers/case-variables-tab.js +0 -9
- package/dist/components/react-wrappers/case-variables-tab.js.map +0 -1
- package/dist/components/react-wrappers/chart.js +0 -9
- package/dist/components/react-wrappers/chart.js.map +0 -1
- package/dist/components/react-wrappers/data-grid-tanstack.js +0 -9
- package/dist/components/react-wrappers/data-grid-tanstack.js.map +0 -1
- package/dist/components/react-wrappers/filter-builder.js +0 -12
- package/dist/components/react-wrappers/filter-builder.js.map +0 -1
- package/dist/components/react-wrappers/filter-modal.js +0 -9
- package/dist/components/react-wrappers/filter-modal.js.map +0 -1
- package/dist/components/react-wrappers/index.js +0 -27
- package/dist/components/react-wrappers/index.js.map +0 -1
- package/dist/components/react-wrappers/progress-bar.js +0 -9
- package/dist/components/react-wrappers/progress-bar.js.map +0 -1
- package/dist/components/react-wrappers/section-tab.js +0 -9
- package/dist/components/react-wrappers/section-tab.js.map +0 -1
- package/dist/components/react-wrappers/tabs-overview.js +0 -9
- package/dist/components/react-wrappers/tabs-overview.js.map +0 -1
- package/dist/data/translations.js +0 -2768
- package/dist/data/translations.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/schemas/index.js +0 -18
- package/dist/schemas/index.js.map +0 -1
- package/dist/schemas/lit-attachments-tab-document.schema.js +0 -39
- package/dist/schemas/lit-attachments-tab-document.schema.js.map +0 -1
- package/dist/schemas/lit-attachments-tab-settings-value.schema.js +0 -30
- package/dist/schemas/lit-attachments-tab-settings-value.schema.js.map +0 -1
- package/dist/schemas/lit-attachments-tab.schema.js +0 -68
- package/dist/schemas/lit-attachments-tab.schema.js.map +0 -1
- package/dist/schemas/lit-case-variables-tab-cell.schema.js +0 -225
- package/dist/schemas/lit-case-variables-tab-cell.schema.js.map +0 -1
- package/dist/schemas/lit-case-variables-tab-rows.schema.js +0 -6
- package/dist/schemas/lit-case-variables-tab-rows.schema.js.map +0 -1
- package/dist/schemas/lit-case-variables-tab.schema.js +0 -27
- package/dist/schemas/lit-case-variables-tab.schema.js.map +0 -1
- package/dist/schemas/lit-data-grid-tanstack-column-array.schema.js +0 -6
- package/dist/schemas/lit-data-grid-tanstack-column-array.schema.js.map +0 -1
- package/dist/schemas/lit-data-grid-tanstack-column-custom-filter-array.schema.js +0 -6
- package/dist/schemas/lit-data-grid-tanstack-column-custom-filter-array.schema.js.map +0 -1
- package/dist/schemas/lit-data-grid-tanstack-column-custom-filter.schema.js +0 -11
- package/dist/schemas/lit-data-grid-tanstack-column-custom-filter.schema.js.map +0 -1
- package/dist/schemas/lit-data-grid-tanstack-column.schema.js +0 -79
- package/dist/schemas/lit-data-grid-tanstack-column.schema.js.map +0 -1
- package/dist/schemas/lit-data-grid-tanstack.schema.js +0 -108
- package/dist/schemas/lit-data-grid-tanstack.schema.js.map +0 -1
- package/dist/schemas/lit-filter-builder.schema.js +0 -61
- package/dist/schemas/lit-filter-builder.schema.js.map +0 -1
- package/dist/schemas/lit-section-tab-schema.js +0 -37
- package/dist/schemas/lit-section-tab-schema.js.map +0 -1
- package/dist/schemas/lit-tabs-overview-tab-array.schema.js +0 -6
- package/dist/schemas/lit-tabs-overview-tab-array.schema.js.map +0 -1
- package/dist/schemas/lit-tabs-overview-tab.schema.js +0 -32
- package/dist/schemas/lit-tabs-overview-tab.schema.js.map +0 -1
- package/dist/schemas/lit-tabs-overview.schema.js +0 -29
- package/dist/schemas/lit-tabs-overview.schema.js.map +0 -1
- package/dist/scripts/translate-locales.js +0 -241
- package/dist/scripts/translate-locales.js.map +0 -1
- package/dist/shared/filter-inputs.js +0 -429
- package/dist/shared/filter-inputs.js.map +0 -1
- package/dist/shared/index.js +0 -40
- package/dist/shared/index.js.map +0 -1
- package/dist/shared/lit-button.js +0 -159
- package/dist/shared/lit-button.js.map +0 -1
- package/dist/shared/lit-calendar.js +0 -485
- package/dist/shared/lit-calendar.js.map +0 -1
- package/dist/shared/lit-case-variables-tab-cell.js +0 -226
- package/dist/shared/lit-case-variables-tab-cell.js.map +0 -1
- package/dist/shared/lit-checkbox.js +0 -184
- package/dist/shared/lit-checkbox.js.map +0 -1
- package/dist/shared/lit-custom-popper.js +0 -116
- package/dist/shared/lit-custom-popper.js.map +0 -1
- package/dist/shared/lit-data-grid-action-buttons-popover.js +0 -295
- package/dist/shared/lit-data-grid-action-buttons-popover.js.map +0 -1
- package/dist/shared/lit-data-grid-density-popover.js +0 -84
- package/dist/shared/lit-data-grid-density-popover.js.map +0 -1
- package/dist/shared/lit-data-grid-export-popover.js +0 -68
- package/dist/shared/lit-data-grid-export-popover.js.map +0 -1
- package/dist/shared/lit-data-grid-operators-popover.js +0 -114
- package/dist/shared/lit-data-grid-operators-popover.js.map +0 -1
- package/dist/shared/lit-data-grid-row-actions.js +0 -87
- package/dist/shared/lit-data-grid-row-actions.js.map +0 -1
- package/dist/shared/lit-date-picker.js +0 -608
- package/dist/shared/lit-date-picker.js.map +0 -1
- package/dist/shared/lit-document-thumbnail.js +0 -383
- package/dist/shared/lit-document-thumbnail.js.map +0 -1
- package/dist/shared/lit-filter-input.js +0 -115
- package/dist/shared/lit-filter-input.js.map +0 -1
- package/dist/shared/lit-icon-button.js +0 -165
- package/dist/shared/lit-icon-button.js.map +0 -1
- package/dist/shared/lit-icon.js +0 -337
- package/dist/shared/lit-icon.js.map +0 -1
- package/dist/shared/lit-input.js +0 -282
- package/dist/shared/lit-input.js.map +0 -1
- package/dist/shared/lit-label.js +0 -103
- package/dist/shared/lit-label.js.map +0 -1
- package/dist/shared/lit-loader.js +0 -68
- package/dist/shared/lit-loader.js.map +0 -1
- package/dist/shared/lit-loading-bar.js +0 -91
- package/dist/shared/lit-loading-bar.js.map +0 -1
- package/dist/shared/lit-menu-item.js +0 -98
- package/dist/shared/lit-menu-item.js.map +0 -1
- package/dist/shared/lit-menu.js +0 -29
- package/dist/shared/lit-menu.js.map +0 -1
- package/dist/shared/lit-modal-body.js +0 -24
- package/dist/shared/lit-modal-body.js.map +0 -1
- package/dist/shared/lit-modal-footer.js +0 -21
- package/dist/shared/lit-modal-footer.js.map +0 -1
- package/dist/shared/lit-modal-header.js +0 -34
- package/dist/shared/lit-modal-header.js.map +0 -1
- package/dist/shared/lit-modal.js +0 -168
- package/dist/shared/lit-modal.js.map +0 -1
- package/dist/shared/lit-overflow-tooltip.js +0 -114
- package/dist/shared/lit-overflow-tooltip.js.map +0 -1
- package/dist/shared/lit-pill.js +0 -87
- package/dist/shared/lit-pill.js.map +0 -1
- package/dist/shared/lit-progress-bar.js +0 -130
- package/dist/shared/lit-progress-bar.js.map +0 -1
- package/dist/shared/lit-responsive-button.js +0 -106
- package/dist/shared/lit-responsive-button.js.map +0 -1
- package/dist/shared/lit-select-field.js +0 -457
- package/dist/shared/lit-select-field.js.map +0 -1
- package/dist/shared/lit-select.js +0 -668
- package/dist/shared/lit-select.js.map +0 -1
- package/dist/shared/lit-settings.js +0 -76
- package/dist/shared/lit-settings.js.map +0 -1
- package/dist/shared/lit-text-field.js +0 -252
- package/dist/shared/lit-text-field.js.map +0 -1
- package/dist/shared/lit-toggle.js +0 -240
- package/dist/shared/lit-toggle.js.map +0 -1
- package/dist/shared/lit-tooltip.js +0 -165
- package/dist/shared/lit-tooltip.js.map +0 -1
- package/dist/shared/simple-popper.js +0 -285
- package/dist/shared/simple-popper.js.map +0 -1
- package/dist/shared/simple-tooltip.js +0 -249
- package/dist/shared/simple-tooltip.js.map +0 -1
- package/dist/shared/styles/button-shared-styles.js +0 -494
- package/dist/shared/styles/button-shared-styles.js.map +0 -1
- package/dist/styles.js +0 -169
- package/dist/styles.js.map +0 -1
- package/dist/utils/custom-filters.js +0 -42
- package/dist/utils/custom-filters.js.map +0 -1
- package/dist/utils/date.js +0 -21
- package/dist/utils/date.js.map +0 -1
- package/dist/utils/file-type-utils.js +0 -55
- package/dist/utils/file-type-utils.js.map +0 -1
- package/dist/utils/formatNumber.js +0 -62
- package/dist/utils/formatNumber.js.map +0 -1
- package/dist/utils/getOperatorByType.js +0 -70
- package/dist/utils/getOperatorByType.js.map +0 -1
- package/dist/utils/getOverviewValue.js +0 -175
- package/dist/utils/getOverviewValue.js.map +0 -1
- package/dist/utils/localization.js +0 -433
- package/dist/utils/localization.js.map +0 -1
- package/dist/utils/pdf-thumbnail-generator.js +0 -91
- package/dist/utils/pdf-thumbnail-generator.js.map +0 -1
- package/dist/utils/utils.js +0 -94
- package/dist/utils/utils.js.map +0 -1
- package/dist/vite.svg +0 -1
|
@@ -1,3718 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { LitElement, html, css } from 'lit';
|
|
8
|
-
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
9
|
-
import { styleMap } from 'lit/directives/style-map.js';
|
|
10
|
-
import { property, state } from 'lit/decorators.js';
|
|
11
|
-
import Sortable from 'sortablejs';
|
|
12
|
-
import { repeat } from 'lit/directives/repeat.js';
|
|
13
|
-
import { Pane } from 'tweakpane';
|
|
14
|
-
// components
|
|
15
|
-
import '../shared/lit-icon.js';
|
|
16
|
-
import '../shared/lit-button.js';
|
|
17
|
-
import '../shared/lit-menu.js';
|
|
18
|
-
import '../shared/lit-menu-item.js';
|
|
19
|
-
import '../shared/lit-checkbox.js';
|
|
20
|
-
import '../shared/lit-input.js';
|
|
21
|
-
import '../shared/simple-popper.js';
|
|
22
|
-
import '../assets/illustration/not-found.js';
|
|
23
|
-
import { tooltip } from '../shared/simple-tooltip.js';
|
|
24
|
-
import '../shared/lit-tooltip.js';
|
|
25
|
-
import '../shared/lit-progress-bar.js';
|
|
26
|
-
import '../shared/lit-modal.js';
|
|
27
|
-
import '../shared/lit-modal-header.js';
|
|
28
|
-
import '../shared/lit-modal-body.js';
|
|
29
|
-
import '../shared/lit-modal-footer.js';
|
|
30
|
-
import '../shared/lit-select-field.js';
|
|
31
|
-
import '../shared/lit-select.js';
|
|
32
|
-
import '../shared/lit-label.js';
|
|
33
|
-
import '../shared/lit-icon-button.js';
|
|
34
|
-
import '../shared/lit-toggle.js';
|
|
35
|
-
import '../shared/lit-text-field.js';
|
|
36
|
-
import './lit-tabs-overview.js';
|
|
37
|
-
// utils
|
|
38
|
-
import { formatDate } from '../utils/date.js';
|
|
39
|
-
import { formatCurrency, formatDecimal } from '../utils/formatNumber.js';
|
|
40
|
-
import { setLocale, getLocale, LOCALE_LANGS } from '../utils/localization.js';
|
|
41
|
-
import { msg } from '@lit/localize';
|
|
42
|
-
import { isEqual } from 'lodash';
|
|
43
|
-
import { getOperatorsByColumnType, getDefaultOperator, } from '../utils/getOperatorByType.js';
|
|
44
|
-
export class LitCaseVariablesTab extends LitElement {
|
|
45
|
-
constructor() {
|
|
46
|
-
super(...arguments);
|
|
47
|
-
this.rows = [];
|
|
48
|
-
this.variables = [];
|
|
49
|
-
this.hideTabWhen = false;
|
|
50
|
-
this.userLang = 'cs';
|
|
51
|
-
this.allowedLang = ['cs'];
|
|
52
|
-
this.dateFormat = null;
|
|
53
|
-
this.isLoading = false;
|
|
54
|
-
this.enableSettings = false;
|
|
55
|
-
this.gridVariables = false;
|
|
56
|
-
this.onSettingsChanged = (rows) => { };
|
|
57
|
-
this.hostURL = '';
|
|
58
|
-
this.currentBreakpoint = this.getBreakpoint();
|
|
59
|
-
this.isOpen = false;
|
|
60
|
-
this.filterText = '';
|
|
61
|
-
this.isMobile = window.innerWidth <= 600;
|
|
62
|
-
this.expertModeModalOpen = false;
|
|
63
|
-
this.expertModeCell = null;
|
|
64
|
-
this.expertModeConfig = {
|
|
65
|
-
enabled: false,
|
|
66
|
-
leftType: 'column',
|
|
67
|
-
leftSource: '',
|
|
68
|
-
leftValue: '',
|
|
69
|
-
leftAggregation: 'sum',
|
|
70
|
-
operation: 'none',
|
|
71
|
-
rightType: 'variable',
|
|
72
|
-
rightSource: '',
|
|
73
|
-
rightValue: '',
|
|
74
|
-
rightAggregation: 'sum',
|
|
75
|
-
headerName: '',
|
|
76
|
-
headerNameMutations: {},
|
|
77
|
-
pmEnabled: false,
|
|
78
|
-
pmLeftType: 'column',
|
|
79
|
-
pmLeftSource: '',
|
|
80
|
-
pmLeftValue: '',
|
|
81
|
-
pmLeftAggregation: 'sum',
|
|
82
|
-
pmOperation: 'none',
|
|
83
|
-
pmRightType: 'variable',
|
|
84
|
-
pmRightSource: '',
|
|
85
|
-
pmRightValue: '',
|
|
86
|
-
pmRightAggregation: 'sum',
|
|
87
|
-
};
|
|
88
|
-
this._resolvedExpertValues = new Map();
|
|
89
|
-
this._resizeListener = this.handleResize.bind(this);
|
|
90
|
-
this.sortableInstances = [];
|
|
91
|
-
this.settingsPanes = new Map();
|
|
92
|
-
this.operatorInputs = new Map(); // Track conditional formatting operator inputs
|
|
93
|
-
this.conditionValueInputs = new Map(); // Track conditional formatting value inputs
|
|
94
|
-
this.hideOperatorInputs = new Map(); // Track hide condition operator inputs
|
|
95
|
-
this.hideValueInputs = new Map(); // Track hide condition value inputs
|
|
96
|
-
this.sortableGroupId = `group-${Math.random().toString(36).substring(2, 9)}`;
|
|
97
|
-
this.activeSettingsCell = null;
|
|
98
|
-
this.settingsPopperOpen = false;
|
|
99
|
-
this.conditionSubFolders = new Map();
|
|
100
|
-
this.language = 'cs';
|
|
101
|
-
this.BREAKPOINTS = ['xs', 'sm', 'md', 'lg', 'xl'];
|
|
102
|
-
this.closeSettingsPopper = () => {
|
|
103
|
-
// Clean up any existing tweakpanes before closing
|
|
104
|
-
this.destroySettingsPanes();
|
|
105
|
-
this.settingsPopperOpen = false;
|
|
106
|
-
this.activeSettingsCell = null;
|
|
107
|
-
};
|
|
108
|
-
this.handleSettingsChanged = (newRows) => {
|
|
109
|
-
this.onSettingsChanged?.(newRows);
|
|
110
|
-
};
|
|
111
|
-
this.addCustomEmptyCell = () => {
|
|
112
|
-
// Generate a unique field name for the custom cell
|
|
113
|
-
const customCellCount = this.rows.filter((cell) => cell.field.startsWith('custom_cell_')).length;
|
|
114
|
-
const fieldName = `custom_cell_${customCellCount + 1}`;
|
|
115
|
-
// Create a new empty custom cell (without tooltip, headerName, or value)
|
|
116
|
-
const newCell = {
|
|
117
|
-
field: fieldName,
|
|
118
|
-
type: 'string',
|
|
119
|
-
size: { xs: 4, sm: 2, md: 1, lg: 1, xl: 1 },
|
|
120
|
-
};
|
|
121
|
-
const newRows = [...this.rows, newCell];
|
|
122
|
-
this.rows = newRows;
|
|
123
|
-
this.handleSettingsChanged(newRows);
|
|
124
|
-
// Automatically open settings for the new cell to allow user to customize it
|
|
125
|
-
setTimeout(() => {
|
|
126
|
-
this.toggleSettingsPane(newCell);
|
|
127
|
-
}, 100);
|
|
128
|
-
};
|
|
129
|
-
this.getHeaderActions = (cell) => {
|
|
130
|
-
return html `<div class="header-buttons">
|
|
131
|
-
${this.enableSettings
|
|
132
|
-
? html `
|
|
133
|
-
<div style="position: relative;">
|
|
134
|
-
<lit-icon
|
|
135
|
-
icon="cog"
|
|
136
|
-
size="1rem"
|
|
137
|
-
style="cursor: pointer"
|
|
138
|
-
@click=${() => this.toggleSettingsPane(cell)}
|
|
139
|
-
id="settings-trigger-${cell.field}"
|
|
140
|
-
></lit-icon>
|
|
141
|
-
|
|
142
|
-
${this.activeSettingsCell?.field === cell.field
|
|
143
|
-
? html `
|
|
144
|
-
<simple-popper
|
|
145
|
-
.showing=${this.settingsPopperOpen}
|
|
146
|
-
.placement=${'bottom'}
|
|
147
|
-
.manualOpening=${true}
|
|
148
|
-
.maxWidthAsTarget=${false}
|
|
149
|
-
.onClose=${this.closeSettingsPopper}
|
|
150
|
-
>
|
|
151
|
-
${this.renderSettingsContent()}
|
|
152
|
-
</simple-popper>
|
|
153
|
-
`
|
|
154
|
-
: ''}
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
|
-
<div class="drag-handle">
|
|
158
|
-
<lit-icon icon="hamburger" size="1rem"></lit-icon>
|
|
159
|
-
</div>
|
|
160
|
-
`
|
|
161
|
-
: null}
|
|
162
|
-
</div>`;
|
|
163
|
-
};
|
|
164
|
-
this.getHeaderLabel = (cell) => {
|
|
165
|
-
const tooltipText = cell?.[`tooltip_${(this.userLang)}`] || cell?.tooltip;
|
|
166
|
-
return html ` <div
|
|
167
|
-
style="${cell?.headerStyle ? styleMap(cell?.headerStyle) : ''}"
|
|
168
|
-
class="process-data-heading"
|
|
169
|
-
>
|
|
170
|
-
${cell?.[`headerName_${(this.userLang)}`] ||
|
|
171
|
-
cell?.headerName ||
|
|
172
|
-
''}
|
|
173
|
-
${tooltipText
|
|
174
|
-
? html `
|
|
175
|
-
<lit-icon
|
|
176
|
-
${tooltip(tooltipText, 'right', 100)}
|
|
177
|
-
size="12px"
|
|
178
|
-
icon="informative"
|
|
179
|
-
></lit-icon>
|
|
180
|
-
`
|
|
181
|
-
: ''}
|
|
182
|
-
</div>`;
|
|
183
|
-
};
|
|
184
|
-
this.getHeader = (cell) => {
|
|
185
|
-
return html ` <div class="header-cell">
|
|
186
|
-
${this.getHeaderLabel(cell)} ${this.getHeaderActions(cell)}
|
|
187
|
-
</div>`;
|
|
188
|
-
};
|
|
189
|
-
this.handleButtonClick = (cell) => {
|
|
190
|
-
// First try the original buttonFn if it exists and is a function
|
|
191
|
-
if (cell.buttonFn && typeof cell.buttonFn === 'function') {
|
|
192
|
-
cell.buttonFn();
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
// Otherwise use the href functionality like links
|
|
196
|
-
const url = this.getLinkUrl(cell);
|
|
197
|
-
if (url) {
|
|
198
|
-
window.open(url, '_blank');
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
this.getCellButton = (cell) => {
|
|
202
|
-
return html `
|
|
203
|
-
<div style="display: flex; justify-content: space-between">
|
|
204
|
-
<lit-button
|
|
205
|
-
style="flex-grow: 1; margin-right: 0.5rem"
|
|
206
|
-
.fullWidth="${cell.buttonFullWidth}"
|
|
207
|
-
variant="${cell.buttonVariant || 'contained'}"
|
|
208
|
-
color="${cell.buttonColor || 'primary'}"
|
|
209
|
-
label="${cell?.headerName}"
|
|
210
|
-
@click=${() => this.handleButtonClick(cell)}
|
|
211
|
-
></lit-button>
|
|
212
|
-
${this.getHeaderActions(cell)}
|
|
213
|
-
</div>
|
|
214
|
-
`;
|
|
215
|
-
};
|
|
216
|
-
this.getCellLink = (cell) => {
|
|
217
|
-
const linkUrl = this.getLinkUrl(cell);
|
|
218
|
-
const displayText = cell?.value || linkUrl || '';
|
|
219
|
-
return html `<div>${this.getHeader(cell)}</div>
|
|
220
|
-
<a class="link" href=${linkUrl} target="_blank">${displayText} </a> `;
|
|
221
|
-
};
|
|
222
|
-
this.getCellValue = (cell) => {
|
|
223
|
-
const langValue = cell?.[`value_${(this.userLang)}`];
|
|
224
|
-
const rawValue = (langValue !== null && langValue !== undefined && langValue !== '') ? langValue : (cell?.value ?? '');
|
|
225
|
-
const value = this.formatDisplayValue(rawValue);
|
|
226
|
-
return html `<div>${this.getHeader(cell)}</div>
|
|
227
|
-
<div
|
|
228
|
-
style="${styleMap(this.computeValueStyles(cell))}"
|
|
229
|
-
class="process-data-value"
|
|
230
|
-
>
|
|
231
|
-
${unsafeHTML(value)}
|
|
232
|
-
</div> `;
|
|
233
|
-
};
|
|
234
|
-
this.getCellDate = (cell) => {
|
|
235
|
-
return html `<div>${this.getHeader(cell)}</div>
|
|
236
|
-
<div
|
|
237
|
-
style="${styleMap(this.computeValueStyles(cell))}"
|
|
238
|
-
class="process-data-value"
|
|
239
|
-
>
|
|
240
|
-
${cell?.value
|
|
241
|
-
? formatDate(cell.value, this.getLocaleLang(), !!this.dateFormat, this.dateFormat)
|
|
242
|
-
: ''}
|
|
243
|
-
</div> `;
|
|
244
|
-
};
|
|
245
|
-
this.getCellCurrency = (cell) => {
|
|
246
|
-
const resolvedCurrency = this.resolveCurrencyType(cell);
|
|
247
|
-
return html `<div>${this.getHeader(cell)}</div>
|
|
248
|
-
<div
|
|
249
|
-
style="${styleMap(this.computeValueStyles(cell))}"
|
|
250
|
-
class="process-data-value"
|
|
251
|
-
>
|
|
252
|
-
${cell?.value != null
|
|
253
|
-
? formatCurrency(cell.value, {
|
|
254
|
-
locale: this.getLocaleLang(),
|
|
255
|
-
currency: resolvedCurrency,
|
|
256
|
-
numberOfDecimal: typeof cell.numberOfDecimal === 'number' ? cell.numberOfDecimal : 2,
|
|
257
|
-
})
|
|
258
|
-
: ''}
|
|
259
|
-
</div> `;
|
|
260
|
-
};
|
|
261
|
-
this.getCellNumber = (cell) => {
|
|
262
|
-
return html `<div>${this.getHeader(cell)}</div>
|
|
263
|
-
<div
|
|
264
|
-
style="${styleMap(this.computeValueStyles(cell))}"
|
|
265
|
-
class="process-data-value"
|
|
266
|
-
>
|
|
267
|
-
${cell?.value != null
|
|
268
|
-
? formatDecimal(cell.value, {
|
|
269
|
-
locale: this.getLocaleLang(),
|
|
270
|
-
numberOfDecimal: typeof cell.numberOfDecimal === 'number'
|
|
271
|
-
? cell.numberOfDecimal
|
|
272
|
-
: undefined,
|
|
273
|
-
})
|
|
274
|
-
: ''}
|
|
275
|
-
</div> `;
|
|
276
|
-
};
|
|
277
|
-
this.getCellProgress = (cell) => {
|
|
278
|
-
const numericValue = this.parseProgressValue(cell?.value);
|
|
279
|
-
const progressMax = this.resolveProgressMax(cell);
|
|
280
|
-
const percentage = progressMax > 0 ? (numericValue / progressMax) * 100 : 0;
|
|
281
|
-
const progressColor = this.computeProgressColor(cell);
|
|
282
|
-
return html `<div>${this.getHeader(cell)}</div>
|
|
283
|
-
<div
|
|
284
|
-
style="${styleMap(this.computeValueStyles(cell))}"
|
|
285
|
-
class="process-data-value"
|
|
286
|
-
>
|
|
287
|
-
<lit-progress-bar
|
|
288
|
-
.progress="${percentage}"
|
|
289
|
-
.color="${progressColor}"
|
|
290
|
-
label=""
|
|
291
|
-
style="width: 100%;"
|
|
292
|
-
></lit-progress-bar>
|
|
293
|
-
</div> `;
|
|
294
|
-
};
|
|
295
|
-
this.getCellCheckbox = (cell) => {
|
|
296
|
-
const checked = this.parseBooleanValue(cell?.value);
|
|
297
|
-
return html `<div>${this.getHeader(cell)}</div>
|
|
298
|
-
<div class="process-data-value">
|
|
299
|
-
<lit-checkbox
|
|
300
|
-
.checked=${checked}
|
|
301
|
-
.disabled=${true}
|
|
302
|
-
></lit-checkbox>
|
|
303
|
-
</div> `;
|
|
304
|
-
};
|
|
305
|
-
this.getInlineCellValue = (cell) => {
|
|
306
|
-
const langVal = cell?.[`value_${(this.userLang)}`];
|
|
307
|
-
let rawValue = (langVal !== null && langVal !== undefined && langVal !== '') ? langVal : (cell?.value ?? '');
|
|
308
|
-
let value = this.formatDisplayValue(rawValue);
|
|
309
|
-
// Format value based on cell.type
|
|
310
|
-
switch (cell.type) {
|
|
311
|
-
case 'currency':
|
|
312
|
-
value = cell?.value != null
|
|
313
|
-
? formatCurrency(cell.value, {
|
|
314
|
-
locale: this.getLocaleLang(),
|
|
315
|
-
currency: this.resolveCurrencyType(cell),
|
|
316
|
-
numberOfDecimal: typeof cell.numberOfDecimal === 'number' ? cell.numberOfDecimal : 2,
|
|
317
|
-
})
|
|
318
|
-
: '';
|
|
319
|
-
break;
|
|
320
|
-
case 'number':
|
|
321
|
-
value = cell?.value != null
|
|
322
|
-
? formatDecimal(cell.value, {
|
|
323
|
-
locale: this.getLocaleLang(),
|
|
324
|
-
numberOfDecimal: typeof cell.numberOfDecimal === 'number'
|
|
325
|
-
? cell.numberOfDecimal
|
|
326
|
-
: undefined,
|
|
327
|
-
})
|
|
328
|
-
: '';
|
|
329
|
-
break;
|
|
330
|
-
case 'date':
|
|
331
|
-
value = cell?.value
|
|
332
|
-
? formatDate(cell.value, this.getLocaleLang(), !!this.dateFormat, this.dateFormat)
|
|
333
|
-
: '';
|
|
334
|
-
break;
|
|
335
|
-
case 'progress':
|
|
336
|
-
// For progress, show percentage value based on progressMax variable
|
|
337
|
-
const progressNumeric = this.parseProgressValue(cell?.value);
|
|
338
|
-
const progressMaxVal = this.resolveProgressMax(cell);
|
|
339
|
-
const progressPercent = progressMaxVal > 0 ? (progressNumeric / progressMaxVal) * 100 : 0;
|
|
340
|
-
value = `${parseFloat(progressPercent.toFixed(2))}%`;
|
|
341
|
-
break;
|
|
342
|
-
case 'checkbox':
|
|
343
|
-
value = this.parseBooleanValue(cell?.value) ? msg('Ano') : msg('Ne');
|
|
344
|
-
break;
|
|
345
|
-
default:
|
|
346
|
-
value = this.formatDisplayValue(rawValue);
|
|
347
|
-
}
|
|
348
|
-
return html `
|
|
349
|
-
<div style="display: flex;align-items: center; justify-content: end; gap: 0.5rem;">
|
|
350
|
-
<div
|
|
351
|
-
style="${styleMap({
|
|
352
|
-
...this.computeCellStyles(cell),
|
|
353
|
-
width: 'fit-content',
|
|
354
|
-
display: 'flex',
|
|
355
|
-
alignItems: 'center',
|
|
356
|
-
justifyContent: 'end',
|
|
357
|
-
gap: '0.5rem',
|
|
358
|
-
padding: '0.375rem',
|
|
359
|
-
})}"
|
|
360
|
-
>
|
|
361
|
-
<div
|
|
362
|
-
style="display: flex;align-items: center; justify-content: end; gap: 0.5rem; flex-direction: row"
|
|
363
|
-
>
|
|
364
|
-
<div>${this.getHeaderLabel(cell)}</div>
|
|
365
|
-
<div
|
|
366
|
-
style="${styleMap(this.computeValueStyles(cell))}"
|
|
367
|
-
class="process-data-value"
|
|
368
|
-
>
|
|
369
|
-
${value}
|
|
370
|
-
</div>
|
|
371
|
-
<div>${this.getHeaderActions(cell)}</div>
|
|
372
|
-
</div>
|
|
373
|
-
</div>
|
|
374
|
-
</div>
|
|
375
|
-
`;
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
normalizeConditions(formatting) {
|
|
379
|
-
if (!formatting)
|
|
380
|
-
return [];
|
|
381
|
-
// Backward compat: single object → wrap in array
|
|
382
|
-
const arr = Array.isArray(formatting) ? formatting : [formatting];
|
|
383
|
-
// Ensure every condition property has a concrete type (tweakpane throws
|
|
384
|
-
// "No matching controller" when a bound value is undefined/null/unsupported)
|
|
385
|
-
const defaults = {
|
|
386
|
-
enabled: true,
|
|
387
|
-
variable: '',
|
|
388
|
-
operator: '',
|
|
389
|
-
value: '',
|
|
390
|
-
cellVariant: 'default',
|
|
391
|
-
valueVariant: 'default',
|
|
392
|
-
progressColor: 'primary',
|
|
393
|
-
};
|
|
394
|
-
return arr.map((c) => ({
|
|
395
|
-
...defaults,
|
|
396
|
-
...c,
|
|
397
|
-
// Force value to string — it may arrive as number, array, object, null
|
|
398
|
-
value: c.value != null ? String(c.value) : '',
|
|
399
|
-
enabled: typeof c.enabled === 'boolean' ? c.enabled : true,
|
|
400
|
-
}));
|
|
401
|
-
}
|
|
402
|
-
createDefaultCondition(cell) {
|
|
403
|
-
return {
|
|
404
|
-
enabled: true,
|
|
405
|
-
variable: cell.field,
|
|
406
|
-
operator: this.getDefaultOperatorForCell(cell),
|
|
407
|
-
value: '',
|
|
408
|
-
cellVariant: 'default',
|
|
409
|
-
valueVariant: 'default',
|
|
410
|
-
progressColor: 'primary',
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
rebuildConditionFolders(parentFolder, config, cell) {
|
|
414
|
-
// Dispose old sub-folders for this cell
|
|
415
|
-
const key = cell.field;
|
|
416
|
-
const oldFolders = this.conditionSubFolders.get(key) || [];
|
|
417
|
-
for (const f of oldFolders) {
|
|
418
|
-
try {
|
|
419
|
-
f.dispose();
|
|
420
|
-
}
|
|
421
|
-
catch (_e) { /* already disposed */ }
|
|
422
|
-
}
|
|
423
|
-
this.conditionSubFolders.set(key, []);
|
|
424
|
-
// Clean up tracked inputs for this cell's conditions
|
|
425
|
-
for (const [k] of this.operatorInputs) {
|
|
426
|
-
if (k.startsWith(`${key}_condition_`)) {
|
|
427
|
-
this.operatorInputs.delete(k);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
for (const [k] of this.conditionValueInputs) {
|
|
431
|
-
if (k.startsWith(`${key}_condition_`)) {
|
|
432
|
-
this.conditionValueInputs.delete(k);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
const conditions = config.conditions;
|
|
436
|
-
const folders = [];
|
|
437
|
-
conditions.forEach((conditionObj, idx) => {
|
|
438
|
-
const subFolder = parentFolder.addFolder({
|
|
439
|
-
title: `${msg('Podmínka')} ${idx + 1}`,
|
|
440
|
-
expanded: idx === conditions.length - 1,
|
|
441
|
-
});
|
|
442
|
-
folders.push(subFolder);
|
|
443
|
-
this.buildSingleConditionFolder(subFolder, conditionObj, config, cell, idx);
|
|
444
|
-
// Delete condition button
|
|
445
|
-
const deleteBtn = subFolder.addButton({ title: msg('Smazat podmínku') });
|
|
446
|
-
deleteBtn.on('click', () => {
|
|
447
|
-
this.removeConditionFromCell(cell, idx);
|
|
448
|
-
config.conditions = this.normalizeConditions(this.rows.find((c) => c.field === cell.field)?.conditionalFormatting);
|
|
449
|
-
this.rebuildConditionFolders(parentFolder, config, cell);
|
|
450
|
-
});
|
|
451
|
-
});
|
|
452
|
-
this.conditionSubFolders.set(key, folders);
|
|
453
|
-
}
|
|
454
|
-
buildSingleConditionFolder(folder, conditionObj, _config, cell, conditionIndex) {
|
|
455
|
-
// Guard: ensure all bound properties have concrete types for tweakpane
|
|
456
|
-
if (typeof conditionObj.enabled !== 'boolean')
|
|
457
|
-
conditionObj.enabled = true;
|
|
458
|
-
if (typeof conditionObj.variable !== 'string')
|
|
459
|
-
conditionObj.variable = cell.field || '';
|
|
460
|
-
if (typeof conditionObj.operator !== 'string')
|
|
461
|
-
conditionObj.operator = '';
|
|
462
|
-
if (conditionObj.value == null || typeof conditionObj.value !== 'string')
|
|
463
|
-
conditionObj.value = conditionObj.value != null ? String(conditionObj.value) : '';
|
|
464
|
-
if (typeof conditionObj.cellVariant !== 'string')
|
|
465
|
-
conditionObj.cellVariant = 'default';
|
|
466
|
-
if (typeof conditionObj.valueVariant !== 'string')
|
|
467
|
-
conditionObj.valueVariant = 'default';
|
|
468
|
-
if (typeof conditionObj.progressColor !== 'string')
|
|
469
|
-
conditionObj.progressColor = 'primary';
|
|
470
|
-
// Enable toggle
|
|
471
|
-
const enabledInput = folder.addBinding(conditionObj, 'enabled', {
|
|
472
|
-
label: msg('Povolit'),
|
|
473
|
-
});
|
|
474
|
-
enabledInput.on('change', (ev) => {
|
|
475
|
-
this.setConditionalFormatting(cell, conditionIndex, 'enabled', ev.value);
|
|
476
|
-
});
|
|
477
|
-
// Variable selector
|
|
478
|
-
const variableOptions = this.getAllAvailableVariables();
|
|
479
|
-
if (variableOptions.length > 0) {
|
|
480
|
-
if (!conditionObj.variable) {
|
|
481
|
-
conditionObj.variable = cell.field;
|
|
482
|
-
this.setConditionalFormatting(cell, conditionIndex, 'variable', cell.field);
|
|
483
|
-
}
|
|
484
|
-
const variableInput = folder.addBinding(conditionObj, 'variable', {
|
|
485
|
-
view: 'list',
|
|
486
|
-
label: msg('Proměnná'),
|
|
487
|
-
options: variableOptions,
|
|
488
|
-
});
|
|
489
|
-
variableInput.on('change', (ev) => {
|
|
490
|
-
this.setConditionalFormatting(cell, conditionIndex, 'variable', ev.value);
|
|
491
|
-
this.updateConditionalFormattingOperators(folder, conditionObj, cell, conditionIndex, ev.value);
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
// Operator
|
|
495
|
-
const variableType = this.getVariableTypeByField(conditionObj.variable);
|
|
496
|
-
const tempCell = { ...cell, field: conditionObj.variable, type: variableType };
|
|
497
|
-
const operatorOptions = this.getOperatorOptionsForCell(tempCell);
|
|
498
|
-
const operatorInput = folder.addBinding(conditionObj, 'operator', {
|
|
499
|
-
view: 'list',
|
|
500
|
-
label: msg('Operátor'),
|
|
501
|
-
options: operatorOptions,
|
|
502
|
-
});
|
|
503
|
-
operatorInput.on('change', (ev) => {
|
|
504
|
-
this.setConditionalFormatting(cell, conditionIndex, 'operator', ev.value);
|
|
505
|
-
});
|
|
506
|
-
const operatorKey = `${cell.field}_condition_${conditionIndex}_operator`;
|
|
507
|
-
this.operatorInputs.set(operatorKey, operatorInput);
|
|
508
|
-
// Value input
|
|
509
|
-
this.addConditionalFormattingValueInput(folder, conditionObj, cell, conditionIndex, conditionObj.variable);
|
|
510
|
-
// Cell Variant
|
|
511
|
-
const cellVariantOptions = [
|
|
512
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
513
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
514
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
515
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
516
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
517
|
-
{ text: msg('Informace'), value: 'info' },
|
|
518
|
-
];
|
|
519
|
-
const cellVariantInput = folder.addBinding(conditionObj, 'cellVariant', {
|
|
520
|
-
view: 'list',
|
|
521
|
-
label: msg('Styl buňky'),
|
|
522
|
-
options: cellVariantOptions,
|
|
523
|
-
});
|
|
524
|
-
cellVariantInput.on('change', (ev) => {
|
|
525
|
-
this.setConditionalFormatting(cell, conditionIndex, 'cellVariant', ev.value);
|
|
526
|
-
});
|
|
527
|
-
this.colorizeVariantSelect(cellVariantInput, cellVariantOptions, conditionObj, 'cellVariant');
|
|
528
|
-
// Value Variant
|
|
529
|
-
const valueVariantOptions = [
|
|
530
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
531
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
532
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
533
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
534
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
535
|
-
{ text: msg('Informace'), value: 'info' },
|
|
536
|
-
];
|
|
537
|
-
const valueVariantInput = folder.addBinding(conditionObj, 'valueVariant', {
|
|
538
|
-
view: 'list',
|
|
539
|
-
label: msg('Barva hodnoty'),
|
|
540
|
-
options: valueVariantOptions,
|
|
541
|
-
});
|
|
542
|
-
valueVariantInput.on('change', (ev) => {
|
|
543
|
-
this.setConditionalFormatting(cell, conditionIndex, 'valueVariant', ev.value);
|
|
544
|
-
});
|
|
545
|
-
this.colorizeVariantSelect(valueVariantInput, valueVariantOptions, conditionObj, 'valueVariant');
|
|
546
|
-
// Progress Color (only for progress type)
|
|
547
|
-
if (cell.type === 'progress') {
|
|
548
|
-
const progressColorOptions = [
|
|
549
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
550
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
551
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
552
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
553
|
-
{ text: msg('Informace'), value: 'info' },
|
|
554
|
-
];
|
|
555
|
-
const progressColorInput = folder.addBinding(conditionObj, 'progressColor', {
|
|
556
|
-
view: 'list',
|
|
557
|
-
label: msg('Barva Progressu'),
|
|
558
|
-
options: progressColorOptions,
|
|
559
|
-
});
|
|
560
|
-
progressColorInput.on('change', (ev) => {
|
|
561
|
-
this.setConditionalFormatting(cell, conditionIndex, 'progressColor', ev.value);
|
|
562
|
-
});
|
|
563
|
-
this.colorizeVariantSelect(progressColorInput, progressColorOptions, conditionObj, 'progressColor');
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
createCellSettingsConfig(cell) {
|
|
567
|
-
// If cell type is 'select' or 'multiselect', set cellType to 'string' for settings display
|
|
568
|
-
let cellType = cell.type || 'string';
|
|
569
|
-
if (cellType === 'select' || cellType === 'multiselect') {
|
|
570
|
-
cellType = 'string';
|
|
571
|
-
}
|
|
572
|
-
return {
|
|
573
|
-
size: cell.size?.lg ?? 1,
|
|
574
|
-
mobileSize: cell.size?.xs ?? 4,
|
|
575
|
-
cellVariant: cell.cellVariant || 'default',
|
|
576
|
-
cellCustomStyles: cell.cellCustomStyles || false,
|
|
577
|
-
valueVariant: cell.valueVariant || 'default',
|
|
578
|
-
valueCustomStyles: cell.valueCustomStyles || false,
|
|
579
|
-
fontWeight: cell.valueStyle?.fontWeight === 'bold',
|
|
580
|
-
cellType,
|
|
581
|
-
// Cell content properties
|
|
582
|
-
headerName: cell.headerName || '',
|
|
583
|
-
cellValue: cell.value || '',
|
|
584
|
-
// Cell type specific properties
|
|
585
|
-
href: cell.href || '',
|
|
586
|
-
linkType: cell.linkType || 'custom',
|
|
587
|
-
dynamicLink: cell.dynamicLink || '',
|
|
588
|
-
numberOfDecimal: cell.numberOfDecimal ?? 2,
|
|
589
|
-
progressColor: cell.progressColor || 'primary',
|
|
590
|
-
progressMax: cell.progressMax ?? 100,
|
|
591
|
-
buttonVariant: cell.buttonVariant || 'contained',
|
|
592
|
-
buttonColor: cell.buttonColor || 'primary',
|
|
593
|
-
buttonFullWidth: cell.buttonFullWidth ?? false,
|
|
594
|
-
currencyType: cell.currencyType || 'CZK',
|
|
595
|
-
customCSS: JSON.stringify(cell.cellStyle || {}),
|
|
596
|
-
// Conditional formatting - array of conditions (backward compat: wrap single object)
|
|
597
|
-
conditions: this.normalizeConditions(cell.conditionalFormatting),
|
|
598
|
-
// Conditional hide cell settings
|
|
599
|
-
hideConditionEnabled: !!cell.hideCondition?.enabled,
|
|
600
|
-
hideConditionVariable: cell.hideCondition?.variable ?? '',
|
|
601
|
-
hideConditionOperator: cell.hideCondition?.operator ?? '',
|
|
602
|
-
hideConditionValue: cell.hideCondition?.value ?? '',
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
getOperatorOptionsForCell(cell) {
|
|
606
|
-
// Map Cell type to FieldType for operators
|
|
607
|
-
let variableType = 'string'; // default type
|
|
608
|
-
if (cell.type) {
|
|
609
|
-
switch (cell.type) {
|
|
610
|
-
case 'select':
|
|
611
|
-
case 'checkbox':
|
|
612
|
-
variableType = 'select';
|
|
613
|
-
break;
|
|
614
|
-
case 'multiselect':
|
|
615
|
-
variableType = 'multiselect';
|
|
616
|
-
break;
|
|
617
|
-
case 'number':
|
|
618
|
-
case 'currency':
|
|
619
|
-
case 'progress':
|
|
620
|
-
variableType = 'number';
|
|
621
|
-
break;
|
|
622
|
-
case 'date':
|
|
623
|
-
variableType = 'date';
|
|
624
|
-
break;
|
|
625
|
-
case 'string':
|
|
626
|
-
case 'button':
|
|
627
|
-
case 'link':
|
|
628
|
-
default:
|
|
629
|
-
variableType = 'string';
|
|
630
|
-
break;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
return getOperatorsByColumnType(variableType).map((op) => ({
|
|
634
|
-
text: op.label,
|
|
635
|
-
value: op.value,
|
|
636
|
-
}));
|
|
637
|
-
}
|
|
638
|
-
getDefaultOperatorForCell(cell) {
|
|
639
|
-
let variableType = 'string'; // default type
|
|
640
|
-
// Map Cell type to FieldType for operators
|
|
641
|
-
if (cell.type) {
|
|
642
|
-
switch (cell.type) {
|
|
643
|
-
case 'select':
|
|
644
|
-
case 'checkbox':
|
|
645
|
-
variableType = 'select';
|
|
646
|
-
break;
|
|
647
|
-
case 'multiselect':
|
|
648
|
-
variableType = 'multiselect';
|
|
649
|
-
break;
|
|
650
|
-
case 'number':
|
|
651
|
-
case 'currency':
|
|
652
|
-
case 'progress':
|
|
653
|
-
variableType = 'number';
|
|
654
|
-
break;
|
|
655
|
-
case 'date':
|
|
656
|
-
variableType = 'date';
|
|
657
|
-
break;
|
|
658
|
-
case 'string':
|
|
659
|
-
case 'button':
|
|
660
|
-
case 'link':
|
|
661
|
-
default:
|
|
662
|
-
variableType = 'string';
|
|
663
|
-
break;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
return getDefaultOperator(variableType);
|
|
667
|
-
}
|
|
668
|
-
getVariableTypeByField(fieldName) {
|
|
669
|
-
// First check variables array
|
|
670
|
-
const cellInVariables = this.variables.find((variable) => variable.field === fieldName);
|
|
671
|
-
if (cellInVariables?.type) {
|
|
672
|
-
return cellInVariables.type;
|
|
673
|
-
}
|
|
674
|
-
// Then check in rows array
|
|
675
|
-
const cellInRows = this.rows.find((cell) => cell.field === fieldName);
|
|
676
|
-
if (cellInRows?.type) {
|
|
677
|
-
return cellInRows.type;
|
|
678
|
-
}
|
|
679
|
-
// Default to string if not found
|
|
680
|
-
return 'string';
|
|
681
|
-
}
|
|
682
|
-
getValueOptionsByField(fieldName) {
|
|
683
|
-
// Firs check in variables array
|
|
684
|
-
const cellInVariables = this.variables.find((variable) => variable.field === fieldName);
|
|
685
|
-
if (cellInVariables?.valueOptions) {
|
|
686
|
-
return cellInVariables.valueOptions;
|
|
687
|
-
}
|
|
688
|
-
// Than check in rows
|
|
689
|
-
const cellInRows = this.rows.find((cell) => cell.field === fieldName);
|
|
690
|
-
if (cellInRows?.valueOptions) {
|
|
691
|
-
return cellInRows.valueOptions;
|
|
692
|
-
}
|
|
693
|
-
return undefined;
|
|
694
|
-
}
|
|
695
|
-
updateConditionalFormattingOperators(folder, conditionObj, cell, conditionIndex, variableName) {
|
|
696
|
-
const variableType = this.getVariableTypeByField(variableName);
|
|
697
|
-
const tempCell = { ...cell, field: variableName, type: variableType };
|
|
698
|
-
const newOperatorOptions = this.getOperatorOptionsForCell(tempCell);
|
|
699
|
-
const operatorKey = `${cell.field}_condition_${conditionIndex}_operator`;
|
|
700
|
-
const existingOperatorInput = this.operatorInputs.get(operatorKey);
|
|
701
|
-
let insertIndex = -1;
|
|
702
|
-
if (existingOperatorInput) {
|
|
703
|
-
try {
|
|
704
|
-
insertIndex = folder.children.indexOf(existingOperatorInput);
|
|
705
|
-
existingOperatorInput.dispose();
|
|
706
|
-
this.operatorInputs.delete(operatorKey);
|
|
707
|
-
}
|
|
708
|
-
catch (error) {
|
|
709
|
-
console.warn('Could not dispose existing operator binding:', error);
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
const defaultOperator = this.getDefaultOperatorForCell(tempCell);
|
|
713
|
-
conditionObj.operator = defaultOperator;
|
|
714
|
-
this.setConditionalFormatting(cell, conditionIndex, 'operator', defaultOperator);
|
|
715
|
-
const operatorInput = folder.addBinding(conditionObj, 'operator', {
|
|
716
|
-
view: 'list',
|
|
717
|
-
label: msg('Operátor'),
|
|
718
|
-
options: newOperatorOptions,
|
|
719
|
-
index: insertIndex >= 0 ? insertIndex : undefined,
|
|
720
|
-
});
|
|
721
|
-
operatorInput.on('change', (ev) => {
|
|
722
|
-
this.setConditionalFormatting(cell, conditionIndex, 'operator', ev.value);
|
|
723
|
-
});
|
|
724
|
-
this.operatorInputs.set(operatorKey, operatorInput);
|
|
725
|
-
this.addConditionalFormattingValueInput(folder, conditionObj, cell, conditionIndex, variableName);
|
|
726
|
-
}
|
|
727
|
-
updateHideConditionOperators(folder, config, cell, variableName) {
|
|
728
|
-
// Get the type of the selected variable to ensure correct operators
|
|
729
|
-
const variableType = this.getVariableTypeByField(variableName);
|
|
730
|
-
// Create a temporary cell object with the new variable and its type
|
|
731
|
-
const tempCell = { ...cell, field: variableName, type: variableType };
|
|
732
|
-
const newOperatorOptions = this.getOperatorOptionsForCell(tempCell);
|
|
733
|
-
// Find existing operator binding and its position
|
|
734
|
-
const operatorKey = `${cell.field}_hide_operator`;
|
|
735
|
-
const existingOperatorInput = this.hideOperatorInputs.get(operatorKey);
|
|
736
|
-
let insertIndex = -1;
|
|
737
|
-
if (existingOperatorInput) {
|
|
738
|
-
try {
|
|
739
|
-
// Find the index of the existing operator input
|
|
740
|
-
insertIndex = folder.children.indexOf(existingOperatorInput);
|
|
741
|
-
existingOperatorInput.dispose();
|
|
742
|
-
this.hideOperatorInputs.delete(operatorKey);
|
|
743
|
-
}
|
|
744
|
-
catch (error) {
|
|
745
|
-
console.warn('Could not dispose existing hide operator binding:', error);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
// Reset operator to default for new variable type
|
|
749
|
-
const defaultOperator = this.getDefaultOperatorForCell(tempCell);
|
|
750
|
-
config.hideConditionOperator = defaultOperator;
|
|
751
|
-
this.setHideCondition(cell, 'operator', defaultOperator);
|
|
752
|
-
// Add new operator binding with updated options
|
|
753
|
-
const hideOperatorInput = folder.addBinding(config, 'hideConditionOperator', {
|
|
754
|
-
view: 'list',
|
|
755
|
-
label: msg('Operátor'),
|
|
756
|
-
options: newOperatorOptions,
|
|
757
|
-
index: insertIndex >= 0 ? insertIndex : undefined, // Insert at same position if possible
|
|
758
|
-
});
|
|
759
|
-
hideOperatorInput.on('change', (ev) => {
|
|
760
|
-
this.setHideCondition(cell, 'operator', ev.value);
|
|
761
|
-
});
|
|
762
|
-
// Store the new operator input for future disposal
|
|
763
|
-
this.hideOperatorInputs.set(operatorKey, hideOperatorInput);
|
|
764
|
-
// Update the value input to match the new variable type
|
|
765
|
-
this.addHideConditionValueInput(folder, config, cell, variableName);
|
|
766
|
-
}
|
|
767
|
-
addHideConditionValueInput(folder, config, cell, variableName) {
|
|
768
|
-
// Find and dispose existing value input if it exists
|
|
769
|
-
const valueKey = `${cell.field}_hide_value`;
|
|
770
|
-
const existingValueInput = this.hideValueInputs.get(valueKey);
|
|
771
|
-
let insertIndex = -1;
|
|
772
|
-
if (existingValueInput) {
|
|
773
|
-
try {
|
|
774
|
-
// Find the index of the existing value input
|
|
775
|
-
insertIndex = folder.children.indexOf(existingValueInput);
|
|
776
|
-
existingValueInput.dispose();
|
|
777
|
-
this.hideValueInputs.delete(valueKey);
|
|
778
|
-
}
|
|
779
|
-
catch (error) {
|
|
780
|
-
console.warn('Could not dispose existing hide value binding:', error);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
// Get the type and valueOptions of the selected variable
|
|
784
|
-
const variableType = this.getVariableTypeByField(variableName);
|
|
785
|
-
const valueOptions = this.getValueOptionsByField(variableName);
|
|
786
|
-
let hideValueInput;
|
|
787
|
-
// If variable is type 'select' or 'multiselect' and has valueOptions, create a dropdown
|
|
788
|
-
if ((variableType === 'select' || variableType === 'multiselect') &&
|
|
789
|
-
valueOptions &&
|
|
790
|
-
valueOptions.length > 0) {
|
|
791
|
-
// Convert valueOptions from {label, value} to {text, value} for Tweakpane
|
|
792
|
-
const tweakpaneOptions = valueOptions.map((opt) => ({
|
|
793
|
-
text: opt.label,
|
|
794
|
-
value: opt.value,
|
|
795
|
-
}));
|
|
796
|
-
hideValueInput = folder.addBinding(config, 'hideConditionValue', {
|
|
797
|
-
view: 'list',
|
|
798
|
-
label: msg('Hodnota'),
|
|
799
|
-
options: tweakpaneOptions,
|
|
800
|
-
index: insertIndex >= 0 ? insertIndex : undefined,
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
// Otherwise, create a text input
|
|
805
|
-
hideValueInput = folder.addBinding(config, 'hideConditionValue', {
|
|
806
|
-
label: msg('Hodnota'),
|
|
807
|
-
index: insertIndex >= 0 ? insertIndex : undefined,
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
hideValueInput.on('change', (ev) => {
|
|
811
|
-
this.setHideCondition(cell, 'value', ev.value);
|
|
812
|
-
});
|
|
813
|
-
// Store the new value input for future disposal
|
|
814
|
-
this.hideValueInputs.set(valueKey, hideValueInput);
|
|
815
|
-
}
|
|
816
|
-
addConditionalFormattingValueInput(folder, conditionObj, cell, conditionIndex, variableName) {
|
|
817
|
-
const valueKey = `${cell.field}_condition_${conditionIndex}_value`;
|
|
818
|
-
const existingValueInput = this.conditionValueInputs.get(valueKey);
|
|
819
|
-
let insertIndex = -1;
|
|
820
|
-
if (existingValueInput) {
|
|
821
|
-
try {
|
|
822
|
-
insertIndex = folder.children.indexOf(existingValueInput);
|
|
823
|
-
existingValueInput.dispose();
|
|
824
|
-
this.conditionValueInputs.delete(valueKey);
|
|
825
|
-
}
|
|
826
|
-
catch (error) {
|
|
827
|
-
console.warn('Could not dispose existing condition value binding:', error);
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
const variableType = this.getVariableTypeByField(variableName);
|
|
831
|
-
const valueOptions = this.getValueOptionsByField(variableName);
|
|
832
|
-
// Ensure value is a string before binding (tweakpane requires a concrete type)
|
|
833
|
-
if (conditionObj.value == null || typeof conditionObj.value !== 'string') {
|
|
834
|
-
conditionObj.value = conditionObj.value != null ? String(conditionObj.value) : '';
|
|
835
|
-
}
|
|
836
|
-
let conditionValueInput;
|
|
837
|
-
if ((variableType === 'select' || variableType === 'multiselect') &&
|
|
838
|
-
valueOptions &&
|
|
839
|
-
valueOptions.length > 0) {
|
|
840
|
-
const tweakpaneOptions = valueOptions.map((opt) => ({
|
|
841
|
-
text: opt.label,
|
|
842
|
-
value: opt.value,
|
|
843
|
-
}));
|
|
844
|
-
conditionValueInput = folder.addBinding(conditionObj, 'value', {
|
|
845
|
-
view: 'list',
|
|
846
|
-
label: msg('Hodnota'),
|
|
847
|
-
options: tweakpaneOptions,
|
|
848
|
-
index: insertIndex >= 0 ? insertIndex : undefined,
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
else {
|
|
852
|
-
conditionValueInput = folder.addBinding(conditionObj, 'value', {
|
|
853
|
-
label: msg('Hodnota'),
|
|
854
|
-
index: insertIndex >= 0 ? insertIndex : undefined,
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
conditionValueInput.on('change', (ev) => {
|
|
858
|
-
this.setConditionalFormatting(cell, conditionIndex, 'value', ev.value);
|
|
859
|
-
});
|
|
860
|
-
this.conditionValueInputs.set(valueKey, conditionValueInput);
|
|
861
|
-
}
|
|
862
|
-
getBreakpoint() {
|
|
863
|
-
const width = window.innerWidth;
|
|
864
|
-
if (width >= 1920)
|
|
865
|
-
return 'xl';
|
|
866
|
-
if (width >= 1280)
|
|
867
|
-
return 'lg';
|
|
868
|
-
if (width >= 960)
|
|
869
|
-
return 'md';
|
|
870
|
-
if (width >= 600)
|
|
871
|
-
return 'sm';
|
|
872
|
-
return 'xs';
|
|
873
|
-
}
|
|
874
|
-
// Function to handle resize events
|
|
875
|
-
handleResize() {
|
|
876
|
-
const newBreakpoint = this.getBreakpoint();
|
|
877
|
-
if (newBreakpoint !== this.currentBreakpoint) {
|
|
878
|
-
this.currentBreakpoint = newBreakpoint; // Update property
|
|
879
|
-
}
|
|
880
|
-
this.isMobile = window.innerWidth <= 600;
|
|
881
|
-
}
|
|
882
|
-
connectedCallback() {
|
|
883
|
-
super.connectedCallback();
|
|
884
|
-
window.addEventListener('resize', this._resizeListener); // Add listener
|
|
885
|
-
this.isMobile = window.innerWidth <= 600;
|
|
886
|
-
if (!this.dateFormat) {
|
|
887
|
-
const userSettings = localStorage.getItem('userSettings');
|
|
888
|
-
const storedFormat = userSettings
|
|
889
|
-
? JSON.parse(userSettings)?.state?.dateFormat
|
|
890
|
-
: undefined;
|
|
891
|
-
this.dateFormat = storedFormat;
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
disconnectedCallback() {
|
|
895
|
-
this.destroySortables();
|
|
896
|
-
this.destroySettingsPanes();
|
|
897
|
-
window.removeEventListener('resize', this._resizeListener); // Remove listener
|
|
898
|
-
super.disconnectedCallback();
|
|
899
|
-
}
|
|
900
|
-
firstUpdated() {
|
|
901
|
-
if (this.enableSettings) {
|
|
902
|
-
this.initSortable();
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
setFontWeight(cell) {
|
|
906
|
-
this.rows = this.rows.map((c) => {
|
|
907
|
-
if (c.field === cell.field) {
|
|
908
|
-
const isBold = c.valueStyle?.fontWeight === 'bold';
|
|
909
|
-
return {
|
|
910
|
-
...c,
|
|
911
|
-
valueCustomStyles: true,
|
|
912
|
-
valueVariant: 'default',
|
|
913
|
-
valueStyle: {
|
|
914
|
-
...(c.valueStyle || {}),
|
|
915
|
-
fontWeight: isBold ? '500' : 'bold',
|
|
916
|
-
},
|
|
917
|
-
};
|
|
918
|
-
}
|
|
919
|
-
return c;
|
|
920
|
-
});
|
|
921
|
-
this.handleSettingsChanged(this.rows);
|
|
922
|
-
}
|
|
923
|
-
getAllAvailableVariables() {
|
|
924
|
-
const variables = [];
|
|
925
|
-
// Add variables from current rows (including all cells)
|
|
926
|
-
this.rows.forEach((cell) => {
|
|
927
|
-
variables.push({
|
|
928
|
-
text: `${cell.headerName || cell.field} (${cell.field})`,
|
|
929
|
-
value: cell.field,
|
|
930
|
-
});
|
|
931
|
-
});
|
|
932
|
-
// Add variables from variables array (that are not in current rows)
|
|
933
|
-
const existingFields = this.rows.map((cell) => cell.field);
|
|
934
|
-
this.variables.forEach((variable) => {
|
|
935
|
-
if (!existingFields.includes(variable.field)) {
|
|
936
|
-
const name = variable.headerName || variable.field;
|
|
937
|
-
variables.push({
|
|
938
|
-
text: `${name} (${variable.field})`,
|
|
939
|
-
value: variable.field,
|
|
940
|
-
});
|
|
941
|
-
}
|
|
942
|
-
});
|
|
943
|
-
return variables.sort((a, b) => a.text.localeCompare(b.text));
|
|
944
|
-
}
|
|
945
|
-
setConditionalFormatting(cell, conditionIndex, property, value) {
|
|
946
|
-
this.rows = this.rows.map((c) => {
|
|
947
|
-
if (c.field === cell.field) {
|
|
948
|
-
const updatedCell = { ...c };
|
|
949
|
-
// Normalize to array
|
|
950
|
-
const conditions = this.normalizeConditions(updatedCell.conditionalFormatting).map((cond) => ({ ...cond }));
|
|
951
|
-
// Ensure index exists
|
|
952
|
-
if (!conditions[conditionIndex]) {
|
|
953
|
-
conditions[conditionIndex] = this.createDefaultCondition(cell);
|
|
954
|
-
}
|
|
955
|
-
conditions[conditionIndex][property] = value;
|
|
956
|
-
updatedCell.conditionalFormatting = conditions;
|
|
957
|
-
return updatedCell;
|
|
958
|
-
}
|
|
959
|
-
return c;
|
|
960
|
-
});
|
|
961
|
-
this.handleSettingsChanged(this.rows);
|
|
962
|
-
}
|
|
963
|
-
addConditionToCell(cell) {
|
|
964
|
-
this.rows = this.rows.map((c) => {
|
|
965
|
-
if (c.field === cell.field) {
|
|
966
|
-
const updatedCell = { ...c };
|
|
967
|
-
const conditions = this.normalizeConditions(updatedCell.conditionalFormatting).map((cond) => ({ ...cond }));
|
|
968
|
-
conditions.push(this.createDefaultCondition(cell));
|
|
969
|
-
updatedCell.conditionalFormatting = conditions;
|
|
970
|
-
return updatedCell;
|
|
971
|
-
}
|
|
972
|
-
return c;
|
|
973
|
-
});
|
|
974
|
-
this.handleSettingsChanged(this.rows);
|
|
975
|
-
}
|
|
976
|
-
removeConditionFromCell(cell, conditionIndex) {
|
|
977
|
-
this.rows = this.rows.map((c) => {
|
|
978
|
-
if (c.field === cell.field) {
|
|
979
|
-
const updatedCell = { ...c };
|
|
980
|
-
const conditions = this.normalizeConditions(updatedCell.conditionalFormatting).map((cond) => ({ ...cond }));
|
|
981
|
-
conditions.splice(conditionIndex, 1);
|
|
982
|
-
updatedCell.conditionalFormatting = conditions;
|
|
983
|
-
return updatedCell;
|
|
984
|
-
}
|
|
985
|
-
return c;
|
|
986
|
-
});
|
|
987
|
-
this.handleSettingsChanged(this.rows);
|
|
988
|
-
}
|
|
989
|
-
setCellStyle(style, cell) {
|
|
990
|
-
this.rows = this.rows.map((c) => {
|
|
991
|
-
if (c.field === cell.field) {
|
|
992
|
-
return { ...c, cellStyle: style };
|
|
993
|
-
}
|
|
994
|
-
return c;
|
|
995
|
-
});
|
|
996
|
-
this.handleSettingsChanged(this.rows);
|
|
997
|
-
}
|
|
998
|
-
setCellVariant(variant, cell) {
|
|
999
|
-
this.rows = this.rows.map((c) => {
|
|
1000
|
-
if (c.field === cell.field) {
|
|
1001
|
-
const updatedCell = { ...c, cellVariant: variant };
|
|
1002
|
-
// If setting a semantic variant, disable custom styles
|
|
1003
|
-
if (variant !== 'default') {
|
|
1004
|
-
updatedCell.cellCustomStyles = false;
|
|
1005
|
-
}
|
|
1006
|
-
return updatedCell;
|
|
1007
|
-
}
|
|
1008
|
-
return c;
|
|
1009
|
-
});
|
|
1010
|
-
this.handleSettingsChanged(this.rows);
|
|
1011
|
-
}
|
|
1012
|
-
setValueVariant(variant, cell) {
|
|
1013
|
-
this.rows = this.rows.map((c) => {
|
|
1014
|
-
if (c.field === cell.field) {
|
|
1015
|
-
const updatedCell = { ...c, valueVariant: variant };
|
|
1016
|
-
// If setting a semantic variant, disable custom styles
|
|
1017
|
-
if (variant !== 'default') {
|
|
1018
|
-
updatedCell.valueCustomStyles = false;
|
|
1019
|
-
}
|
|
1020
|
-
return updatedCell;
|
|
1021
|
-
}
|
|
1022
|
-
return c;
|
|
1023
|
-
});
|
|
1024
|
-
this.handleSettingsChanged(this.rows);
|
|
1025
|
-
}
|
|
1026
|
-
enableCellCustomStyles(cell) {
|
|
1027
|
-
this.rows = this.rows.map((c) => {
|
|
1028
|
-
if (c.field === cell.field) {
|
|
1029
|
-
return {
|
|
1030
|
-
...c,
|
|
1031
|
-
cellCustomStyles: true,
|
|
1032
|
-
cellVariant: 'default',
|
|
1033
|
-
};
|
|
1034
|
-
}
|
|
1035
|
-
return c;
|
|
1036
|
-
});
|
|
1037
|
-
this.handleSettingsChanged(this.rows);
|
|
1038
|
-
}
|
|
1039
|
-
enableValueCustomStyles(cell) {
|
|
1040
|
-
this.rows = this.rows.map((c) => {
|
|
1041
|
-
if (c.field === cell.field) {
|
|
1042
|
-
return {
|
|
1043
|
-
...c,
|
|
1044
|
-
valueCustomStyles: true,
|
|
1045
|
-
valueVariant: 'default',
|
|
1046
|
-
};
|
|
1047
|
-
}
|
|
1048
|
-
return c;
|
|
1049
|
-
});
|
|
1050
|
-
this.handleSettingsChanged(this.rows);
|
|
1051
|
-
}
|
|
1052
|
-
destroySortables() {
|
|
1053
|
-
this.sortableInstances.forEach((instance) => {
|
|
1054
|
-
instance.destroy();
|
|
1055
|
-
});
|
|
1056
|
-
this.sortableInstances = [];
|
|
1057
|
-
}
|
|
1058
|
-
destroySettingsPanes() {
|
|
1059
|
-
this.settingsPanes.forEach((pane, field) => {
|
|
1060
|
-
try {
|
|
1061
|
-
if (pane) {
|
|
1062
|
-
pane.dispose();
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
catch (error) {
|
|
1066
|
-
// Silently catch disposal errors (usually means already disposed)
|
|
1067
|
-
if (error.type !== 'alreadydisposed') {
|
|
1068
|
-
console.error(`Error disposing pane for ${field}:`, error);
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
});
|
|
1072
|
-
this.settingsPanes.clear();
|
|
1073
|
-
// Remove any floating tooltip containers (legacy cleanup)
|
|
1074
|
-
document.querySelectorAll('.tweakpane-floating-tooltip').forEach((el) => {
|
|
1075
|
-
el.remove();
|
|
1076
|
-
});
|
|
1077
|
-
// Clean up any leftover tweakpane containers in document
|
|
1078
|
-
document.querySelectorAll('[id^="tweakpane-"]').forEach((el) => {
|
|
1079
|
-
const parentContainer = el.closest('.tweakpane-container');
|
|
1080
|
-
if (parentContainer) {
|
|
1081
|
-
parentContainer.remove();
|
|
1082
|
-
}
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
|
-
toggleSettingsPane(cell) {
|
|
1086
|
-
// If clicking the same cell, toggle the popper
|
|
1087
|
-
if (this.activeSettingsCell?.field === cell.field) {
|
|
1088
|
-
this.settingsPopperOpen = !this.settingsPopperOpen;
|
|
1089
|
-
if (!this.settingsPopperOpen) {
|
|
1090
|
-
this.activeSettingsCell = null;
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
else {
|
|
1094
|
-
// Different cell, show popper for this cell
|
|
1095
|
-
this.activeSettingsCell = cell;
|
|
1096
|
-
this.settingsPopperOpen = true;
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
getVariantColor(variant) {
|
|
1100
|
-
const entry = LitCaseVariablesTab.VARIANT_CSS_VARS[variant];
|
|
1101
|
-
if (!entry)
|
|
1102
|
-
return '#9ca3af';
|
|
1103
|
-
const styles = getComputedStyle(this);
|
|
1104
|
-
return styles.getPropertyValue(entry.var).trim() || entry.fallback;
|
|
1105
|
-
}
|
|
1106
|
-
colorizeVariantSelect(binding, options, config, configKey) {
|
|
1107
|
-
const el = binding.element;
|
|
1108
|
-
if (!el)
|
|
1109
|
-
return;
|
|
1110
|
-
const selectEl = el.querySelector('select');
|
|
1111
|
-
if (!selectEl)
|
|
1112
|
-
return;
|
|
1113
|
-
// Hide the native select
|
|
1114
|
-
const valueContainer = el.querySelector('.tp-lblv_v');
|
|
1115
|
-
if (!valueContainer)
|
|
1116
|
-
return;
|
|
1117
|
-
selectEl.style.display = 'none';
|
|
1118
|
-
// Also hide the dropdown arrow
|
|
1119
|
-
const arrow = valueContainer.querySelector('.tp-lstv_m');
|
|
1120
|
-
if (arrow)
|
|
1121
|
-
arrow.style.display = 'none';
|
|
1122
|
-
// Create swatches container
|
|
1123
|
-
const swatchContainer = document.createElement('div');
|
|
1124
|
-
swatchContainer.style.cssText = 'display:flex;gap:4px;flex-wrap:wrap;align-items:center;';
|
|
1125
|
-
const borderVarMap = {
|
|
1126
|
-
default: 'var(--text-secondary, #9ca3af)',
|
|
1127
|
-
primary: 'var(--color-primary-main, #76b703)',
|
|
1128
|
-
secondary: 'var(--color-secondary-main, #6b7280)',
|
|
1129
|
-
success: 'var(--color-success-main, #22c55e)',
|
|
1130
|
-
warning: 'var(--color-warning-main, #f59e0b)',
|
|
1131
|
-
error: 'var(--color-error-main, #ef4444)',
|
|
1132
|
-
info: 'var(--color-info-main, #3b82f6)',
|
|
1133
|
-
custom: 'var(--color-primary-main, #8b5cf6)',
|
|
1134
|
-
ai: 'var(--color-primary-main, #a855f7)',
|
|
1135
|
-
};
|
|
1136
|
-
options.forEach((opt) => {
|
|
1137
|
-
const color = this.getVariantColor(opt.value);
|
|
1138
|
-
const borderColor = borderVarMap[opt.value] || 'var(--text-secondary, #9ca3af)';
|
|
1139
|
-
const isCustom = opt.value === 'custom';
|
|
1140
|
-
// Wrapper for positioning the tooltip
|
|
1141
|
-
const wrapper = document.createElement('div');
|
|
1142
|
-
wrapper.style.cssText = 'position:relative;display:inline-flex;';
|
|
1143
|
-
const swatch = document.createElement('div');
|
|
1144
|
-
swatch.dataset.value = opt.value;
|
|
1145
|
-
if (isCustom) {
|
|
1146
|
-
swatch.style.cssText = `
|
|
1147
|
-
width:16px;height:16px;border-radius:50%;cursor:pointer;
|
|
1148
|
-
background:conic-gradient(#ef4444,#f59e0b,#22c55e,#3b82f6,#8b5cf6,#ef4444);
|
|
1149
|
-
border:2px dashed var(--text-secondary, #9ca3af);transition:box-shadow .15s;flex-shrink:0;
|
|
1150
|
-
`;
|
|
1151
|
-
}
|
|
1152
|
-
else {
|
|
1153
|
-
swatch.style.cssText = `
|
|
1154
|
-
width:16px;height:16px;border-radius:50%;background:${color};cursor:pointer;
|
|
1155
|
-
border:2px solid ${borderColor};transition:box-shadow .15s;flex-shrink:0;
|
|
1156
|
-
`;
|
|
1157
|
-
}
|
|
1158
|
-
// Tooltip using SimpleTooltip component
|
|
1159
|
-
const tip = document.createElement('simple-tooltip');
|
|
1160
|
-
tip.textContent = opt.text;
|
|
1161
|
-
tip.placement = 'top';
|
|
1162
|
-
tip.offset = 6;
|
|
1163
|
-
tip.openDelayMs = 200;
|
|
1164
|
-
tip.target = swatch;
|
|
1165
|
-
wrapper.appendChild(tip);
|
|
1166
|
-
if (config[configKey] === opt.value) {
|
|
1167
|
-
swatch.style.boxShadow = `0 0 0 2px #fff, 0 0 0 4px ${borderColor}`;
|
|
1168
|
-
}
|
|
1169
|
-
swatch.addEventListener('click', () => {
|
|
1170
|
-
config[configKey] = opt.value;
|
|
1171
|
-
binding.refresh();
|
|
1172
|
-
swatchContainer.querySelectorAll('[data-value]').forEach((s) => {
|
|
1173
|
-
s.style.boxShadow = 'none';
|
|
1174
|
-
});
|
|
1175
|
-
swatch.style.boxShadow = `0 0 0 2px #fff, 0 0 0 4px ${borderColor}`;
|
|
1176
|
-
});
|
|
1177
|
-
wrapper.appendChild(swatch);
|
|
1178
|
-
swatchContainer.appendChild(wrapper);
|
|
1179
|
-
});
|
|
1180
|
-
valueContainer.appendChild(swatchContainer);
|
|
1181
|
-
}
|
|
1182
|
-
// Sanitize field name for use in CSS selectors
|
|
1183
|
-
sanitizeFieldName(field) {
|
|
1184
|
-
return field.replace(/[^a-zA-Z0-9-_]/g, '-');
|
|
1185
|
-
}
|
|
1186
|
-
renderSettingsContent() {
|
|
1187
|
-
if (!this.activeSettingsCell)
|
|
1188
|
-
return null;
|
|
1189
|
-
const cell = this.activeSettingsCell;
|
|
1190
|
-
return html `
|
|
1191
|
-
<div class="tweakpane-container" @click=${(e) => e.stopPropagation()}>
|
|
1192
|
-
<div id="tweakpane-${this.sanitizeFieldName(cell.field)}"></div>
|
|
1193
|
-
</div>
|
|
1194
|
-
`;
|
|
1195
|
-
}
|
|
1196
|
-
updated(changedProperties) {
|
|
1197
|
-
super.updated(changedProperties);
|
|
1198
|
-
if (changedProperties.has('userLang')) {
|
|
1199
|
-
const localeLang = this.getLocaleLang();
|
|
1200
|
-
if (getLocale() !== localeLang) {
|
|
1201
|
-
setLocale(localeLang).then(() => this.requestUpdate());
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
// Initialize tweakpane when activeSettingsCell changes and popper is open
|
|
1205
|
-
if (changedProperties.has('activeSettingsCell') ||
|
|
1206
|
-
changedProperties.has('settingsPopperOpen')) {
|
|
1207
|
-
if (this.activeSettingsCell && this.settingsPopperOpen) {
|
|
1208
|
-
// Use requestAnimationFrame + small delay to ensure DOM is ready (container is in shadowRoot)
|
|
1209
|
-
requestAnimationFrame(() => {
|
|
1210
|
-
this.initializeTweakpane(this.activeSettingsCell, 0);
|
|
1211
|
-
});
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
initializeTweakpaneWithRetry(cell, attempt = 1) {
|
|
1216
|
-
// Clean up any existing pane for this cell first
|
|
1217
|
-
const existingPane = this.settingsPanes.get(cell.field);
|
|
1218
|
-
if (existingPane) {
|
|
1219
|
-
try {
|
|
1220
|
-
existingPane.dispose();
|
|
1221
|
-
}
|
|
1222
|
-
catch (error) {
|
|
1223
|
-
// Silently catch disposal errors (usually means already disposed)
|
|
1224
|
-
if (error.type !== 'alreadydisposed') {
|
|
1225
|
-
console.error(`Error disposing existing pane for ${cell.field}:`, error);
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
this.settingsPanes.delete(cell.field);
|
|
1229
|
-
}
|
|
1230
|
-
// Increased retries and delay for slower PCs
|
|
1231
|
-
const maxAttempts = 20;
|
|
1232
|
-
const retryDelay = 100; // 100ms per retry = 2000ms total
|
|
1233
|
-
const selector = `#tweakpane-${this.sanitizeFieldName(cell.field)}`;
|
|
1234
|
-
const container = document.querySelector(selector) || this.shadowRoot?.querySelector(selector);
|
|
1235
|
-
if (container) {
|
|
1236
|
-
this.initializeTweakpane(cell, 0);
|
|
1237
|
-
}
|
|
1238
|
-
else if (attempt < maxAttempts) {
|
|
1239
|
-
setTimeout(() => {
|
|
1240
|
-
// Check if we're still supposed to be showing this cell
|
|
1241
|
-
if (this.activeSettingsCell?.field === cell.field && this.settingsPopperOpen) {
|
|
1242
|
-
this.initializeTweakpaneWithRetry(cell, attempt + 1);
|
|
1243
|
-
}
|
|
1244
|
-
}, retryDelay);
|
|
1245
|
-
}
|
|
1246
|
-
else {
|
|
1247
|
-
console.warn(`Failed to find tweakpane container for ${cell.field} after ${maxAttempts} attempts (${maxAttempts * retryDelay}ms)`);
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
initializeTweakpane(cell, retryCount = 0) {
|
|
1251
|
-
// Get the container from shadow DOM (always available in fixed overlay)
|
|
1252
|
-
const selector = `#tweakpane-${this.sanitizeFieldName(cell.field)}`;
|
|
1253
|
-
const container = document.querySelector(selector) || this.shadowRoot?.querySelector(selector);
|
|
1254
|
-
if (!container) {
|
|
1255
|
-
// Increased retries for slower PCs
|
|
1256
|
-
const maxRetries = 5;
|
|
1257
|
-
const retryDelay = 150;
|
|
1258
|
-
if (retryCount < maxRetries) {
|
|
1259
|
-
console.warn(`Tweakpane container not found, retrying... (${retryCount + 1}/${maxRetries})`);
|
|
1260
|
-
setTimeout(() => {
|
|
1261
|
-
this.initializeTweakpane(cell, retryCount + 1);
|
|
1262
|
-
}, retryDelay);
|
|
1263
|
-
return;
|
|
1264
|
-
}
|
|
1265
|
-
else {
|
|
1266
|
-
console.error(`Tweakpane container not found: #tweakpane-${this.sanitizeFieldName(cell.field)}`);
|
|
1267
|
-
return;
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
// Clear any existing pane for this cell
|
|
1271
|
-
const existingPane = this.settingsPanes.get(cell.field);
|
|
1272
|
-
if (existingPane) {
|
|
1273
|
-
try {
|
|
1274
|
-
existingPane.dispose();
|
|
1275
|
-
}
|
|
1276
|
-
catch (error) {
|
|
1277
|
-
// Silently catch disposal errors (usually means already disposed)
|
|
1278
|
-
if (error.type !== 'alreadydisposed') {
|
|
1279
|
-
console.error(`Error disposing existing pane for ${cell.field}:`, error);
|
|
1280
|
-
}
|
|
1281
|
-
}
|
|
1282
|
-
this.settingsPanes.delete(cell.field);
|
|
1283
|
-
}
|
|
1284
|
-
// Create Tweakpane in the container
|
|
1285
|
-
const pane = new Pane({
|
|
1286
|
-
container: container,
|
|
1287
|
-
title: `${cell.headerName || cell.field}`,
|
|
1288
|
-
});
|
|
1289
|
-
// Apply app theme CSS variables to Tweakpane
|
|
1290
|
-
const styles = getComputedStyle(this);
|
|
1291
|
-
const bgPaper = styles.getPropertyValue('--background-paper').trim() || '#fff';
|
|
1292
|
-
const bgDefault = styles.getPropertyValue('--background-default').trim() || '#fff';
|
|
1293
|
-
const textPrimary = styles.getPropertyValue('--text-primary').trim() || '#111827';
|
|
1294
|
-
const textSecondary = styles.getPropertyValue('--text-secondary').trim() || '#5d6371';
|
|
1295
|
-
const colorDivider = styles.getPropertyValue('--color-divider').trim() || '#e5e7eb';
|
|
1296
|
-
const containerEl = container;
|
|
1297
|
-
containerEl.style.setProperty('--tp-base-background-color', bgPaper);
|
|
1298
|
-
containerEl.style.setProperty('--tp-base-shadow-color', 'rgba(0,0,0,0)');
|
|
1299
|
-
containerEl.style.setProperty('--tp-button-background-color', bgDefault);
|
|
1300
|
-
containerEl.style.setProperty('--tp-button-foreground-color', textPrimary);
|
|
1301
|
-
containerEl.style.setProperty('--tp-container-background-color', colorDivider);
|
|
1302
|
-
containerEl.style.setProperty('--tp-container-background-color-hover', colorDivider);
|
|
1303
|
-
containerEl.style.setProperty('--tp-container-foreground-color', textPrimary);
|
|
1304
|
-
containerEl.style.setProperty('--tp-input-background-color', bgDefault);
|
|
1305
|
-
containerEl.style.setProperty('--tp-input-foreground-color', textPrimary);
|
|
1306
|
-
containerEl.style.setProperty('--tp-label-foreground-color', textSecondary);
|
|
1307
|
-
containerEl.style.setProperty('--tp-monitor-background-color', colorDivider);
|
|
1308
|
-
containerEl.style.setProperty('--tp-monitor-foreground-color', textSecondary);
|
|
1309
|
-
containerEl.style.setProperty('--tp-groove-foreground-color', colorDivider);
|
|
1310
|
-
const config = this.createCellSettingsConfig(cell);
|
|
1311
|
-
// Add size controls for desktop and mobile (only if not in grid variables mode)
|
|
1312
|
-
if (!this.gridVariables) {
|
|
1313
|
-
// Desktop size input
|
|
1314
|
-
const desktopSizeInput = pane.addBinding(config, 'size', {
|
|
1315
|
-
view: 'list',
|
|
1316
|
-
label: msg('Velikost desktop'),
|
|
1317
|
-
options: [
|
|
1318
|
-
{ text: msg('Skrytý'), value: 0 },
|
|
1319
|
-
{ text: msg('1 sloupec'), value: 1 },
|
|
1320
|
-
{ text: msg('2 sloupce'), value: 2 },
|
|
1321
|
-
{ text: msg('3 sloupce'), value: 3 },
|
|
1322
|
-
{ text: msg('4 sloupce'), value: 4 },
|
|
1323
|
-
],
|
|
1324
|
-
});
|
|
1325
|
-
desktopSizeInput.on('change', (ev) => {
|
|
1326
|
-
this.setCellSize(ev.value, cell, 'lg');
|
|
1327
|
-
});
|
|
1328
|
-
// Mobile size input
|
|
1329
|
-
const mobileSizeInput = pane.addBinding(config, 'mobileSize', {
|
|
1330
|
-
view: 'list',
|
|
1331
|
-
label: msg('Velikost mobil'),
|
|
1332
|
-
options: [
|
|
1333
|
-
{ text: msg('Skrytý'), value: 0 },
|
|
1334
|
-
{ text: msg('1 sloupec'), value: 1 },
|
|
1335
|
-
{ text: msg('2 sloupce'), value: 2 },
|
|
1336
|
-
{ text: msg('3 sloupce'), value: 3 },
|
|
1337
|
-
{ text: msg('4 sloupce'), value: 4 },
|
|
1338
|
-
],
|
|
1339
|
-
});
|
|
1340
|
-
mobileSizeInput.on('change', (ev) => {
|
|
1341
|
-
this.setCellSize(ev.value, cell, 'xs');
|
|
1342
|
-
});
|
|
1343
|
-
}
|
|
1344
|
-
// Add cell type control - at the top
|
|
1345
|
-
const cellTypeInput = pane.addBinding(config, 'cellType', {
|
|
1346
|
-
view: 'list',
|
|
1347
|
-
label: msg('Typ buňky'),
|
|
1348
|
-
options: [
|
|
1349
|
-
{ text: msg('Text'), value: 'string' },
|
|
1350
|
-
{ text: msg('Tlačítko'), value: 'button' },
|
|
1351
|
-
{ text: msg('Odkaz'), value: 'link' },
|
|
1352
|
-
{ text: msg('Datum'), value: 'date' },
|
|
1353
|
-
{ text: msg('Měna'), value: 'currency' },
|
|
1354
|
-
{ text: msg('Progress'), value: 'progress' },
|
|
1355
|
-
{ text: msg('Číslo'), value: 'number' },
|
|
1356
|
-
{ text: msg('Checkbox'), value: 'checkbox' },
|
|
1357
|
-
],
|
|
1358
|
-
});
|
|
1359
|
-
cellTypeInput.on('change', (ev) => {
|
|
1360
|
-
this.setCellType(cell, ev.value);
|
|
1361
|
-
});
|
|
1362
|
-
// Add header name and value controls (only for custom cells)
|
|
1363
|
-
const isCustomCell = cell.field.startsWith('custom_cell_');
|
|
1364
|
-
if (isCustomCell) {
|
|
1365
|
-
const headerNameInput = pane.addBinding(config, 'headerName', {
|
|
1366
|
-
label: msg('Název buňky'),
|
|
1367
|
-
});
|
|
1368
|
-
headerNameInput.on('change', (ev) => {
|
|
1369
|
-
this.setCellHeaderName(cell, ev.value);
|
|
1370
|
-
});
|
|
1371
|
-
// Add cell value control for custom cells
|
|
1372
|
-
const cellValueInput = pane.addBinding(config, 'cellValue', {
|
|
1373
|
-
label: msg('Hodnota buňky'),
|
|
1374
|
-
multiline: cell.type === 'string',
|
|
1375
|
-
});
|
|
1376
|
-
cellValueInput.on('change', (ev) => {
|
|
1377
|
-
this.setCellValue(cell, ev.value);
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
// Add cell variant control - common for all types
|
|
1381
|
-
const cellVariantOptions = [
|
|
1382
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
1383
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1384
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
1385
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1386
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1387
|
-
{ text: msg('Informace'), value: 'info' },
|
|
1388
|
-
{ text: msg('Vlastní'), value: 'custom' },
|
|
1389
|
-
];
|
|
1390
|
-
const cellVariantInput = pane.addBinding(config, 'cellVariant', {
|
|
1391
|
-
view: 'list',
|
|
1392
|
-
label: msg('Styl buňky'),
|
|
1393
|
-
options: cellVariantOptions,
|
|
1394
|
-
});
|
|
1395
|
-
// Add CSS input for custom styles (always present but controlled by visibility)
|
|
1396
|
-
const cssInput = pane.addBinding(config, 'customCSS', {
|
|
1397
|
-
label: msg('CSS buňky'),
|
|
1398
|
-
multiline: true,
|
|
1399
|
-
rows: 4,
|
|
1400
|
-
});
|
|
1401
|
-
cssInput.on('change', (ev) => {
|
|
1402
|
-
try {
|
|
1403
|
-
const cssObject = JSON.parse(ev.value || '{}');
|
|
1404
|
-
this.setCellStyle(cssObject, cell);
|
|
1405
|
-
}
|
|
1406
|
-
catch (error) {
|
|
1407
|
-
console.error('Invalid JSON for custom CSS:', error);
|
|
1408
|
-
}
|
|
1409
|
-
});
|
|
1410
|
-
const showCssInput = () => {
|
|
1411
|
-
if (cssInput.element) {
|
|
1412
|
-
cssInput.element.style.display = '';
|
|
1413
|
-
}
|
|
1414
|
-
};
|
|
1415
|
-
const hideCssInput = () => {
|
|
1416
|
-
if (cssInput.element) {
|
|
1417
|
-
cssInput.element.style.display = 'none';
|
|
1418
|
-
}
|
|
1419
|
-
};
|
|
1420
|
-
// Set initial visibility based on whether custom style is selected
|
|
1421
|
-
if (config.cellCustomStyles) {
|
|
1422
|
-
showCssInput();
|
|
1423
|
-
}
|
|
1424
|
-
else {
|
|
1425
|
-
hideCssInput();
|
|
1426
|
-
}
|
|
1427
|
-
cellVariantInput.on('change', (ev) => {
|
|
1428
|
-
if (ev.value === 'custom') {
|
|
1429
|
-
this.enableCellCustomStyles(cell);
|
|
1430
|
-
showCssInput();
|
|
1431
|
-
}
|
|
1432
|
-
else {
|
|
1433
|
-
this.setCellVariant(ev.value, cell);
|
|
1434
|
-
hideCssInput();
|
|
1435
|
-
}
|
|
1436
|
-
});
|
|
1437
|
-
this.colorizeVariantSelect(cellVariantInput, cellVariantOptions, config, 'cellVariant');
|
|
1438
|
-
// Add cell type-specific controls
|
|
1439
|
-
this.addCellTypeSpecificControls(pane, config, cell);
|
|
1440
|
-
// Add conditional formatting section
|
|
1441
|
-
const conditionFolder = pane.addFolder({
|
|
1442
|
-
title: msg('Podmíněné formátování buněk'),
|
|
1443
|
-
expanded: false,
|
|
1444
|
-
});
|
|
1445
|
-
// "Add Condition" button
|
|
1446
|
-
const addConditionBtn = conditionFolder.addButton({ title: `+ ${msg('Přidat podmínku')}` });
|
|
1447
|
-
addConditionBtn.on('click', () => {
|
|
1448
|
-
this.addConditionToCell(cell);
|
|
1449
|
-
// Rebuild conditions UI
|
|
1450
|
-
config.conditions = this.normalizeConditions(this.rows.find((c) => c.field === cell.field)?.conditionalFormatting);
|
|
1451
|
-
this.rebuildConditionFolders(conditionFolder, config, cell);
|
|
1452
|
-
});
|
|
1453
|
-
// Build initial condition sub-folders
|
|
1454
|
-
this.rebuildConditionFolders(conditionFolder, config, cell);
|
|
1455
|
-
// Add conditional hide section
|
|
1456
|
-
const hideFolder = pane.addFolder({
|
|
1457
|
-
title: msg('Podmíněné skrytí buněk'),
|
|
1458
|
-
expanded: false,
|
|
1459
|
-
});
|
|
1460
|
-
// Enable/disable conditional hide
|
|
1461
|
-
const hideConditionEnabledInput = hideFolder.addBinding(config, 'hideConditionEnabled', {
|
|
1462
|
-
label: msg('Povolit podmínky skrytí'),
|
|
1463
|
-
});
|
|
1464
|
-
hideConditionEnabledInput.on('change', (ev) => {
|
|
1465
|
-
this.setHideCondition(cell, 'enabled', ev.value);
|
|
1466
|
-
});
|
|
1467
|
-
// Variable selector for hide condition
|
|
1468
|
-
const hideVariableOptions = this.getAllAvailableVariables();
|
|
1469
|
-
if (hideVariableOptions.length > 0) {
|
|
1470
|
-
// Set default variable to current cell's field if not already set
|
|
1471
|
-
if (!config.hideConditionVariable) {
|
|
1472
|
-
config.hideConditionVariable = cell.field;
|
|
1473
|
-
this.setHideCondition(cell, 'variable', cell.field);
|
|
1474
|
-
}
|
|
1475
|
-
const hideConditionVariableInput = hideFolder.addBinding(config, 'hideConditionVariable', {
|
|
1476
|
-
view: 'list',
|
|
1477
|
-
label: msg('Proměnná'),
|
|
1478
|
-
options: hideVariableOptions,
|
|
1479
|
-
});
|
|
1480
|
-
hideConditionVariableInput.on('change', (ev) => {
|
|
1481
|
-
this.setHideCondition(cell, 'variable', ev.value);
|
|
1482
|
-
// Update operators when variable changes
|
|
1483
|
-
this.updateHideConditionOperators(hideFolder, config, cell, ev.value);
|
|
1484
|
-
});
|
|
1485
|
-
}
|
|
1486
|
-
// Hide condition operator - use operators based on cell type
|
|
1487
|
-
// Get the actual cell/variable to determine correct operators
|
|
1488
|
-
const hideVariableType = this.getVariableTypeByField(config.hideConditionVariable);
|
|
1489
|
-
const tempHideCell = {
|
|
1490
|
-
...cell,
|
|
1491
|
-
field: config.hideConditionVariable,
|
|
1492
|
-
type: hideVariableType,
|
|
1493
|
-
};
|
|
1494
|
-
const hideOperatorOptions = this.getOperatorOptionsForCell(tempHideCell);
|
|
1495
|
-
const hideOperatorInput = hideFolder.addBinding(config, 'hideConditionOperator', {
|
|
1496
|
-
view: 'list',
|
|
1497
|
-
label: msg('Operátor'),
|
|
1498
|
-
options: hideOperatorOptions,
|
|
1499
|
-
});
|
|
1500
|
-
hideOperatorInput.on('change', (ev) => {
|
|
1501
|
-
this.setHideCondition(cell, 'operator', ev.value);
|
|
1502
|
-
});
|
|
1503
|
-
// Store the operator input for future disposal
|
|
1504
|
-
const hideOperatorKey = `${cell.field}_hide_operator`;
|
|
1505
|
-
this.hideOperatorInputs.set(hideOperatorKey, hideOperatorInput);
|
|
1506
|
-
// Hide condition value - dynamic input based on variable type
|
|
1507
|
-
this.addHideConditionValueInput(hideFolder, config, cell, config.hideConditionVariable);
|
|
1508
|
-
// Expert mode button
|
|
1509
|
-
const expertBtn = pane.addButton({ title: msg('Expertní mód') });
|
|
1510
|
-
expertBtn.on('click', () => {
|
|
1511
|
-
this.openExpertModeModal(cell);
|
|
1512
|
-
});
|
|
1513
|
-
// Add delete button
|
|
1514
|
-
const deleteBtn = pane.addButton({ title: msg('Smazat buňku') });
|
|
1515
|
-
deleteBtn.on('click', () => {
|
|
1516
|
-
this.removeCellFromRows(cell.field);
|
|
1517
|
-
this.closeSettingsPopper();
|
|
1518
|
-
});
|
|
1519
|
-
this.settingsPanes.set(cell.field, pane);
|
|
1520
|
-
return pane;
|
|
1521
|
-
}
|
|
1522
|
-
addCellTypeSpecificControls(pane, config, cell) {
|
|
1523
|
-
const cellType = cell.type || 'string';
|
|
1524
|
-
// Create a tab for the current cell type only
|
|
1525
|
-
const tabTitle = this.getCellTypeTabTitle(cellType);
|
|
1526
|
-
if (tabTitle) {
|
|
1527
|
-
const tab = pane.addTab({
|
|
1528
|
-
pages: [{ title: tabTitle }],
|
|
1529
|
-
});
|
|
1530
|
-
const tabPage = tab.pages[0];
|
|
1531
|
-
// Add controls based on cell type
|
|
1532
|
-
switch (cellType) {
|
|
1533
|
-
case 'link':
|
|
1534
|
-
this.addLinkControls(tabPage, config, cell);
|
|
1535
|
-
break;
|
|
1536
|
-
case 'number':
|
|
1537
|
-
this.addNumberControls(tabPage, config, cell);
|
|
1538
|
-
break;
|
|
1539
|
-
case 'progress':
|
|
1540
|
-
this.addProgressControls(tabPage, config, cell);
|
|
1541
|
-
break;
|
|
1542
|
-
case 'button':
|
|
1543
|
-
this.addButtonControls(tabPage, config, cell);
|
|
1544
|
-
break;
|
|
1545
|
-
case 'currency':
|
|
1546
|
-
this.addCurrencyControls(tabPage, config, cell);
|
|
1547
|
-
break;
|
|
1548
|
-
case 'date':
|
|
1549
|
-
this.addDateControls(tabPage, config, cell);
|
|
1550
|
-
break;
|
|
1551
|
-
case 'checkbox':
|
|
1552
|
-
// Checkbox has no additional type-specific controls
|
|
1553
|
-
break;
|
|
1554
|
-
default:
|
|
1555
|
-
this.addStringControls(tabPage, config, cell);
|
|
1556
|
-
break;
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
getCellTypeTabTitle(cellType) {
|
|
1561
|
-
const typeTitles = {
|
|
1562
|
-
string: msg('Nastavení textu'),
|
|
1563
|
-
link: msg('Nastavení odkazu'),
|
|
1564
|
-
number: msg('Nastavení čísla'),
|
|
1565
|
-
button: msg('Nastavení tlačítka'),
|
|
1566
|
-
currency: msg('Nastavení měny'),
|
|
1567
|
-
date: msg('Nastavení data'),
|
|
1568
|
-
progress: msg('Nastavení postupu'),
|
|
1569
|
-
checkbox: msg('Nastavení checkboxu'),
|
|
1570
|
-
};
|
|
1571
|
-
return typeTitles[cellType] || msg('Nastavení buňky');
|
|
1572
|
-
}
|
|
1573
|
-
addStringControls(pane, config, cell) {
|
|
1574
|
-
// Value Bold
|
|
1575
|
-
const fontInput = pane.addBinding(config, 'fontWeight', {
|
|
1576
|
-
label: msg('Tučná hodnota'),
|
|
1577
|
-
});
|
|
1578
|
-
fontInput.on('change', () => {
|
|
1579
|
-
this.setFontWeight(cell);
|
|
1580
|
-
});
|
|
1581
|
-
// Value Variant
|
|
1582
|
-
const valueVariantOptions = [
|
|
1583
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
1584
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1585
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
1586
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1587
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1588
|
-
{ text: msg('Informace'), value: 'info' },
|
|
1589
|
-
];
|
|
1590
|
-
const valueVariantInput = pane.addBinding(config, 'valueVariant', {
|
|
1591
|
-
view: 'list',
|
|
1592
|
-
label: 'Value Color',
|
|
1593
|
-
options: valueVariantOptions,
|
|
1594
|
-
});
|
|
1595
|
-
valueVariantInput.on('change', (ev) => {
|
|
1596
|
-
if (ev.value === 'custom') {
|
|
1597
|
-
this.enableValueCustomStyles(cell);
|
|
1598
|
-
}
|
|
1599
|
-
else {
|
|
1600
|
-
this.setValueVariant(ev.value, cell);
|
|
1601
|
-
}
|
|
1602
|
-
});
|
|
1603
|
-
this.colorizeVariantSelect(valueVariantInput, valueVariantOptions, config, 'valueVariant');
|
|
1604
|
-
}
|
|
1605
|
-
addLinkControls(pane, config, cell) {
|
|
1606
|
-
// Link Type selector
|
|
1607
|
-
const linkTypeInput = pane.addBinding(config, 'linkType', {
|
|
1608
|
-
view: 'list',
|
|
1609
|
-
label: msg('Typ odkazu'),
|
|
1610
|
-
options: [
|
|
1611
|
-
{ text: msg('Vlastní URL'), value: 'custom' },
|
|
1612
|
-
{ text: msg('Dynamický odkaz'), value: 'dynamic' },
|
|
1613
|
-
],
|
|
1614
|
-
});
|
|
1615
|
-
linkTypeInput.on('change', (ev) => {
|
|
1616
|
-
this.setLinkType(cell, ev.value);
|
|
1617
|
-
});
|
|
1618
|
-
// Custom URL input (shown when linkType is 'custom')
|
|
1619
|
-
const hrefInput = pane.addBinding(config, 'href', {
|
|
1620
|
-
label: msg('Vlastní URL'),
|
|
1621
|
-
});
|
|
1622
|
-
hrefInput.on('change', (ev) => {
|
|
1623
|
-
this.setHref(cell, ev.value);
|
|
1624
|
-
});
|
|
1625
|
-
}
|
|
1626
|
-
addNumberControls(pane, config, cell) {
|
|
1627
|
-
// Value Bold
|
|
1628
|
-
const fontInput = pane.addBinding(config, 'fontWeight', {
|
|
1629
|
-
label: msg('Hodnota tučně'),
|
|
1630
|
-
});
|
|
1631
|
-
fontInput.on('change', () => {
|
|
1632
|
-
this.setFontWeight(cell);
|
|
1633
|
-
});
|
|
1634
|
-
// Value Variant
|
|
1635
|
-
const valueVariantOptions = [
|
|
1636
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
1637
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1638
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
1639
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1640
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1641
|
-
{ text: msg('Informace'), value: 'info' },
|
|
1642
|
-
];
|
|
1643
|
-
const valueVariantInput = pane.addBinding(config, 'valueVariant', {
|
|
1644
|
-
view: 'list',
|
|
1645
|
-
label: 'Value Color',
|
|
1646
|
-
options: valueVariantOptions,
|
|
1647
|
-
});
|
|
1648
|
-
valueVariantInput.on('change', (ev) => {
|
|
1649
|
-
if (ev.value === 'custom') {
|
|
1650
|
-
this.enableValueCustomStyles(cell);
|
|
1651
|
-
}
|
|
1652
|
-
else {
|
|
1653
|
-
this.setValueVariant(ev.value, cell);
|
|
1654
|
-
}
|
|
1655
|
-
});
|
|
1656
|
-
this.colorizeVariantSelect(valueVariantInput, valueVariantOptions, config, 'valueVariant');
|
|
1657
|
-
}
|
|
1658
|
-
addButtonControls(pane, config, cell) {
|
|
1659
|
-
// Button Variant
|
|
1660
|
-
const variantInput = pane.addBinding(config, 'buttonVariant', {
|
|
1661
|
-
view: 'list',
|
|
1662
|
-
label: msg('Varianta tlačítka'),
|
|
1663
|
-
options: [
|
|
1664
|
-
{ text: msg('Vyplněné'), value: 'contained' },
|
|
1665
|
-
{ text: msg('Ohraničené'), value: 'outlined' },
|
|
1666
|
-
{ text: msg('Textové'), value: 'text' },
|
|
1667
|
-
{ text: msg('Čárkované'), value: 'dashed' },
|
|
1668
|
-
],
|
|
1669
|
-
});
|
|
1670
|
-
variantInput.on('change', (ev) => {
|
|
1671
|
-
this.setButtonVariant(cell, ev.value);
|
|
1672
|
-
});
|
|
1673
|
-
// Button Color
|
|
1674
|
-
const buttonColorOptions = [
|
|
1675
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1676
|
-
{ text: msg('Druhé'), value: 'secondary' },
|
|
1677
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1678
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1679
|
-
{ text: msg('AI'), value: 'ai' },
|
|
1680
|
-
];
|
|
1681
|
-
const colorInput = pane.addBinding(config, 'buttonColor', {
|
|
1682
|
-
view: 'list',
|
|
1683
|
-
label: msg('Barva tlačítka'),
|
|
1684
|
-
options: buttonColorOptions,
|
|
1685
|
-
});
|
|
1686
|
-
colorInput.on('change', (ev) => {
|
|
1687
|
-
this.setButtonColor(cell, ev.value);
|
|
1688
|
-
});
|
|
1689
|
-
this.colorizeVariantSelect(colorInput, buttonColorOptions, config, 'buttonColor');
|
|
1690
|
-
// Button Full Width
|
|
1691
|
-
const fullWidthInput = pane.addBinding(config, 'buttonFullWidth', {
|
|
1692
|
-
label: msg('Tlačítko na celou šířku'),
|
|
1693
|
-
});
|
|
1694
|
-
fullWidthInput.on('change', (ev) => {
|
|
1695
|
-
this.setButtonFullWidth(cell, ev.value);
|
|
1696
|
-
});
|
|
1697
|
-
// Add link configuration for buttons (same as links)
|
|
1698
|
-
// Link Type selector
|
|
1699
|
-
const linkTypeInput = pane.addBinding(config, 'linkType', {
|
|
1700
|
-
view: 'list',
|
|
1701
|
-
label: msg('Typ odkazu'),
|
|
1702
|
-
options: [
|
|
1703
|
-
{ text: msg('Vlastní URL'), value: 'custom' },
|
|
1704
|
-
{ text: msg('Dynamický odkaz'), value: 'dynamic' },
|
|
1705
|
-
],
|
|
1706
|
-
});
|
|
1707
|
-
linkTypeInput.on('change', (ev) => {
|
|
1708
|
-
this.setLinkType(cell, ev.value);
|
|
1709
|
-
});
|
|
1710
|
-
// Custom URL input (shown when linkType is 'custom')
|
|
1711
|
-
const hrefInput = pane.addBinding(config, 'href', {
|
|
1712
|
-
label: msg('Vlastní URL'),
|
|
1713
|
-
});
|
|
1714
|
-
hrefInput.on('change', (ev) => {
|
|
1715
|
-
this.setHref(cell, ev.value);
|
|
1716
|
-
});
|
|
1717
|
-
}
|
|
1718
|
-
addCurrencyControls(pane, config, cell) {
|
|
1719
|
-
// Value Bold
|
|
1720
|
-
const fontInput = pane.addBinding(config, 'fontWeight', {
|
|
1721
|
-
label: msg('Tučná hodnota'),
|
|
1722
|
-
});
|
|
1723
|
-
fontInput.on('change', () => {
|
|
1724
|
-
this.setFontWeight(cell);
|
|
1725
|
-
});
|
|
1726
|
-
// Value Variant
|
|
1727
|
-
const valueVariantOptions = [
|
|
1728
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
1729
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1730
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
1731
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1732
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1733
|
-
{ text: msg('Informace'), value: 'info' },
|
|
1734
|
-
{ text: msg('Vlastní'), value: 'custom' },
|
|
1735
|
-
];
|
|
1736
|
-
const valueVariantInput = pane.addBinding(config, 'valueVariant', {
|
|
1737
|
-
view: 'list',
|
|
1738
|
-
label: 'Value Color',
|
|
1739
|
-
options: valueVariantOptions,
|
|
1740
|
-
});
|
|
1741
|
-
valueVariantInput.on('change', (ev) => {
|
|
1742
|
-
if (ev.value === 'custom') {
|
|
1743
|
-
this.enableValueCustomStyles(cell);
|
|
1744
|
-
}
|
|
1745
|
-
else {
|
|
1746
|
-
this.setValueVariant(ev.value, cell);
|
|
1747
|
-
}
|
|
1748
|
-
});
|
|
1749
|
-
this.colorizeVariantSelect(valueVariantInput, valueVariantOptions, config, 'valueVariant');
|
|
1750
|
-
// Number of Decimals
|
|
1751
|
-
const decimalInput = pane.addBinding(config, 'numberOfDecimal', {
|
|
1752
|
-
label: msg('Počet desetinných míst'),
|
|
1753
|
-
min: 0,
|
|
1754
|
-
max: 10,
|
|
1755
|
-
step: 1,
|
|
1756
|
-
});
|
|
1757
|
-
decimalInput.on('change', (ev) => {
|
|
1758
|
-
this.setNumberOfDecimal(cell, ev.value);
|
|
1759
|
-
});
|
|
1760
|
-
// Currency Type
|
|
1761
|
-
const currencyOptions = [
|
|
1762
|
-
{ text: 'CZK', value: 'CZK' },
|
|
1763
|
-
{ text: 'EUR', value: 'EUR' },
|
|
1764
|
-
{ text: 'USD', value: 'USD' },
|
|
1765
|
-
{ text: 'GBP', value: 'GBP' },
|
|
1766
|
-
{ text: 'CHF', value: 'CHF' },
|
|
1767
|
-
{ text: 'PLN', value: 'PLN' },
|
|
1768
|
-
{ text: 'HUF', value: 'HUF' },
|
|
1769
|
-
{ text: 'JPY', value: 'JPY' },
|
|
1770
|
-
{ text: 'AUD', value: 'AUD' },
|
|
1771
|
-
{ text: 'CAD', value: 'CAD' },
|
|
1772
|
-
{ text: 'NOK', value: 'NOK' },
|
|
1773
|
-
{ text: 'SEK', value: 'SEK' },
|
|
1774
|
-
{ text: 'DKK', value: 'DKK' },
|
|
1775
|
-
{ text: 'CNY', value: 'CNY' },
|
|
1776
|
-
{ text: 'RUB', value: 'RUB' },
|
|
1777
|
-
];
|
|
1778
|
-
// Add variables as currency source options
|
|
1779
|
-
const variableOptions = this.getAllAvailableVariables();
|
|
1780
|
-
variableOptions.forEach((v) => {
|
|
1781
|
-
currencyOptions.push({
|
|
1782
|
-
text: `${v.text}`,
|
|
1783
|
-
value: `var:${v.value}`,
|
|
1784
|
-
});
|
|
1785
|
-
});
|
|
1786
|
-
const currencyInput = pane.addBinding(config, 'currencyType', {
|
|
1787
|
-
view: 'list',
|
|
1788
|
-
label: msg('Typ měny'),
|
|
1789
|
-
options: currencyOptions,
|
|
1790
|
-
});
|
|
1791
|
-
currencyInput.on('change', (ev) => {
|
|
1792
|
-
this.setCurrencyType(cell, ev.value);
|
|
1793
|
-
});
|
|
1794
|
-
}
|
|
1795
|
-
addDateControls(pane, config, cell) {
|
|
1796
|
-
// Value Bold
|
|
1797
|
-
const fontInput = pane.addBinding(config, 'fontWeight', {
|
|
1798
|
-
label: msg('Tučná hodnota'),
|
|
1799
|
-
});
|
|
1800
|
-
fontInput.on('change', () => {
|
|
1801
|
-
this.setFontWeight(cell);
|
|
1802
|
-
});
|
|
1803
|
-
// Value Variant
|
|
1804
|
-
const valueVariantOptions = [
|
|
1805
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
1806
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1807
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
1808
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1809
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1810
|
-
{ text: msg('Informace'), value: 'info' },
|
|
1811
|
-
];
|
|
1812
|
-
const valueVariantInput = pane.addBinding(config, 'valueVariant', {
|
|
1813
|
-
view: 'list',
|
|
1814
|
-
label: 'Value Color',
|
|
1815
|
-
options: valueVariantOptions,
|
|
1816
|
-
});
|
|
1817
|
-
valueVariantInput.on('change', (ev) => {
|
|
1818
|
-
if (ev.value === 'custom') {
|
|
1819
|
-
this.enableValueCustomStyles(cell);
|
|
1820
|
-
}
|
|
1821
|
-
else {
|
|
1822
|
-
this.setValueVariant(ev.value, cell);
|
|
1823
|
-
}
|
|
1824
|
-
});
|
|
1825
|
-
this.colorizeVariantSelect(valueVariantInput, valueVariantOptions, config, 'valueVariant');
|
|
1826
|
-
}
|
|
1827
|
-
addProgressControls(pane, config, cell) {
|
|
1828
|
-
// Progress Max — numeric value for 100%
|
|
1829
|
-
const progressMaxInput = pane.addBinding(config, 'progressMax', {
|
|
1830
|
-
label: msg('Hodnota 100%'),
|
|
1831
|
-
min: 1,
|
|
1832
|
-
step: 1,
|
|
1833
|
-
});
|
|
1834
|
-
progressMaxInput.on('change', (ev) => {
|
|
1835
|
-
this.setProgressMax(cell, ev.value);
|
|
1836
|
-
});
|
|
1837
|
-
// Progress Color
|
|
1838
|
-
const progressColorOptions = [
|
|
1839
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1840
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
1841
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1842
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1843
|
-
{ text: msg('Informace'), value: 'info' },
|
|
1844
|
-
];
|
|
1845
|
-
const progressColorInput = pane.addBinding(config, 'progressColor', {
|
|
1846
|
-
view: 'list',
|
|
1847
|
-
label: msg('Barva postupu'),
|
|
1848
|
-
options: progressColorOptions,
|
|
1849
|
-
});
|
|
1850
|
-
progressColorInput.on('change', (ev) => {
|
|
1851
|
-
this.setProgressColor(cell, ev.value);
|
|
1852
|
-
});
|
|
1853
|
-
this.colorizeVariantSelect(progressColorInput, progressColorOptions, config, 'progressColor');
|
|
1854
|
-
// Value Variant (for progress text color if needed)
|
|
1855
|
-
const valueVariantOptions = [
|
|
1856
|
-
{ text: msg('Výchozí'), value: 'default' },
|
|
1857
|
-
{ text: msg('Primární'), value: 'primary' },
|
|
1858
|
-
{ text: msg('Úspěch'), value: 'success' },
|
|
1859
|
-
{ text: msg('Varování'), value: 'warning' },
|
|
1860
|
-
{ text: msg('Chyba'), value: 'error' },
|
|
1861
|
-
{ text: msg('Informace'), value: 'info' },
|
|
1862
|
-
];
|
|
1863
|
-
const valueVariantInput = pane.addBinding(config, 'valueVariant', {
|
|
1864
|
-
view: 'list',
|
|
1865
|
-
label: 'Value Color',
|
|
1866
|
-
options: valueVariantOptions,
|
|
1867
|
-
});
|
|
1868
|
-
valueVariantInput.on('change', (ev) => {
|
|
1869
|
-
if (ev.value === 'custom') {
|
|
1870
|
-
this.enableValueCustomStyles(cell);
|
|
1871
|
-
}
|
|
1872
|
-
else {
|
|
1873
|
-
this.setValueVariant(ev.value, cell);
|
|
1874
|
-
}
|
|
1875
|
-
});
|
|
1876
|
-
this.colorizeVariantSelect(valueVariantInput, valueVariantOptions, config, 'valueVariant');
|
|
1877
|
-
}
|
|
1878
|
-
getVariableValue(fieldName) {
|
|
1879
|
-
// First check in variables array for a matching field
|
|
1880
|
-
if (this.variables && Array.isArray(this.variables)) {
|
|
1881
|
-
const variableObj = this.variables.find((variable) => variable.field === fieldName);
|
|
1882
|
-
if (variableObj) {
|
|
1883
|
-
return variableObj.value;
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
// Then check in current rows
|
|
1887
|
-
const rowCell = this.rows.find((cell) => cell.field === fieldName);
|
|
1888
|
-
if (rowCell) {
|
|
1889
|
-
return rowCell.value;
|
|
1890
|
-
}
|
|
1891
|
-
// Finally check in variables array
|
|
1892
|
-
const variableItem = this.variables.find((variable) => variable.field === fieldName);
|
|
1893
|
-
if (variableItem) {
|
|
1894
|
-
return variableItem.value;
|
|
1895
|
-
}
|
|
1896
|
-
return '';
|
|
1897
|
-
}
|
|
1898
|
-
evaluateCondition(variableField, conditionValue, operator) {
|
|
1899
|
-
// Get the value of the selected variable
|
|
1900
|
-
const variableValue = this.getVariableValue(variableField);
|
|
1901
|
-
// For isEmpty/isNotEmpty operators, check the raw value first
|
|
1902
|
-
if (operator === 'isEmpty') {
|
|
1903
|
-
return (variableValue === null ||
|
|
1904
|
-
variableValue === undefined ||
|
|
1905
|
-
variableValue === '' ||
|
|
1906
|
-
(typeof variableValue === 'string' && variableValue.trim() === ''));
|
|
1907
|
-
}
|
|
1908
|
-
if (operator === 'isNotEmpty') {
|
|
1909
|
-
return !(variableValue === null ||
|
|
1910
|
-
variableValue === undefined ||
|
|
1911
|
-
variableValue === '' ||
|
|
1912
|
-
(typeof variableValue === 'string' && variableValue.trim() === ''));
|
|
1913
|
-
}
|
|
1914
|
-
// Determine field type for proper comparison
|
|
1915
|
-
const fieldCell = this.rows.find((cell) => cell.field === variableField);
|
|
1916
|
-
// Determine field type for proper comparison
|
|
1917
|
-
let fieldType = 'string';
|
|
1918
|
-
if (fieldCell) {
|
|
1919
|
-
// Use cell.type directly for field type determination
|
|
1920
|
-
switch (fieldCell.type) {
|
|
1921
|
-
case 'number':
|
|
1922
|
-
case 'progress':
|
|
1923
|
-
case 'currency':
|
|
1924
|
-
fieldType = 'number';
|
|
1925
|
-
break;
|
|
1926
|
-
case 'date':
|
|
1927
|
-
fieldType = 'date';
|
|
1928
|
-
break;
|
|
1929
|
-
case 'select':
|
|
1930
|
-
case 'checkbox':
|
|
1931
|
-
fieldType = 'select';
|
|
1932
|
-
break;
|
|
1933
|
-
case 'multiselect':
|
|
1934
|
-
fieldType = 'multiselect';
|
|
1935
|
-
break;
|
|
1936
|
-
case 'string':
|
|
1937
|
-
case 'button':
|
|
1938
|
-
case 'link':
|
|
1939
|
-
default:
|
|
1940
|
-
fieldType = 'string';
|
|
1941
|
-
break;
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
const variableStr = String(variableValue || '').toLowerCase();
|
|
1945
|
-
const conditionStr = String(conditionValue || '').toLowerCase();
|
|
1946
|
-
const variableNum = parseFloat(variableValue);
|
|
1947
|
-
const conditionNum = parseFloat(conditionValue);
|
|
1948
|
-
// For date fields, parse dates for comparison
|
|
1949
|
-
let variableDate = null;
|
|
1950
|
-
let conditionDate = null;
|
|
1951
|
-
if (fieldType === 'date') {
|
|
1952
|
-
variableDate = variableValue ? new Date(variableValue) : null;
|
|
1953
|
-
conditionDate = conditionValue ? new Date(conditionValue) : null;
|
|
1954
|
-
}
|
|
1955
|
-
switch (operator) {
|
|
1956
|
-
case '=':
|
|
1957
|
-
// Use numeric comparison for number/currency/progress types
|
|
1958
|
-
if (fieldType === 'number' /* ||
|
|
1959
|
-
fieldType === 'currency' ||
|
|
1960
|
-
fieldType === 'progress' */) {
|
|
1961
|
-
return (!isNaN(variableNum) && !isNaN(conditionNum) && variableNum === conditionNum);
|
|
1962
|
-
}
|
|
1963
|
-
else if (fieldType === 'date') {
|
|
1964
|
-
if (!variableDate || !conditionDate)
|
|
1965
|
-
return false;
|
|
1966
|
-
return variableDate.getTime() === conditionDate.getTime();
|
|
1967
|
-
}
|
|
1968
|
-
else {
|
|
1969
|
-
return variableStr === conditionStr;
|
|
1970
|
-
}
|
|
1971
|
-
case '!=':
|
|
1972
|
-
// Use numeric comparison for number/currency/progress types
|
|
1973
|
-
if (fieldType === 'number' /* ||
|
|
1974
|
-
fieldType === 'currency' ||
|
|
1975
|
-
fieldType === 'progress' */) {
|
|
1976
|
-
return (!isNaN(variableNum) && !isNaN(conditionNum) && variableNum !== conditionNum);
|
|
1977
|
-
}
|
|
1978
|
-
else if (fieldType === 'date') {
|
|
1979
|
-
if (!variableDate || !conditionDate)
|
|
1980
|
-
return true;
|
|
1981
|
-
return variableDate.getTime() !== conditionDate.getTime();
|
|
1982
|
-
}
|
|
1983
|
-
else {
|
|
1984
|
-
return variableStr !== conditionStr;
|
|
1985
|
-
}
|
|
1986
|
-
case '>':
|
|
1987
|
-
if (fieldType === 'date') {
|
|
1988
|
-
if (!variableDate || !conditionDate)
|
|
1989
|
-
return false;
|
|
1990
|
-
return variableDate.getTime() > conditionDate.getTime();
|
|
1991
|
-
}
|
|
1992
|
-
return !isNaN(variableNum) && !isNaN(conditionNum) && variableNum > conditionNum;
|
|
1993
|
-
case '>=':
|
|
1994
|
-
if (fieldType === 'date') {
|
|
1995
|
-
if (!variableDate || !conditionDate)
|
|
1996
|
-
return false;
|
|
1997
|
-
return variableDate.getTime() >= conditionDate.getTime();
|
|
1998
|
-
}
|
|
1999
|
-
return !isNaN(variableNum) && !isNaN(conditionNum) && variableNum >= conditionNum;
|
|
2000
|
-
case '<':
|
|
2001
|
-
if (fieldType === 'date') {
|
|
2002
|
-
if (!variableDate || !conditionDate)
|
|
2003
|
-
return false;
|
|
2004
|
-
return variableDate.getTime() < conditionDate.getTime();
|
|
2005
|
-
}
|
|
2006
|
-
return !isNaN(variableNum) && !isNaN(conditionNum) && variableNum < conditionNum;
|
|
2007
|
-
case '<=':
|
|
2008
|
-
if (fieldType === 'date') {
|
|
2009
|
-
if (!variableDate || !conditionDate)
|
|
2010
|
-
return false;
|
|
2011
|
-
return variableDate.getTime() <= conditionDate.getTime();
|
|
2012
|
-
}
|
|
2013
|
-
return !isNaN(variableNum) && !isNaN(conditionNum) && variableNum <= conditionNum;
|
|
2014
|
-
case 'contains':
|
|
2015
|
-
return variableStr.includes(conditionStr);
|
|
2016
|
-
case 'doesNotContain':
|
|
2017
|
-
return !variableStr.includes(conditionStr);
|
|
2018
|
-
case 'startsWith':
|
|
2019
|
-
return variableStr.startsWith(conditionStr);
|
|
2020
|
-
case 'endsWith':
|
|
2021
|
-
return variableStr.endsWith(conditionStr);
|
|
2022
|
-
case 'is':
|
|
2023
|
-
// "is" operator - for select type fields only
|
|
2024
|
-
// Use exact value matching (case-sensitive)
|
|
2025
|
-
return String(variableValue) === String(conditionValue);
|
|
2026
|
-
case 'not':
|
|
2027
|
-
// "not" operator (is not) - for select type fields only
|
|
2028
|
-
// Use exact value matching (case-sensitive)
|
|
2029
|
-
return String(variableValue) !== String(conditionValue);
|
|
2030
|
-
case 'in':
|
|
2031
|
-
// "in" operator - for multiselect fields
|
|
2032
|
-
// variableValue is an array, check if conditionValue is in that array
|
|
2033
|
-
if (Array.isArray(variableValue)) {
|
|
2034
|
-
return variableValue.includes(conditionValue);
|
|
2035
|
-
}
|
|
2036
|
-
// Fallback: check if variableValue is in conditionValue list
|
|
2037
|
-
if (Array.isArray(conditionValue)) {
|
|
2038
|
-
return conditionValue.includes(variableValue);
|
|
2039
|
-
}
|
|
2040
|
-
else {
|
|
2041
|
-
// Parse comma-separated string
|
|
2042
|
-
const values = String(conditionValue)
|
|
2043
|
-
.split(',')
|
|
2044
|
-
.map((v) => v.trim());
|
|
2045
|
-
return values.includes(String(variableValue));
|
|
2046
|
-
}
|
|
2047
|
-
case 'nin':
|
|
2048
|
-
// "nin" operator (not in) - for multiselect fields
|
|
2049
|
-
// variableValue is an array, check if conditionValue is not in that array
|
|
2050
|
-
if (Array.isArray(variableValue)) {
|
|
2051
|
-
return !variableValue.includes(conditionValue);
|
|
2052
|
-
}
|
|
2053
|
-
// Fallback: check if variableValue is not in conditionValue list
|
|
2054
|
-
if (Array.isArray(conditionValue)) {
|
|
2055
|
-
return !conditionValue.includes(variableValue);
|
|
2056
|
-
}
|
|
2057
|
-
else {
|
|
2058
|
-
// Parse comma-separated string
|
|
2059
|
-
const values = String(conditionValue)
|
|
2060
|
-
.split(',')
|
|
2061
|
-
.map((v) => v.trim());
|
|
2062
|
-
return !values.includes(String(variableValue));
|
|
2063
|
-
}
|
|
2064
|
-
case 'isAnyOfValue':
|
|
2065
|
-
// "isAnyOfValue" operator - checks if variableValue matches any of the comma-separated values
|
|
2066
|
-
if (!conditionValue)
|
|
2067
|
-
return false;
|
|
2068
|
-
// If variableValue is an array (for multiselect), check if any element matches any condition value
|
|
2069
|
-
if (Array.isArray(variableValue)) {
|
|
2070
|
-
const conditionValues = String(conditionValue)
|
|
2071
|
-
.split(',')
|
|
2072
|
-
.map((v) => v.trim().toLowerCase());
|
|
2073
|
-
return variableValue.some((val) => conditionValues.includes(String(val).toLowerCase()));
|
|
2074
|
-
}
|
|
2075
|
-
// For single values, check if variableValue matches any of the condition values
|
|
2076
|
-
const values = String(conditionValue)
|
|
2077
|
-
.split(',')
|
|
2078
|
-
.map((v) => v.trim().toLowerCase());
|
|
2079
|
-
return values.includes(variableStr);
|
|
2080
|
-
default:
|
|
2081
|
-
return false;
|
|
2082
|
-
}
|
|
2083
|
-
}
|
|
2084
|
-
computeCellStyles(cell) {
|
|
2085
|
-
// Priority order:
|
|
2086
|
-
// 1. Conditional formatting (highest)
|
|
2087
|
-
// 2. Custom cellStyle (if cellCustomStyles = true)
|
|
2088
|
-
// 3. Semantic cellVariant
|
|
2089
|
-
// 4. Default styles (lowest)
|
|
2090
|
-
let styles = {};
|
|
2091
|
-
// 4. Default styles (base)
|
|
2092
|
-
// (none for now, could add default cell styling here)
|
|
2093
|
-
// 3. Semantic cellVariant
|
|
2094
|
-
if (cell.cellVariant && cell.cellVariant !== 'default') {
|
|
2095
|
-
const variantStyle = this.getCellVariantStyle(cell.cellVariant);
|
|
2096
|
-
styles = { ...styles, ...variantStyle };
|
|
2097
|
-
}
|
|
2098
|
-
// 2. Custom cellStyle (if explicitly enabled)
|
|
2099
|
-
if (cell.cellCustomStyles && cell.cellStyle) {
|
|
2100
|
-
styles = { ...styles, ...cell.cellStyle };
|
|
2101
|
-
}
|
|
2102
|
-
// 1. Conditional formatting cell variant (highest priority, first match wins)
|
|
2103
|
-
const conditions = this.normalizeConditions(cell.conditionalFormatting);
|
|
2104
|
-
for (const condition of conditions) {
|
|
2105
|
-
if (condition?.enabled && condition?.variable) {
|
|
2106
|
-
const conditionMet = this.evaluateCondition(condition.variable, condition.value, condition.operator);
|
|
2107
|
-
if (conditionMet &&
|
|
2108
|
-
condition.cellVariant &&
|
|
2109
|
-
condition.cellVariant !== 'default') {
|
|
2110
|
-
const conditionalCellStyle = this.getCellVariantStyle(condition.cellVariant);
|
|
2111
|
-
styles = { ...styles, ...conditionalCellStyle };
|
|
2112
|
-
break;
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
return styles;
|
|
2117
|
-
}
|
|
2118
|
-
getCellVariantStyle(variant) {
|
|
2119
|
-
const variantMap = {
|
|
2120
|
-
primary: {
|
|
2121
|
-
backgroundColor: 'var(--color-primary-light)',
|
|
2122
|
-
borderRadius: '8px',
|
|
2123
|
-
border: '1px solid var(--color-primary-dark)',
|
|
2124
|
-
},
|
|
2125
|
-
success: {
|
|
2126
|
-
backgroundColor: 'var(--color-success-light)',
|
|
2127
|
-
borderRadius: '8px',
|
|
2128
|
-
border: '1px solid var(--color-success-dark)',
|
|
2129
|
-
},
|
|
2130
|
-
warning: {
|
|
2131
|
-
backgroundColor: 'var(--color-warning-light)',
|
|
2132
|
-
borderRadius: '8px',
|
|
2133
|
-
border: '1px solid var(--color-warning-dark)',
|
|
2134
|
-
},
|
|
2135
|
-
error: {
|
|
2136
|
-
backgroundColor: 'var(--color-error-light)',
|
|
2137
|
-
borderRadius: '8px',
|
|
2138
|
-
border: '1px solid var(--color-error-dark)',
|
|
2139
|
-
},
|
|
2140
|
-
info: {
|
|
2141
|
-
backgroundColor: 'var(--color-info-light)',
|
|
2142
|
-
borderRadius: '8px',
|
|
2143
|
-
border: '1px solid var(--color-info-dark)',
|
|
2144
|
-
},
|
|
2145
|
-
};
|
|
2146
|
-
return variantMap[variant] || {};
|
|
2147
|
-
}
|
|
2148
|
-
computeValueStyles(cell) {
|
|
2149
|
-
// Priority order:
|
|
2150
|
-
// 1. Conditional formatting value variant (highest)
|
|
2151
|
-
// 2. Custom valueStyle (if valueCustomStyles = true)
|
|
2152
|
-
// 3. Semantic valueVariant + Independent fontWeight
|
|
2153
|
-
// 4. Default styles (lowest)
|
|
2154
|
-
let styles = {};
|
|
2155
|
-
// 4. Default styles (base)
|
|
2156
|
-
// (none for now, could add default value styling here)
|
|
2157
|
-
// 3. Semantic valueVariant
|
|
2158
|
-
if (cell.valueVariant && cell.valueVariant !== 'default') {
|
|
2159
|
-
const variantStyle = this.getValueVariantStyle(cell.valueVariant);
|
|
2160
|
-
styles = { ...styles, ...variantStyle };
|
|
2161
|
-
}
|
|
2162
|
-
// 3b. Independent fontWeight (works alongside variants)
|
|
2163
|
-
if (cell.fontWeight && cell.fontWeight !== 'normal') {
|
|
2164
|
-
styles = { ...styles, fontWeight: cell.fontWeight };
|
|
2165
|
-
}
|
|
2166
|
-
// 2. Custom valueStyle (if explicitly enabled)
|
|
2167
|
-
if (cell.valueCustomStyles && cell.valueStyle) {
|
|
2168
|
-
styles = { ...styles, ...cell.valueStyle };
|
|
2169
|
-
}
|
|
2170
|
-
// 1. Conditional formatting value variant (highest priority, first match wins)
|
|
2171
|
-
const conditions = this.normalizeConditions(cell.conditionalFormatting);
|
|
2172
|
-
for (const condition of conditions) {
|
|
2173
|
-
if (condition?.enabled && condition?.variable) {
|
|
2174
|
-
const conditionMet = this.evaluateCondition(condition.variable, condition.value, condition.operator);
|
|
2175
|
-
if (conditionMet &&
|
|
2176
|
-
condition.valueVariant &&
|
|
2177
|
-
condition.valueVariant !== 'default') {
|
|
2178
|
-
const conditionalValueStyle = this.getValueVariantStyle(condition.valueVariant);
|
|
2179
|
-
styles = { ...styles, ...conditionalValueStyle };
|
|
2180
|
-
break;
|
|
2181
|
-
}
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
return styles;
|
|
2185
|
-
}
|
|
2186
|
-
// Helper method to convert progress value (string or number) to numeric value
|
|
2187
|
-
parseProgressValue(value) {
|
|
2188
|
-
if (typeof value === 'number') {
|
|
2189
|
-
return value;
|
|
2190
|
-
}
|
|
2191
|
-
else if (typeof value === 'string') {
|
|
2192
|
-
const parsed = parseFloat(value);
|
|
2193
|
-
return !isNaN(parsed) ? parsed : 0;
|
|
2194
|
-
}
|
|
2195
|
-
return 0;
|
|
2196
|
-
}
|
|
2197
|
-
computeProgressColor(cell) {
|
|
2198
|
-
// Priority order:
|
|
2199
|
-
// 1. Conditional formatting progressColor (highest)
|
|
2200
|
-
// 2. Cell progressColor property
|
|
2201
|
-
// 3. Default 'primary' color (lowest)
|
|
2202
|
-
let progressColor = cell.progressColor || 'primary';
|
|
2203
|
-
// 1. Conditional formatting progressColor (highest priority, first match wins)
|
|
2204
|
-
const conditions = this.normalizeConditions(cell.conditionalFormatting);
|
|
2205
|
-
for (const condition of conditions) {
|
|
2206
|
-
if (condition?.enabled && condition?.variable) {
|
|
2207
|
-
const conditionMet = this.evaluateCondition(condition.variable, condition.value, condition.operator);
|
|
2208
|
-
if (conditionMet && condition.progressColor) {
|
|
2209
|
-
progressColor = condition.progressColor;
|
|
2210
|
-
break;
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
}
|
|
2214
|
-
return progressColor;
|
|
2215
|
-
}
|
|
2216
|
-
getValueVariantStyle(variant) {
|
|
2217
|
-
const variantMap = {
|
|
2218
|
-
primary: {
|
|
2219
|
-
color: 'var(--color-primary-main)',
|
|
2220
|
-
fontWeight: '500',
|
|
2221
|
-
},
|
|
2222
|
-
success: {
|
|
2223
|
-
color: 'var(--color-success-main)',
|
|
2224
|
-
fontWeight: '500',
|
|
2225
|
-
},
|
|
2226
|
-
warning: {
|
|
2227
|
-
color: 'var(--color-warning-main)',
|
|
2228
|
-
fontWeight: '500',
|
|
2229
|
-
},
|
|
2230
|
-
error: {
|
|
2231
|
-
color: 'var(--color-error-main)',
|
|
2232
|
-
fontWeight: '500',
|
|
2233
|
-
},
|
|
2234
|
-
info: {
|
|
2235
|
-
color: 'var(--color-info-main)',
|
|
2236
|
-
fontWeight: '500',
|
|
2237
|
-
},
|
|
2238
|
-
};
|
|
2239
|
-
return variantMap[variant] || {};
|
|
2240
|
-
}
|
|
2241
|
-
shouldHideCell(cell) {
|
|
2242
|
-
const hideCondition = cell.hideCondition;
|
|
2243
|
-
if (!hideCondition?.enabled || !hideCondition?.variable || this.enableSettings) {
|
|
2244
|
-
return false;
|
|
2245
|
-
}
|
|
2246
|
-
return this.evaluateCondition(hideCondition.variable, hideCondition.value, hideCondition.operator);
|
|
2247
|
-
}
|
|
2248
|
-
initSortable() {
|
|
2249
|
-
this.updateComplete.then(() => {
|
|
2250
|
-
const containers = this.shadowRoot?.querySelectorAll('.grid-container');
|
|
2251
|
-
if (!containers?.length)
|
|
2252
|
-
return;
|
|
2253
|
-
containers.forEach((container) => {
|
|
2254
|
-
let originalNodes = [];
|
|
2255
|
-
const sortableInstance = Sortable.create(container, {
|
|
2256
|
-
group: this.tabId || this.sortableGroupId,
|
|
2257
|
-
animation: 150,
|
|
2258
|
-
handle: '.drag-handle',
|
|
2259
|
-
ghostClass: 'sortable-ghost',
|
|
2260
|
-
chosenClass: 'sortable-chosen',
|
|
2261
|
-
dragClass: 'sortable-drag',
|
|
2262
|
-
sort: true,
|
|
2263
|
-
onStart: (evt) => {
|
|
2264
|
-
originalNodes = Array.from(evt.from.childNodes);
|
|
2265
|
-
},
|
|
2266
|
-
onEnd: (evt) => {
|
|
2267
|
-
evt.from.innerHTML = '';
|
|
2268
|
-
originalNodes.forEach((node) => evt.from.appendChild(node));
|
|
2269
|
-
const { oldIndex, newIndex } = evt;
|
|
2270
|
-
if (oldIndex == null || newIndex == null || oldIndex === newIndex)
|
|
2271
|
-
return;
|
|
2272
|
-
const updated = [...this.rows];
|
|
2273
|
-
const [movedItem] = updated.splice(oldIndex, 1);
|
|
2274
|
-
updated.splice(newIndex, 0, movedItem);
|
|
2275
|
-
this.rows = updated;
|
|
2276
|
-
this.handleSettingsChanged?.(updated);
|
|
2277
|
-
},
|
|
2278
|
-
});
|
|
2279
|
-
this.sortableInstances.push(sortableInstance);
|
|
2280
|
-
});
|
|
2281
|
-
});
|
|
2282
|
-
}
|
|
2283
|
-
getLocaleLang() {
|
|
2284
|
-
if (this.userLang && LOCALE_LANGS.has(this.userLang)) {
|
|
2285
|
-
return this.userLang;
|
|
2286
|
-
}
|
|
2287
|
-
return 'cs';
|
|
2288
|
-
}
|
|
2289
|
-
setCellSize(size, cell, breakpoint = 'lg') {
|
|
2290
|
-
this.rows = this.rows.map((c) => {
|
|
2291
|
-
if (c.field === cell.field) {
|
|
2292
|
-
const updatedCell = { ...c };
|
|
2293
|
-
if (!updatedCell.size) {
|
|
2294
|
-
updatedCell.size = {};
|
|
2295
|
-
}
|
|
2296
|
-
if (breakpoint === 'xs') {
|
|
2297
|
-
updatedCell.size.xs = size;
|
|
2298
|
-
updatedCell.size.sm = size;
|
|
2299
|
-
}
|
|
2300
|
-
else if (breakpoint === 'lg') {
|
|
2301
|
-
updatedCell.size.md = size;
|
|
2302
|
-
updatedCell.size.lg = size;
|
|
2303
|
-
updatedCell.size.xl = size;
|
|
2304
|
-
}
|
|
2305
|
-
else {
|
|
2306
|
-
updatedCell.size[breakpoint] = size;
|
|
2307
|
-
}
|
|
2308
|
-
return updatedCell;
|
|
2309
|
-
}
|
|
2310
|
-
return c;
|
|
2311
|
-
});
|
|
2312
|
-
this.handleSettingsChanged(this.rows);
|
|
2313
|
-
}
|
|
2314
|
-
setCellType(cell, type) {
|
|
2315
|
-
this.rows = this.rows.map((c) => {
|
|
2316
|
-
if (c.field === cell.field) {
|
|
2317
|
-
return { ...c, type };
|
|
2318
|
-
}
|
|
2319
|
-
return c;
|
|
2320
|
-
});
|
|
2321
|
-
this.handleSettingsChanged(this.rows);
|
|
2322
|
-
// Simply close the settings popper when cell type changes
|
|
2323
|
-
// User can reopen to see the new type-specific controls
|
|
2324
|
-
//this.closeSettingsPopper();
|
|
2325
|
-
}
|
|
2326
|
-
setHideCondition(cell, property, value) {
|
|
2327
|
-
// Update the cell in the rows array
|
|
2328
|
-
this.rows = this.rows.map((c) => {
|
|
2329
|
-
if (c.field === cell.field) {
|
|
2330
|
-
const updatedCell = { ...c };
|
|
2331
|
-
// Initialize hide condition if not exists
|
|
2332
|
-
if (!updatedCell.hideCondition) {
|
|
2333
|
-
updatedCell.hideCondition = {
|
|
2334
|
-
// Set default operator when creating new hide condition
|
|
2335
|
-
operator: this.getDefaultOperatorForCell(cell),
|
|
2336
|
-
};
|
|
2337
|
-
}
|
|
2338
|
-
else {
|
|
2339
|
-
// Create a copy of hideCondition to avoid mutating the original
|
|
2340
|
-
updatedCell.hideCondition = { ...updatedCell.hideCondition };
|
|
2341
|
-
}
|
|
2342
|
-
// Set the property
|
|
2343
|
-
updatedCell.hideCondition[property] = value;
|
|
2344
|
-
return updatedCell;
|
|
2345
|
-
}
|
|
2346
|
-
return c;
|
|
2347
|
-
});
|
|
2348
|
-
this.handleSettingsChanged(this.rows);
|
|
2349
|
-
}
|
|
2350
|
-
setHref(cell, href) {
|
|
2351
|
-
this.rows = this.rows.map((c) => {
|
|
2352
|
-
if (c.field === cell.field) {
|
|
2353
|
-
return { ...c, href };
|
|
2354
|
-
}
|
|
2355
|
-
return c;
|
|
2356
|
-
});
|
|
2357
|
-
this.handleSettingsChanged(this.rows);
|
|
2358
|
-
}
|
|
2359
|
-
setLinkType(cell, linkType) {
|
|
2360
|
-
this.rows = this.rows.map((c) => {
|
|
2361
|
-
if (c.field === cell.field) {
|
|
2362
|
-
const updatedCell = { ...c, linkType: linkType };
|
|
2363
|
-
// Clear other link properties when switching types
|
|
2364
|
-
{
|
|
2365
|
-
updatedCell.href = '';
|
|
2366
|
-
}
|
|
2367
|
-
return updatedCell;
|
|
2368
|
-
}
|
|
2369
|
-
return c;
|
|
2370
|
-
});
|
|
2371
|
-
this.handleSettingsChanged(this.rows);
|
|
2372
|
-
}
|
|
2373
|
-
setNumberOfDecimal(cell, numberOfDecimal) {
|
|
2374
|
-
this.rows = this.rows.map((c) => {
|
|
2375
|
-
if (c.field === cell.field) {
|
|
2376
|
-
return { ...c, numberOfDecimal };
|
|
2377
|
-
}
|
|
2378
|
-
return c;
|
|
2379
|
-
});
|
|
2380
|
-
this.handleSettingsChanged(this.rows);
|
|
2381
|
-
}
|
|
2382
|
-
setButtonVariant(cell, variant) {
|
|
2383
|
-
this.rows = this.rows.map((c) => {
|
|
2384
|
-
if (c.field === cell.field) {
|
|
2385
|
-
return { ...c, buttonVariant: variant };
|
|
2386
|
-
}
|
|
2387
|
-
return c;
|
|
2388
|
-
});
|
|
2389
|
-
this.handleSettingsChanged(this.rows);
|
|
2390
|
-
}
|
|
2391
|
-
setButtonColor(cell, color) {
|
|
2392
|
-
this.rows = this.rows.map((c) => {
|
|
2393
|
-
if (c.field === cell.field) {
|
|
2394
|
-
return { ...c, buttonColor: color };
|
|
2395
|
-
}
|
|
2396
|
-
return c;
|
|
2397
|
-
});
|
|
2398
|
-
this.handleSettingsChanged(this.rows);
|
|
2399
|
-
}
|
|
2400
|
-
setButtonFullWidth(cell, fullWidth) {
|
|
2401
|
-
this.rows = this.rows.map((c) => {
|
|
2402
|
-
if (c.field === cell.field) {
|
|
2403
|
-
return { ...c, buttonFullWidth: fullWidth };
|
|
2404
|
-
}
|
|
2405
|
-
return c;
|
|
2406
|
-
});
|
|
2407
|
-
this.handleSettingsChanged(this.rows);
|
|
2408
|
-
}
|
|
2409
|
-
setCurrencyType(cell, currencyType) {
|
|
2410
|
-
this.rows = this.rows.map((c) => {
|
|
2411
|
-
if (c.field === cell.field) {
|
|
2412
|
-
return { ...c, currencyType };
|
|
2413
|
-
}
|
|
2414
|
-
return c;
|
|
2415
|
-
});
|
|
2416
|
-
this.handleSettingsChanged(this.rows);
|
|
2417
|
-
}
|
|
2418
|
-
setProgressMax(cell, progressMax) {
|
|
2419
|
-
this.rows = this.rows.map((c) => {
|
|
2420
|
-
if (c.field === cell.field) {
|
|
2421
|
-
return { ...c, progressMax };
|
|
2422
|
-
}
|
|
2423
|
-
return c;
|
|
2424
|
-
});
|
|
2425
|
-
this.handleSettingsChanged(this.rows);
|
|
2426
|
-
}
|
|
2427
|
-
setProgressColor(cell, progressColor) {
|
|
2428
|
-
this.rows = this.rows.map((c) => {
|
|
2429
|
-
if (c.field === cell.field) {
|
|
2430
|
-
return { ...c, progressColor };
|
|
2431
|
-
}
|
|
2432
|
-
return c;
|
|
2433
|
-
});
|
|
2434
|
-
this.handleSettingsChanged(this.rows);
|
|
2435
|
-
}
|
|
2436
|
-
setCellHeaderName(cell, headerName) {
|
|
2437
|
-
this.rows = this.rows.map((c) => {
|
|
2438
|
-
if (c.field === cell.field) {
|
|
2439
|
-
return { ...c, headerName };
|
|
2440
|
-
}
|
|
2441
|
-
return c;
|
|
2442
|
-
});
|
|
2443
|
-
this.handleSettingsChanged(this.rows);
|
|
2444
|
-
}
|
|
2445
|
-
setCellValue(cell, value) {
|
|
2446
|
-
// Update the cell in the rows array
|
|
2447
|
-
this.rows = this.rows.map((c) => {
|
|
2448
|
-
if (c.field === cell.field) {
|
|
2449
|
-
return { ...c, value };
|
|
2450
|
-
}
|
|
2451
|
-
return c;
|
|
2452
|
-
});
|
|
2453
|
-
this.handleSettingsChanged(this.rows);
|
|
2454
|
-
}
|
|
2455
|
-
removeCellFromRows(field) {
|
|
2456
|
-
this.destroySortables();
|
|
2457
|
-
const updatedRows = this.rows.filter((c) => c.field !== field);
|
|
2458
|
-
this.rows = [];
|
|
2459
|
-
this.updateComplete.then(() => {
|
|
2460
|
-
this.rows = [...updatedRows];
|
|
2461
|
-
this.initSortable();
|
|
2462
|
-
this.handleSettingsChanged(this.rows);
|
|
2463
|
-
});
|
|
2464
|
-
}
|
|
2465
|
-
closePopover() {
|
|
2466
|
-
this.isOpen = false;
|
|
2467
|
-
}
|
|
2468
|
-
toggleCustomPopover() {
|
|
2469
|
-
this.isOpen = !this.isOpen;
|
|
2470
|
-
if (this.isOpen) {
|
|
2471
|
-
this.updateComplete.then(() => {
|
|
2472
|
-
setTimeout(() => {
|
|
2473
|
-
const input = this.shadowRoot?.querySelector('#variable-filter-input') ||
|
|
2474
|
-
document.querySelector('#variable-filter-input');
|
|
2475
|
-
input?.focus();
|
|
2476
|
-
}, 100);
|
|
2477
|
-
});
|
|
2478
|
-
}
|
|
2479
|
-
}
|
|
2480
|
-
get existingFields() {
|
|
2481
|
-
return this.rows.flat().map((cell) => cell.field);
|
|
2482
|
-
}
|
|
2483
|
-
toggleRowCell(key) {
|
|
2484
|
-
const exists = this.rows.some((cell) => cell.field === key);
|
|
2485
|
-
if (exists) {
|
|
2486
|
-
this.removeCellFromRows(key);
|
|
2487
|
-
}
|
|
2488
|
-
else {
|
|
2489
|
-
const raw = this.variables.find((variable) => variable.field === key);
|
|
2490
|
-
if (!raw)
|
|
2491
|
-
return;
|
|
2492
|
-
const newCell = {
|
|
2493
|
-
field: key,
|
|
2494
|
-
type: raw.type,
|
|
2495
|
-
headerName: raw.headerName,
|
|
2496
|
-
value: raw.value,
|
|
2497
|
-
size: { xs: 4, sm: 2, md: 1, lg: 1, xl: 1 },
|
|
2498
|
-
tooltip: raw.tooltip,
|
|
2499
|
-
};
|
|
2500
|
-
const newRows = [...this.rows];
|
|
2501
|
-
newRows.push(newCell);
|
|
2502
|
-
this.rows = newRows;
|
|
2503
|
-
this.handleSettingsChanged(newRows);
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
replaceDynamicVariables(template) {
|
|
2507
|
-
// Replace {variableName} patterns with actual variable values
|
|
2508
|
-
return template.replace(/\{([^}]+)\}/g, (match, variableName) => {
|
|
2509
|
-
const variableValue = this.getVariableValue(variableName.trim());
|
|
2510
|
-
return String(variableValue || '');
|
|
2511
|
-
});
|
|
2512
|
-
}
|
|
2513
|
-
getLinkUrl(cell) {
|
|
2514
|
-
const href = cell.href || '';
|
|
2515
|
-
// Check if href contains ${variable} patterns
|
|
2516
|
-
if (href.includes('{')) {
|
|
2517
|
-
// Replace ${variableName} patterns with actual values
|
|
2518
|
-
return `${this.hostURL}/${this.replaceDynamicVariables(href)}`;
|
|
2519
|
-
}
|
|
2520
|
-
// Return static href as-is
|
|
2521
|
-
return href;
|
|
2522
|
-
}
|
|
2523
|
-
formatDisplayValue(rawValue) {
|
|
2524
|
-
if (rawValue === null || rawValue === undefined)
|
|
2525
|
-
return '';
|
|
2526
|
-
if (typeof rawValue === 'string') {
|
|
2527
|
-
// Handle string representations of arrays, e.g. "[Finance, Legal, HR]"
|
|
2528
|
-
if (rawValue.startsWith('[') && rawValue.endsWith(']')) {
|
|
2529
|
-
const inner = rawValue.slice(1, -1).trim();
|
|
2530
|
-
if (inner.length > 0) {
|
|
2531
|
-
return inner.split(',').map((s) => s.trim()).filter((s) => s !== '').join(', ');
|
|
2532
|
-
}
|
|
2533
|
-
return '';
|
|
2534
|
-
}
|
|
2535
|
-
return rawValue;
|
|
2536
|
-
}
|
|
2537
|
-
if (Array.isArray(rawValue)) {
|
|
2538
|
-
return rawValue
|
|
2539
|
-
.map((v) => this.formatDisplayValue(v))
|
|
2540
|
-
.filter((v) => v !== '')
|
|
2541
|
-
.join(', ');
|
|
2542
|
-
}
|
|
2543
|
-
if (typeof rawValue === 'object') {
|
|
2544
|
-
const entries = Object.entries(rawValue)
|
|
2545
|
-
.map(([key, v]) => {
|
|
2546
|
-
const val = this.formatDisplayValue(v);
|
|
2547
|
-
return val ? `${key}: ${val}` : '';
|
|
2548
|
-
})
|
|
2549
|
-
.filter((entry) => entry !== '');
|
|
2550
|
-
return entries.length > 0 ? entries.join(' | ') : '';
|
|
2551
|
-
}
|
|
2552
|
-
return String(rawValue);
|
|
2553
|
-
}
|
|
2554
|
-
getAllDataGridRefs() {
|
|
2555
|
-
if (this.dataGridRefs?.length)
|
|
2556
|
-
return this.dataGridRefs;
|
|
2557
|
-
if (this.dataGridRef)
|
|
2558
|
-
return [{ id: '_default', label: 'DataGrid', ref: this.dataGridRef }];
|
|
2559
|
-
return [];
|
|
2560
|
-
}
|
|
2561
|
-
hasAnyDataGridRef() {
|
|
2562
|
-
return this.getAllDataGridRefs().length > 0;
|
|
2563
|
-
}
|
|
2564
|
-
getDataGridBySource(source) {
|
|
2565
|
-
const refs = this.getAllDataGridRefs();
|
|
2566
|
-
if (!source) {
|
|
2567
|
-
return refs.length === 1 ? refs[0].ref : null;
|
|
2568
|
-
}
|
|
2569
|
-
const entry = refs.find((r) => r.id === source);
|
|
2570
|
-
return entry?.ref || null;
|
|
2571
|
-
}
|
|
2572
|
-
resolveExpertOperand(type, value, source, aggregation = 'sum') {
|
|
2573
|
-
if (!value)
|
|
2574
|
-
return null;
|
|
2575
|
-
if (type === 'column') {
|
|
2576
|
-
const grid = this.getDataGridBySource(source || '');
|
|
2577
|
-
if (!grid)
|
|
2578
|
-
return null;
|
|
2579
|
-
const rows = grid.row || [];
|
|
2580
|
-
const values = rows.map((row) => parseFloat(row[value])).filter((v) => !isNaN(v));
|
|
2581
|
-
if (values.length === 0)
|
|
2582
|
-
return 0;
|
|
2583
|
-
switch (aggregation) {
|
|
2584
|
-
case 'sum':
|
|
2585
|
-
return values.reduce((acc, v) => acc + v, 0);
|
|
2586
|
-
case 'avg':
|
|
2587
|
-
return values.reduce((acc, v) => acc + v, 0) / values.length;
|
|
2588
|
-
case 'min':
|
|
2589
|
-
return Math.min(...values);
|
|
2590
|
-
case 'max':
|
|
2591
|
-
return Math.max(...values);
|
|
2592
|
-
case 'count':
|
|
2593
|
-
return values.length;
|
|
2594
|
-
default:
|
|
2595
|
-
return values.reduce((acc, v) => acc + v, 0);
|
|
2596
|
-
}
|
|
2597
|
-
}
|
|
2598
|
-
// type === 'variable'
|
|
2599
|
-
// Use pre-computed expert value if available, otherwise fall back to raw value
|
|
2600
|
-
if (this._resolvedExpertValues.has(value)) {
|
|
2601
|
-
return this._resolvedExpertValues.get(value);
|
|
2602
|
-
}
|
|
2603
|
-
const variable = [...this.rows, ...this.variables].find((v) => v.field === value);
|
|
2604
|
-
if (!variable)
|
|
2605
|
-
return null;
|
|
2606
|
-
const parsed = parseFloat(String(variable.value || 0));
|
|
2607
|
-
return isNaN(parsed) ? 0 : parsed;
|
|
2608
|
-
}
|
|
2609
|
-
computeExpertValue(cell) {
|
|
2610
|
-
const config = cell.expertMode;
|
|
2611
|
-
if (!config?.enabled)
|
|
2612
|
-
return null;
|
|
2613
|
-
const leftType = config.leftType || 'column';
|
|
2614
|
-
const rightType = config.rightType || 'variable';
|
|
2615
|
-
const left = this.resolveExpertOperand(leftType, config.leftValue || config.sourceColumn || '', config.leftSource, config.leftAggregation || 'sum');
|
|
2616
|
-
if (left === null)
|
|
2617
|
-
return null;
|
|
2618
|
-
if (config.operation === 'none')
|
|
2619
|
-
return left;
|
|
2620
|
-
const rightValue = config.rightValue || config.variableField || '';
|
|
2621
|
-
if (!rightValue)
|
|
2622
|
-
return left;
|
|
2623
|
-
const right = this.resolveExpertOperand(rightType, rightValue, config.rightSource, config.rightAggregation || 'sum');
|
|
2624
|
-
if (right === null)
|
|
2625
|
-
return left;
|
|
2626
|
-
switch (config.operation) {
|
|
2627
|
-
case '+':
|
|
2628
|
-
return left + right;
|
|
2629
|
-
case '-':
|
|
2630
|
-
return left - right;
|
|
2631
|
-
case '*':
|
|
2632
|
-
return left * right;
|
|
2633
|
-
case '/':
|
|
2634
|
-
return right !== 0 ? left / right : null;
|
|
2635
|
-
default:
|
|
2636
|
-
return left;
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
precomputeExpertValues() {
|
|
2640
|
-
this._resolvedExpertValues.clear();
|
|
2641
|
-
const maxPasses = 3;
|
|
2642
|
-
for (let pass = 0; pass < maxPasses; pass++) {
|
|
2643
|
-
let changed = false;
|
|
2644
|
-
for (const cell of this.rows) {
|
|
2645
|
-
const expertValue = this.computeExpertValue(cell);
|
|
2646
|
-
if (expertValue !== null) {
|
|
2647
|
-
const prev = this._resolvedExpertValues.get(cell.field);
|
|
2648
|
-
if (prev !== expertValue) {
|
|
2649
|
-
this._resolvedExpertValues.set(cell.field, expertValue);
|
|
2650
|
-
changed = true;
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
}
|
|
2654
|
-
if (!changed)
|
|
2655
|
-
break;
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
getCellWithExpertValue(cell) {
|
|
2659
|
-
const expertValue = this._resolvedExpertValues.get(cell.field);
|
|
2660
|
-
if (expertValue !== undefined) {
|
|
2661
|
-
return { ...cell, value: expertValue };
|
|
2662
|
-
}
|
|
2663
|
-
return cell;
|
|
2664
|
-
}
|
|
2665
|
-
openExpertModeModal(cell) {
|
|
2666
|
-
this.closeSettingsPopper();
|
|
2667
|
-
this.expertModeCell = cell;
|
|
2668
|
-
const existing = cell.expertMode;
|
|
2669
|
-
const defaultSource = this.getAllDataGridRefs().length === 1 ? this.getAllDataGridRefs()[0].id : '';
|
|
2670
|
-
// Load headerName mutations from cell
|
|
2671
|
-
const mutations = {};
|
|
2672
|
-
const supportedLangs = ['cs', 'en', 'de', 'sk', 'pl', 'hu', 'fr', 'it', 'es', 'sr'];
|
|
2673
|
-
supportedLangs.forEach((lang) => {
|
|
2674
|
-
const val = cell[`headerName_${lang}`];
|
|
2675
|
-
if (val)
|
|
2676
|
-
mutations[lang] = val;
|
|
2677
|
-
});
|
|
2678
|
-
this.expertModeConfig = {
|
|
2679
|
-
enabled: existing?.enabled || false,
|
|
2680
|
-
leftType: existing?.leftType || 'column',
|
|
2681
|
-
leftSource: existing?.leftSource || defaultSource,
|
|
2682
|
-
leftValue: existing?.leftValue || existing?.sourceColumn || '',
|
|
2683
|
-
leftAggregation: existing?.leftAggregation || 'sum',
|
|
2684
|
-
operation: existing?.operation || 'none',
|
|
2685
|
-
rightType: existing?.rightType || 'variable',
|
|
2686
|
-
rightSource: existing?.rightSource || defaultSource,
|
|
2687
|
-
rightValue: existing?.rightValue || existing?.variableField || '',
|
|
2688
|
-
rightAggregation: existing?.rightAggregation || 'sum',
|
|
2689
|
-
headerName: cell.headerName || '',
|
|
2690
|
-
headerNameMutations: mutations,
|
|
2691
|
-
pmEnabled: existing?.pmEnabled || false,
|
|
2692
|
-
pmLeftType: existing?.pmLeftType || 'column',
|
|
2693
|
-
pmLeftSource: existing?.pmLeftSource || defaultSource,
|
|
2694
|
-
pmLeftValue: existing?.pmLeftValue || '',
|
|
2695
|
-
pmLeftAggregation: existing?.pmLeftAggregation || 'sum',
|
|
2696
|
-
pmOperation: existing?.pmOperation || 'none',
|
|
2697
|
-
pmRightType: existing?.pmRightType || 'variable',
|
|
2698
|
-
pmRightSource: existing?.pmRightSource || defaultSource,
|
|
2699
|
-
pmRightValue: existing?.pmRightValue || '',
|
|
2700
|
-
pmRightAggregation: existing?.pmRightAggregation || 'sum',
|
|
2701
|
-
};
|
|
2702
|
-
this.expertModeModalOpen = true;
|
|
2703
|
-
}
|
|
2704
|
-
saveExpertMode() {
|
|
2705
|
-
if (!this.expertModeCell)
|
|
2706
|
-
return;
|
|
2707
|
-
this.rows = this.rows.map((c) => {
|
|
2708
|
-
if (c.field === this.expertModeCell.field) {
|
|
2709
|
-
const { headerName, headerNameMutations, ...expertModeData } = this.expertModeConfig;
|
|
2710
|
-
const updated = {
|
|
2711
|
-
...c,
|
|
2712
|
-
expertMode: expertModeData,
|
|
2713
|
-
headerName: headerName,
|
|
2714
|
-
};
|
|
2715
|
-
// Write language mutations
|
|
2716
|
-
Object.entries(headerNameMutations).forEach(([lang, val]) => {
|
|
2717
|
-
updated[`headerName_${lang}`] = val;
|
|
2718
|
-
});
|
|
2719
|
-
// Remove empty mutations
|
|
2720
|
-
const supportedLangs = ['cs', 'en', 'de', 'sk', 'pl', 'hu', 'fr', 'it', 'es', 'sr'];
|
|
2721
|
-
supportedLangs.forEach((lang) => {
|
|
2722
|
-
if (!headerNameMutations[lang]) {
|
|
2723
|
-
delete updated[`headerName_${lang}`];
|
|
2724
|
-
}
|
|
2725
|
-
});
|
|
2726
|
-
return updated;
|
|
2727
|
-
}
|
|
2728
|
-
return c;
|
|
2729
|
-
});
|
|
2730
|
-
this.handleSettingsChanged(this.rows);
|
|
2731
|
-
this.expertModeModalOpen = false;
|
|
2732
|
-
this.expertModeCell = null;
|
|
2733
|
-
}
|
|
2734
|
-
getGridColumnOptions(source) {
|
|
2735
|
-
const grid = this.getDataGridBySource(source || '');
|
|
2736
|
-
if (!grid?.columns)
|
|
2737
|
-
return [];
|
|
2738
|
-
return grid.columns
|
|
2739
|
-
.filter((col) => {
|
|
2740
|
-
const type = col.type;
|
|
2741
|
-
return type === 'number' || type === 'currency' || type === 'range' || type === 'numberRange';
|
|
2742
|
-
})
|
|
2743
|
-
.map((col) => ({
|
|
2744
|
-
label: col.headerName || col.field,
|
|
2745
|
-
value: col.field,
|
|
2746
|
-
}));
|
|
2747
|
-
}
|
|
2748
|
-
getGridSourceOptions() {
|
|
2749
|
-
return this.getAllDataGridRefs().map((entry) => ({
|
|
2750
|
-
label: entry.label,
|
|
2751
|
-
value: entry.id,
|
|
2752
|
-
}));
|
|
2753
|
-
}
|
|
2754
|
-
getExpertVariableOptions() {
|
|
2755
|
-
const numericTypes = ['currency', 'number'];
|
|
2756
|
-
const variables = [];
|
|
2757
|
-
this.rows.forEach((cell) => {
|
|
2758
|
-
if (cell.type && numericTypes.includes(cell.type)) {
|
|
2759
|
-
variables.push({
|
|
2760
|
-
label: cell.headerName || cell.field,
|
|
2761
|
-
value: cell.field,
|
|
2762
|
-
});
|
|
2763
|
-
}
|
|
2764
|
-
});
|
|
2765
|
-
const existingFields = this.rows.map((cell) => cell.field);
|
|
2766
|
-
this.variables.forEach((variable) => {
|
|
2767
|
-
if (!existingFields.includes(variable.field) && variable.type && numericTypes.includes(variable.type)) {
|
|
2768
|
-
variables.push({
|
|
2769
|
-
label: variable.headerName || variable.field,
|
|
2770
|
-
value: variable.field,
|
|
2771
|
-
});
|
|
2772
|
-
}
|
|
2773
|
-
});
|
|
2774
|
-
return variables.sort((a, b) => a.label.localeCompare(b.label));
|
|
2775
|
-
}
|
|
2776
|
-
getExpertModePreviewValue() {
|
|
2777
|
-
if (!this.expertModeConfig.enabled || !this.expertModeConfig.leftValue) {
|
|
2778
|
-
return '-';
|
|
2779
|
-
}
|
|
2780
|
-
const tempCell = { field: '__preview__', expertMode: { ...this.expertModeConfig } };
|
|
2781
|
-
const value = this.computeExpertValue(tempCell);
|
|
2782
|
-
if (value === null)
|
|
2783
|
-
return 'N/A';
|
|
2784
|
-
return formatDecimal(value, { locale: this.getLocaleLang(), numberOfDecimal: 2 }) || String(value);
|
|
2785
|
-
}
|
|
2786
|
-
computeProgressMaxExpertValue(config) {
|
|
2787
|
-
if (!config?.pmEnabled)
|
|
2788
|
-
return null;
|
|
2789
|
-
const leftType = config.pmLeftType || 'column';
|
|
2790
|
-
const rightType = config.pmRightType || 'variable';
|
|
2791
|
-
const left = this.resolveExpertOperand(leftType, config.pmLeftValue || '', config.pmLeftSource, config.pmLeftAggregation || 'sum');
|
|
2792
|
-
if (left === null)
|
|
2793
|
-
return null;
|
|
2794
|
-
if (config.pmOperation === 'none')
|
|
2795
|
-
return left;
|
|
2796
|
-
const rightValue = config.pmRightValue || '';
|
|
2797
|
-
if (!rightValue)
|
|
2798
|
-
return left;
|
|
2799
|
-
const right = this.resolveExpertOperand(rightType, rightValue, config.pmRightSource, config.pmRightAggregation || 'sum');
|
|
2800
|
-
if (right === null)
|
|
2801
|
-
return left;
|
|
2802
|
-
switch (config.pmOperation) {
|
|
2803
|
-
case '+': return left + right;
|
|
2804
|
-
case '-': return left - right;
|
|
2805
|
-
case '*': return left * right;
|
|
2806
|
-
case '/': return right !== 0 ? left / right : null;
|
|
2807
|
-
default: return left;
|
|
2808
|
-
}
|
|
2809
|
-
}
|
|
2810
|
-
getProgressMaxPreviewValue() {
|
|
2811
|
-
if (!this.expertModeConfig.pmEnabled || !this.expertModeConfig.pmLeftValue) {
|
|
2812
|
-
return '-';
|
|
2813
|
-
}
|
|
2814
|
-
const value = this.computeProgressMaxExpertValue(this.expertModeConfig);
|
|
2815
|
-
if (value === null)
|
|
2816
|
-
return 'N/A';
|
|
2817
|
-
return formatDecimal(value, { locale: this.getLocaleLang(), numberOfDecimal: 2 }) || String(value);
|
|
2818
|
-
}
|
|
2819
|
-
getExpertOperandLabel(type, value, source, aggregation = 'sum') {
|
|
2820
|
-
if (!value)
|
|
2821
|
-
return '?';
|
|
2822
|
-
if (type === 'column') {
|
|
2823
|
-
const refs = this.getAllDataGridRefs();
|
|
2824
|
-
const sourceLabel = refs.length > 1
|
|
2825
|
-
? refs.find((r) => r.id === source)?.label || ''
|
|
2826
|
-
: '';
|
|
2827
|
-
const aggLabel = (aggregation || 'sum').toUpperCase();
|
|
2828
|
-
return sourceLabel ? `${aggLabel}(${sourceLabel}.${value})` : `${aggLabel}(${value})`;
|
|
2829
|
-
}
|
|
2830
|
-
const variable = [...this.rows, ...this.variables].find((v) => v.field === value);
|
|
2831
|
-
return variable?.headerName || value;
|
|
2832
|
-
}
|
|
2833
|
-
renderExpertOperandSelector(side, label, tooltipText, prefix = '') {
|
|
2834
|
-
const pre = prefix || '';
|
|
2835
|
-
const typeKey = (pre + (side === 'left' ? 'LeftType' : 'RightType'));
|
|
2836
|
-
const sourceKey = (pre + (side === 'left' ? 'LeftSource' : 'RightSource'));
|
|
2837
|
-
const valueKey = (pre + (side === 'left' ? 'LeftValue' : 'RightValue'));
|
|
2838
|
-
const aggregationKey = (pre + (side === 'left' ? 'LeftAggregation' : 'RightAggregation'));
|
|
2839
|
-
const enabledKey = (pre ? pre + 'Enabled' : 'enabled');
|
|
2840
|
-
// For non-prefixed keys (default), use original camelCase: leftType, rightType, etc.
|
|
2841
|
-
const typeKeyFinal = pre ? typeKey : (side === 'left' ? 'leftType' : 'rightType');
|
|
2842
|
-
const sourceKeyFinal = pre ? sourceKey : (side === 'left' ? 'leftSource' : 'rightSource');
|
|
2843
|
-
const valueKeyFinal = pre ? valueKey : (side === 'left' ? 'leftValue' : 'rightValue');
|
|
2844
|
-
const aggregationKeyFinal = pre ? aggregationKey : (side === 'left' ? 'leftAggregation' : 'rightAggregation');
|
|
2845
|
-
const currentType = this.expertModeConfig[typeKeyFinal];
|
|
2846
|
-
const currentSource = this.expertModeConfig[sourceKeyFinal];
|
|
2847
|
-
const currentValue = this.expertModeConfig[valueKeyFinal];
|
|
2848
|
-
const currentAggregation = this.expertModeConfig[aggregationKeyFinal];
|
|
2849
|
-
const isEnabled = !!this.expertModeConfig[enabledKey];
|
|
2850
|
-
const typeOptions = [
|
|
2851
|
-
{ label: msg('Tabulka'), value: 'column' },
|
|
2852
|
-
{ label: msg('Proměnná'), value: 'variable' },
|
|
2853
|
-
];
|
|
2854
|
-
const aggregationOptions = [
|
|
2855
|
-
{ label: 'SUM', value: 'sum' },
|
|
2856
|
-
{ label: 'AVG', value: 'avg' },
|
|
2857
|
-
{ label: 'MIN', value: 'min' },
|
|
2858
|
-
{ label: 'MAX', value: 'max' },
|
|
2859
|
-
{ label: 'COUNT', value: 'count' },
|
|
2860
|
-
];
|
|
2861
|
-
const gridSourceOptions = this.getGridSourceOptions();
|
|
2862
|
-
const showSourceSelector = currentType === 'column' && gridSourceOptions.length >= 1;
|
|
2863
|
-
const valueOptions = currentType === 'column'
|
|
2864
|
-
? this.getGridColumnOptions(currentSource)
|
|
2865
|
-
: this.getExpertVariableOptions();
|
|
2866
|
-
return html `
|
|
2867
|
-
<div style="flex: 1; display: flex; flex-direction: column; gap: 4px;">
|
|
2868
|
-
<lit-label .label="${label}" .tooltip="${tooltipText}"></lit-label>
|
|
2869
|
-
<div style="display: flex; flex-direction: column; gap: 4px;">
|
|
2870
|
-
<lit-select
|
|
2871
|
-
.options=${typeOptions}
|
|
2872
|
-
.value=${currentType}
|
|
2873
|
-
.placeholder=${msg('Vyberte typ')}
|
|
2874
|
-
.disabled=${!isEnabled}
|
|
2875
|
-
.onChange=${(value) => {
|
|
2876
|
-
const val = (Array.isArray(value) ? value[0] : value);
|
|
2877
|
-
this.expertModeConfig = {
|
|
2878
|
-
...this.expertModeConfig,
|
|
2879
|
-
[typeKeyFinal]: val || 'column',
|
|
2880
|
-
[valueKeyFinal]: '',
|
|
2881
|
-
};
|
|
2882
|
-
this.requestUpdate();
|
|
2883
|
-
}}
|
|
2884
|
-
></lit-select>
|
|
2885
|
-
${currentType === 'column' && gridSourceOptions.length === 0
|
|
2886
|
-
? html `
|
|
2887
|
-
<div style="
|
|
2888
|
-
display: flex;
|
|
2889
|
-
align-items: center;
|
|
2890
|
-
gap: 0.375rem;
|
|
2891
|
-
padding: 0.5rem 0.75rem;
|
|
2892
|
-
background: var(--color-info-light, #e0f2fe);
|
|
2893
|
-
color: var(--color-info-dark, #0369a1);
|
|
2894
|
-
border-radius: var(--border-radius-small, 8px);
|
|
2895
|
-
font-size: 0.75rem;
|
|
2896
|
-
font-weight: 500;
|
|
2897
|
-
">
|
|
2898
|
-
<lit-icon name="info" size="16"></lit-icon>
|
|
2899
|
-
${msg('Pro výpočet z tabulky je nutné přidat tabulku.')}
|
|
2900
|
-
</div>
|
|
2901
|
-
`
|
|
2902
|
-
: html `
|
|
2903
|
-
${showSourceSelector
|
|
2904
|
-
? html `
|
|
2905
|
-
<lit-select
|
|
2906
|
-
.options=${gridSourceOptions}
|
|
2907
|
-
.value=${currentSource}
|
|
2908
|
-
.placeholder=${msg('Vyberte tabulku')}
|
|
2909
|
-
.disabled=${!isEnabled}
|
|
2910
|
-
.onChange=${(value) => {
|
|
2911
|
-
const val = Array.isArray(value) ? value[0] : value;
|
|
2912
|
-
this.expertModeConfig = {
|
|
2913
|
-
...this.expertModeConfig,
|
|
2914
|
-
[sourceKeyFinal]: val || '',
|
|
2915
|
-
[valueKeyFinal]: '',
|
|
2916
|
-
};
|
|
2917
|
-
this.requestUpdate();
|
|
2918
|
-
}}
|
|
2919
|
-
></lit-select>
|
|
2920
|
-
`
|
|
2921
|
-
: ''}
|
|
2922
|
-
<lit-select
|
|
2923
|
-
.options=${valueOptions}
|
|
2924
|
-
.value=${currentValue}
|
|
2925
|
-
.placeholder=${currentType === 'column' ? msg('Vyberte sloupec') : msg('Vyberte proměnnou')}
|
|
2926
|
-
.disabled=${!isEnabled}
|
|
2927
|
-
.onChange=${(value) => {
|
|
2928
|
-
const val = Array.isArray(value) ? value[0] : value;
|
|
2929
|
-
this.expertModeConfig = {
|
|
2930
|
-
...this.expertModeConfig,
|
|
2931
|
-
[valueKeyFinal]: val || '',
|
|
2932
|
-
};
|
|
2933
|
-
this.requestUpdate();
|
|
2934
|
-
}}
|
|
2935
|
-
></lit-select>
|
|
2936
|
-
${currentType === 'column'
|
|
2937
|
-
? html `
|
|
2938
|
-
<lit-select
|
|
2939
|
-
.options=${aggregationOptions}
|
|
2940
|
-
.value=${currentAggregation}
|
|
2941
|
-
.placeholder=${msg('Vyberte agregaci')}
|
|
2942
|
-
.disabled=${!isEnabled}
|
|
2943
|
-
.onChange=${(value) => {
|
|
2944
|
-
const val = Array.isArray(value) ? value[0] : value;
|
|
2945
|
-
this.expertModeConfig = {
|
|
2946
|
-
...this.expertModeConfig,
|
|
2947
|
-
[aggregationKeyFinal]: val || 'sum',
|
|
2948
|
-
};
|
|
2949
|
-
this.requestUpdate();
|
|
2950
|
-
}}
|
|
2951
|
-
></lit-select>
|
|
2952
|
-
`
|
|
2953
|
-
: ''}
|
|
2954
|
-
`}
|
|
2955
|
-
</div>
|
|
2956
|
-
</div>
|
|
2957
|
-
`;
|
|
2958
|
-
}
|
|
2959
|
-
renderExpertModeModal() {
|
|
2960
|
-
const operationOptions = [
|
|
2961
|
-
{ label: msg('Žádná'), value: 'none' },
|
|
2962
|
-
{ label: '+ (' + msg('Sčítání') + ')', value: '+' },
|
|
2963
|
-
{ label: '- (' + msg('Odčítání') + ')', value: '-' },
|
|
2964
|
-
{ label: '× (' + msg('Násobení') + ')', value: '*' },
|
|
2965
|
-
{ label: '÷ (' + msg('Dělení') + ')', value: '/' },
|
|
2966
|
-
];
|
|
2967
|
-
const isNoOperation = this.expertModeConfig.operation === 'none';
|
|
2968
|
-
const closeModal = () => {
|
|
2969
|
-
this.expertModeModalOpen = false;
|
|
2970
|
-
this.expertModeCell = null;
|
|
2971
|
-
};
|
|
2972
|
-
return html `
|
|
2973
|
-
<lit-modal
|
|
2974
|
-
.open=${this.expertModeModalOpen}
|
|
2975
|
-
.onClose=${closeModal}
|
|
2976
|
-
.closeOnOutsideClick=${false}
|
|
2977
|
-
style="min-width: 60vw;"
|
|
2978
|
-
>
|
|
2979
|
-
<lit-modal-header
|
|
2980
|
-
style="display: flex; align-items: center; justify-content: space-between; color: var(--text-secondary, #777);"
|
|
2981
|
-
>
|
|
2982
|
-
${msg('Expertní mód')} - ${this.expertModeCell?.headerName || this.expertModeCell?.field || ''}
|
|
2983
|
-
<lit-icon-button
|
|
2984
|
-
.icon="${'close'}"
|
|
2985
|
-
variant="text"
|
|
2986
|
-
color="secondary"
|
|
2987
|
-
size="${'small'}"
|
|
2988
|
-
@click=${closeModal}
|
|
2989
|
-
></lit-icon-button>
|
|
2990
|
-
</lit-modal-header>
|
|
2991
|
-
<lit-modal-body>
|
|
2992
|
-
<div style="height: 400px;">
|
|
2993
|
-
<lit-tabs-overview
|
|
2994
|
-
.tabs=${[
|
|
2995
|
-
...(this.expertModeCell?.type === 'progress'
|
|
2996
|
-
? [{ id: 'progressMax', label: { default: msg('Hodnota 100%') }, icon: 'accomplish' }]
|
|
2997
|
-
: []),
|
|
2998
|
-
...(this.expertModeCell?.type === 'number' || this.expertModeCell?.type === 'currency' || this.expertModeCell?.type === 'progress'
|
|
2999
|
-
? [{ id: 'calculation', label: { default: msg('Výpočet') }, icon: 'calculator' }]
|
|
3000
|
-
: []),
|
|
3001
|
-
...(this.expertModeCell?.field.startsWith('custom_cell_')
|
|
3002
|
-
? [{ id: 'header', label: { default: msg('Název buňky') }, icon: 'lang' }]
|
|
3003
|
-
: []),
|
|
3004
|
-
]}
|
|
3005
|
-
.userLang=${this.userLang}
|
|
3006
|
-
>
|
|
3007
|
-
<!-- Tab: Výpočet (Calculation) -->
|
|
3008
|
-
<div slot="calculation" style="display: flex; flex-direction: column; gap: 1rem;">
|
|
3009
|
-
<lit-toggle
|
|
3010
|
-
.label="${msg('Povolit expertní výpočet')}"
|
|
3011
|
-
.tooltip="${msg('Vypočítá hodnotu na základě vybraných sloupců/proměnných a zvolené matematické operace.')}"
|
|
3012
|
-
.checked=${this.expertModeConfig.enabled}
|
|
3013
|
-
@change=${(e) => {
|
|
3014
|
-
this.expertModeConfig = {
|
|
3015
|
-
...this.expertModeConfig,
|
|
3016
|
-
enabled: e.detail,
|
|
3017
|
-
};
|
|
3018
|
-
}}
|
|
3019
|
-
></lit-toggle>
|
|
3020
|
-
|
|
3021
|
-
${this.expertModeConfig.enabled ? html `
|
|
3022
|
-
<div style="display: flex; flex-direction: row; gap: 1rem; align-items: flex-start;">
|
|
3023
|
-
${this.renderExpertOperandSelector('left', msg('Levý operand'), msg('Vyberte typ a hodnotu levého operandu. Sloupec vypočítá agregaci (SUM, AVG, MIN, MAX, COUNT) všech hodnot, proměnná použije hodnotu vybrané buňky.'))}
|
|
3024
|
-
|
|
3025
|
-
<div style="flex: 0 0 auto; display: flex; flex-direction: column; gap: 4px; min-width: 120px;">
|
|
3026
|
-
<lit-label .label="${msg('Operace')}" .tooltip="${msg('Matematická operace mezi levým a pravým operandem. Zvolte Žádná pro zobrazení pouze levého operandu.')}"></lit-label>
|
|
3027
|
-
<lit-select
|
|
3028
|
-
.options=${operationOptions}
|
|
3029
|
-
.value=${this.expertModeConfig.operation}
|
|
3030
|
-
.placeholder=${msg('Vyberte operaci')}
|
|
3031
|
-
.onChange=${(value) => {
|
|
3032
|
-
const val = Array.isArray(value) ? value[0] : value;
|
|
3033
|
-
this.expertModeConfig = {
|
|
3034
|
-
...this.expertModeConfig,
|
|
3035
|
-
operation: val || '+',
|
|
3036
|
-
};
|
|
3037
|
-
this.requestUpdate();
|
|
3038
|
-
}}
|
|
3039
|
-
></lit-select>
|
|
3040
|
-
</div>
|
|
3041
|
-
|
|
3042
|
-
${!isNoOperation ? this.renderExpertOperandSelector('right', msg('Pravý operand'), msg('Vyberte typ a hodnotu pravého operandu. Sloupec vypočítá agregaci (SUM, AVG, MIN, MAX, COUNT) všech hodnot, proměnná použije hodnotu vybrané buňky.')) : ''}
|
|
3043
|
-
</div>
|
|
3044
|
-
|
|
3045
|
-
<div
|
|
3046
|
-
style="
|
|
3047
|
-
padding: 0.75rem;
|
|
3048
|
-
background: var(--background-default, #f5f5f5);
|
|
3049
|
-
border-radius: var(--border-radius-small, 8px);
|
|
3050
|
-
font-size: 0.8125rem;
|
|
3051
|
-
color: var(--text-secondary, #5d6371);
|
|
3052
|
-
"
|
|
3053
|
-
>
|
|
3054
|
-
<div style="font-weight: 600; margin-bottom: 0.25rem;">${msg('Náhled výpočtu')}</div>
|
|
3055
|
-
<div>
|
|
3056
|
-
${this.getExpertOperandLabel(this.expertModeConfig.leftType, this.expertModeConfig.leftValue, this.expertModeConfig.leftSource, this.expertModeConfig.leftAggregation)}
|
|
3057
|
-
${this.expertModeConfig.operation !== 'none'
|
|
3058
|
-
? html `${this.expertModeConfig.operation} ${this.getExpertOperandLabel(this.expertModeConfig.rightType, this.expertModeConfig.rightValue, this.expertModeConfig.rightSource, this.expertModeConfig.rightAggregation)}`
|
|
3059
|
-
: ''}
|
|
3060
|
-
= <strong style="color: var(--text-primary, #111827);">${this.getExpertModePreviewValue()}</strong>
|
|
3061
|
-
</div>
|
|
3062
|
-
</div>
|
|
3063
|
-
` : ''}
|
|
3064
|
-
</div>
|
|
3065
|
-
|
|
3066
|
-
<!-- Tab: Hodnota 100% (Progress Max) -->
|
|
3067
|
-
${this.expertModeCell?.type === 'progress' ? html `
|
|
3068
|
-
<div slot="progressMax" style="display: flex; flex-direction: column; gap: 1rem;">
|
|
3069
|
-
<lit-toggle
|
|
3070
|
-
.label="${msg('Vypočítat hodnotu 100%')}"
|
|
3071
|
-
.tooltip="${msg('Vypočítá hodnotu pro 100% na základě vybraných sloupců/proměnných a zvolené matematické operace.')}"
|
|
3072
|
-
.checked=${this.expertModeConfig.pmEnabled}
|
|
3073
|
-
@change=${(e) => {
|
|
3074
|
-
this.expertModeConfig = {
|
|
3075
|
-
...this.expertModeConfig,
|
|
3076
|
-
pmEnabled: e.detail,
|
|
3077
|
-
};
|
|
3078
|
-
}}
|
|
3079
|
-
></lit-toggle>
|
|
3080
|
-
|
|
3081
|
-
${this.expertModeConfig.pmEnabled ? html `
|
|
3082
|
-
<div style="display: flex; flex-direction: row; gap: 1rem; align-items: flex-start;">
|
|
3083
|
-
${this.renderExpertOperandSelector('left', msg('Levý operand'), msg('Vyberte typ a hodnotu levého operandu pro výpočet hodnoty 100%.'), 'pm')}
|
|
3084
|
-
|
|
3085
|
-
<div style="flex: 0 0 auto; display: flex; flex-direction: column; gap: 4px; min-width: 120px;">
|
|
3086
|
-
<lit-label .label="${msg('Operace')}" .tooltip="${msg('Matematická operace mezi levým a pravým operandem.')}"></lit-label>
|
|
3087
|
-
<lit-select
|
|
3088
|
-
.options=${operationOptions}
|
|
3089
|
-
.value=${this.expertModeConfig.pmOperation}
|
|
3090
|
-
.placeholder=${msg('Vyberte operaci')}
|
|
3091
|
-
.onChange=${(value) => {
|
|
3092
|
-
const val = Array.isArray(value) ? value[0] : value;
|
|
3093
|
-
this.expertModeConfig = {
|
|
3094
|
-
...this.expertModeConfig,
|
|
3095
|
-
pmOperation: val || 'none',
|
|
3096
|
-
};
|
|
3097
|
-
this.requestUpdate();
|
|
3098
|
-
}}
|
|
3099
|
-
></lit-select>
|
|
3100
|
-
</div>
|
|
3101
|
-
|
|
3102
|
-
${this.expertModeConfig.pmOperation !== 'none' ? this.renderExpertOperandSelector('right', msg('Pravý operand'), msg('Vyberte typ a hodnotu pravého operandu pro výpočet hodnoty 100%.'), 'pm') : ''}
|
|
3103
|
-
</div>
|
|
3104
|
-
|
|
3105
|
-
<div
|
|
3106
|
-
style="
|
|
3107
|
-
padding: 0.75rem;
|
|
3108
|
-
background: var(--background-default, #f5f5f5);
|
|
3109
|
-
border-radius: var(--border-radius-small, 8px);
|
|
3110
|
-
font-size: 0.8125rem;
|
|
3111
|
-
color: var(--text-secondary, #5d6371);
|
|
3112
|
-
"
|
|
3113
|
-
>
|
|
3114
|
-
<div style="font-weight: 600; margin-bottom: 0.25rem;">${msg('Náhled hodnoty 100%')}</div>
|
|
3115
|
-
<div>
|
|
3116
|
-
${this.getExpertOperandLabel(this.expertModeConfig.pmLeftType, this.expertModeConfig.pmLeftValue, this.expertModeConfig.pmLeftSource, this.expertModeConfig.pmLeftAggregation)}
|
|
3117
|
-
${this.expertModeConfig.pmOperation !== 'none'
|
|
3118
|
-
? html `${this.expertModeConfig.pmOperation} ${this.getExpertOperandLabel(this.expertModeConfig.pmRightType, this.expertModeConfig.pmRightValue, this.expertModeConfig.pmRightSource, this.expertModeConfig.pmRightAggregation)}`
|
|
3119
|
-
: ''}
|
|
3120
|
-
= <strong style="color: var(--text-primary, #111827);">${this.getProgressMaxPreviewValue()}</strong>
|
|
3121
|
-
</div>
|
|
3122
|
-
</div>
|
|
3123
|
-
` : ''}
|
|
3124
|
-
</div>
|
|
3125
|
-
` : ''}
|
|
3126
|
-
|
|
3127
|
-
<!-- Tab: Název buňky (Header) -->
|
|
3128
|
-
<div slot="header" style="display: flex; flex-direction: column; gap: 1rem;">
|
|
3129
|
-
<lit-label
|
|
3130
|
-
.label="${msg('Název buňky')}"
|
|
3131
|
-
.tooltip="${msg('Název buňky zobrazený v záhlaví. Můžete nastavit překlad pro různé jazyky.')}"
|
|
3132
|
-
></lit-label>
|
|
3133
|
-
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
|
|
3134
|
-
<lit-text-field
|
|
3135
|
-
.label="${msg('Výchozí název')}"
|
|
3136
|
-
.value=${this.expertModeConfig.headerName}
|
|
3137
|
-
@onChange=${(e) => {
|
|
3138
|
-
this.expertModeConfig = {
|
|
3139
|
-
...this.expertModeConfig,
|
|
3140
|
-
headerName: e.detail,
|
|
3141
|
-
};
|
|
3142
|
-
}}
|
|
3143
|
-
></lit-text-field>
|
|
3144
|
-
|
|
3145
|
-
${(this.allowedLang || []).map((lang) => html `
|
|
3146
|
-
<lit-text-field
|
|
3147
|
-
.label="${msg('Název')} ${lang.toUpperCase()}"
|
|
3148
|
-
.placeholder="${msg('Zadejte název')} ${lang.toUpperCase()}"
|
|
3149
|
-
.value=${this.expertModeConfig.headerNameMutations[lang] || ''}
|
|
3150
|
-
@onChange=${(e) => {
|
|
3151
|
-
this.expertModeConfig = {
|
|
3152
|
-
...this.expertModeConfig,
|
|
3153
|
-
headerNameMutations: {
|
|
3154
|
-
...this.expertModeConfig.headerNameMutations,
|
|
3155
|
-
[lang]: e.detail,
|
|
3156
|
-
},
|
|
3157
|
-
};
|
|
3158
|
-
}}
|
|
3159
|
-
></lit-text-field>
|
|
3160
|
-
`)}
|
|
3161
|
-
</div>
|
|
3162
|
-
</div>
|
|
3163
|
-
</lit-tabs-overview>
|
|
3164
|
-
</div>
|
|
3165
|
-
</lit-modal-body>
|
|
3166
|
-
<lit-modal-footer
|
|
3167
|
-
style="display: flex; flex-direction: row; gap: 0.5rem; justify-content: center;"
|
|
3168
|
-
>
|
|
3169
|
-
<lit-button
|
|
3170
|
-
.label="${msg('Uložit')}"
|
|
3171
|
-
.icon="check"
|
|
3172
|
-
.size="medium"
|
|
3173
|
-
@click=${() => this.saveExpertMode()}
|
|
3174
|
-
></lit-button>
|
|
3175
|
-
<lit-button
|
|
3176
|
-
color="secondary"
|
|
3177
|
-
.label="${msg('Zrušit')}"
|
|
3178
|
-
variant="text"
|
|
3179
|
-
.icon="close"
|
|
3180
|
-
.size="medium"
|
|
3181
|
-
@click=${closeModal}
|
|
3182
|
-
></lit-button>
|
|
3183
|
-
</lit-modal-footer>
|
|
3184
|
-
</lit-modal>
|
|
3185
|
-
`;
|
|
3186
|
-
}
|
|
3187
|
-
resolveCurrencyType(cell) {
|
|
3188
|
-
const currencyType = cell.currencyType || 'CZK';
|
|
3189
|
-
if (currencyType.startsWith('var:')) {
|
|
3190
|
-
const variableField = currencyType.substring(4);
|
|
3191
|
-
const variable = this.variables.find((v) => v.field === variableField)
|
|
3192
|
-
|| this.rows.find((c) => c.field === variableField);
|
|
3193
|
-
const resolved = String(variable?.value || '').toUpperCase();
|
|
3194
|
-
if (LitCaseVariablesTab.SUPPORTED_CURRENCIES.includes(resolved)) {
|
|
3195
|
-
return resolved;
|
|
3196
|
-
}
|
|
3197
|
-
return 'CZK';
|
|
3198
|
-
}
|
|
3199
|
-
return currencyType;
|
|
3200
|
-
}
|
|
3201
|
-
resolveProgressMax(cell) {
|
|
3202
|
-
// 1. If expert mode progressMax computation is enabled, use it
|
|
3203
|
-
const config = cell.expertMode;
|
|
3204
|
-
if (config?.pmEnabled) {
|
|
3205
|
-
const computed = this.computeProgressMaxExpertValue(config);
|
|
3206
|
-
if (computed !== null && computed > 0)
|
|
3207
|
-
return computed;
|
|
3208
|
-
}
|
|
3209
|
-
// 2. Otherwise use static progressMax from tweakpane
|
|
3210
|
-
const staticMax = cell.progressMax;
|
|
3211
|
-
if (typeof staticMax === 'number' && staticMax > 0)
|
|
3212
|
-
return staticMax;
|
|
3213
|
-
return 100;
|
|
3214
|
-
}
|
|
3215
|
-
parseBooleanValue(value) {
|
|
3216
|
-
if (typeof value === 'boolean')
|
|
3217
|
-
return value;
|
|
3218
|
-
if (typeof value === 'string') {
|
|
3219
|
-
const lower = value.toLowerCase().trim();
|
|
3220
|
-
return lower === 'true' || lower === '1' || lower === 'yes' || lower === 'ano';
|
|
3221
|
-
}
|
|
3222
|
-
if (typeof value === 'number')
|
|
3223
|
-
return value !== 0;
|
|
3224
|
-
return !!value;
|
|
3225
|
-
}
|
|
3226
|
-
render() {
|
|
3227
|
-
if (this.hideTabWhen)
|
|
3228
|
-
return null;
|
|
3229
|
-
this.precomputeExpertValues();
|
|
3230
|
-
const filteredKeys = this.variables
|
|
3231
|
-
.map((variable) => variable.field)
|
|
3232
|
-
.filter((key) => {
|
|
3233
|
-
const item = this.variables.find((variable) => variable.field === key);
|
|
3234
|
-
const headerName = item?.headerName || '';
|
|
3235
|
-
return (key.toLowerCase().includes(this.filterText) ||
|
|
3236
|
-
headerName.toLowerCase().includes(this.filterText));
|
|
3237
|
-
});
|
|
3238
|
-
return html `
|
|
3239
|
-
${this.enableSettings
|
|
3240
|
-
? html `
|
|
3241
|
-
<div
|
|
3242
|
-
style="display: flex; gap: 0.5rem; justify-content: right; margin-bottom: 1rem; flex-wrap: wrap;"
|
|
3243
|
-
>
|
|
3244
|
-
<lit-button
|
|
3245
|
-
color="secondary"
|
|
3246
|
-
variant="${'dashed'}"
|
|
3247
|
-
label="${msg('Přiřadit vlastní buňku')}"
|
|
3248
|
-
icon="add"
|
|
3249
|
-
.fullWidth=${this.isMobile}
|
|
3250
|
-
@click="${this.addCustomEmptyCell}"
|
|
3251
|
-
class="add-variable-button"
|
|
3252
|
-
></lit-button>
|
|
3253
|
-
<lit-button
|
|
3254
|
-
color="secondary"
|
|
3255
|
-
variant="${'dashed'}"
|
|
3256
|
-
label="${msg('Přiřadit proměnnou')}"
|
|
3257
|
-
icon="add"
|
|
3258
|
-
.fullWidth=${this.isMobile}
|
|
3259
|
-
@click="${this.toggleCustomPopover}"
|
|
3260
|
-
class="add-variable-button"
|
|
3261
|
-
></lit-button>
|
|
3262
|
-
|
|
3263
|
-
<simple-popper
|
|
3264
|
-
.showing=${this.isOpen}
|
|
3265
|
-
.placement=${'bottom-end'}
|
|
3266
|
-
.manualOpening=${true}
|
|
3267
|
-
.maxWidthAsTarget=${false}
|
|
3268
|
-
.minWidth=${'400px'}
|
|
3269
|
-
.minHeight=${'300px'}
|
|
3270
|
-
.onClose=${() => this.closePopover()}
|
|
3271
|
-
>
|
|
3272
|
-
<div
|
|
3273
|
-
class="popper-input"
|
|
3274
|
-
style="position: sticky; top: 0; z-index: 1;"
|
|
3275
|
-
>
|
|
3276
|
-
<lit-input
|
|
3277
|
-
id="variable-filter-input"
|
|
3278
|
-
.value=${this.filterText}
|
|
3279
|
-
.onInput=${(value) => {
|
|
3280
|
-
this.filterText = value?.toLowerCase?.() || '';
|
|
3281
|
-
}}
|
|
3282
|
-
.onClear=${() => {
|
|
3283
|
-
this.filterText = '';
|
|
3284
|
-
}}
|
|
3285
|
-
placeholder="${msg('Zadejte název proměnné')}"
|
|
3286
|
-
.size=${'small'}
|
|
3287
|
-
></lit-input>
|
|
3288
|
-
</div>
|
|
3289
|
-
<lit-menu tabindex="0">
|
|
3290
|
-
${this.variables
|
|
3291
|
-
.map((variable) => variable.field)
|
|
3292
|
-
.filter((key) => {
|
|
3293
|
-
const item = this.variables.find((variable) => variable.field === key);
|
|
3294
|
-
const headerName = item?.headerName || '';
|
|
3295
|
-
return (key.toLowerCase().includes(this.filterText) ||
|
|
3296
|
-
headerName.toLowerCase().includes(this.filterText));
|
|
3297
|
-
})
|
|
3298
|
-
.sort((a, b) => {
|
|
3299
|
-
const aIsUnderscore = a.startsWith('_');
|
|
3300
|
-
const bIsUnderscore = b.startsWith('_');
|
|
3301
|
-
if (aIsUnderscore && !bIsUnderscore)
|
|
3302
|
-
return 1;
|
|
3303
|
-
if (!aIsUnderscore && bIsUnderscore)
|
|
3304
|
-
return -1;
|
|
3305
|
-
const aItem = this.variables.find((v) => v.field === a);
|
|
3306
|
-
const bItem = this.variables.find((v) => v.field === b);
|
|
3307
|
-
const aName = aItem?.headerName || a;
|
|
3308
|
-
const bName = bItem?.headerName || b;
|
|
3309
|
-
return aName.localeCompare(bName, this.getLocaleLang());
|
|
3310
|
-
})
|
|
3311
|
-
.map((key) => html `
|
|
3312
|
-
<lit-menu-item
|
|
3313
|
-
.onClick=${() => this.toggleRowCell(key)}
|
|
3314
|
-
.isActive=${this.existingFields.includes(key)}
|
|
3315
|
-
>
|
|
3316
|
-
<span class="menu-item--multiple">
|
|
3317
|
-
<lit-checkbox
|
|
3318
|
-
class="cursor"
|
|
3319
|
-
.checked=${this.existingFields.includes(key)}
|
|
3320
|
-
></lit-checkbox>
|
|
3321
|
-
${this.variables.find((variable) => variable.field === key)?.headerName || key}
|
|
3322
|
-
(${key})
|
|
3323
|
-
</span>
|
|
3324
|
-
</lit-menu-item>
|
|
3325
|
-
`)}
|
|
3326
|
-
</lit-menu>
|
|
3327
|
-
|
|
3328
|
-
${isEqual(filteredKeys.length, 0)
|
|
3329
|
-
? html `
|
|
3330
|
-
<div
|
|
3331
|
-
style="display: flex;flex-direction: column; align-items: center; justify-content: center; height: 15.625rem;"
|
|
3332
|
-
>
|
|
3333
|
-
<div style="max-height: 7.125rem; max-width: 7.125rem">
|
|
3334
|
-
<not-found></not-found>
|
|
3335
|
-
</div>
|
|
3336
|
-
${msg('Nenalezeno')}
|
|
3337
|
-
</div>
|
|
3338
|
-
`
|
|
3339
|
-
: null}
|
|
3340
|
-
</simple-popper>
|
|
3341
|
-
</div>
|
|
3342
|
-
`
|
|
3343
|
-
: ''}
|
|
3344
|
-
${this.isLoading
|
|
3345
|
-
? html `<lit-loader></lit-loader>`
|
|
3346
|
-
: this.gridVariables
|
|
3347
|
-
? html ` <div class="grid-container">
|
|
3348
|
-
${repeat(this.rows, (cell, index) => cell.field, (cell) => {
|
|
3349
|
-
const resolvedCell = this.getCellWithExpertValue(cell);
|
|
3350
|
-
const classes = `cell--span4`;
|
|
3351
|
-
return html `
|
|
3352
|
-
<div class="${classes}" data-field="${cell.field}">
|
|
3353
|
-
${this.getInlineCellValue(resolvedCell)}
|
|
3354
|
-
</div>
|
|
3355
|
-
`;
|
|
3356
|
-
})}
|
|
3357
|
-
</div>`
|
|
3358
|
-
: html `
|
|
3359
|
-
<div class="grid-container">
|
|
3360
|
-
${repeat(this.rows, (cell, index) => cell.field, (cell) => {
|
|
3361
|
-
const resolvedCell = this.getCellWithExpertValue(cell);
|
|
3362
|
-
const bpIndex = this.BREAKPOINTS.indexOf(this.currentBreakpoint);
|
|
3363
|
-
const spanSize = this.gridVariables
|
|
3364
|
-
? 4
|
|
3365
|
-
: (this.BREAKPOINTS.slice(0, bpIndex + 1)
|
|
3366
|
-
.reverse()
|
|
3367
|
-
.map((bp) => cell.size?.[bp])
|
|
3368
|
-
.find((s) => s !== undefined) ?? 2);
|
|
3369
|
-
const classes = `cell--span${spanSize} cell ${this.shouldHideCell(cell) ? 'hidden-cell' : ''}`;
|
|
3370
|
-
return html `
|
|
3371
|
-
<div
|
|
3372
|
-
class="${classes}"
|
|
3373
|
-
style="${styleMap(this.computeCellStyles(cell))}"
|
|
3374
|
-
data-field="${cell.field}"
|
|
3375
|
-
>
|
|
3376
|
-
${resolvedCell?.type === 'button'
|
|
3377
|
-
? this.getCellButton(resolvedCell)
|
|
3378
|
-
: resolvedCell.type === 'link'
|
|
3379
|
-
? this.getCellLink(resolvedCell)
|
|
3380
|
-
: resolvedCell.type === 'progress'
|
|
3381
|
-
? this.getCellProgress(resolvedCell)
|
|
3382
|
-
: resolvedCell.type === 'currency'
|
|
3383
|
-
? this.getCellCurrency(resolvedCell)
|
|
3384
|
-
: resolvedCell.type === 'date'
|
|
3385
|
-
? this.getCellDate(resolvedCell)
|
|
3386
|
-
: resolvedCell.type === 'number'
|
|
3387
|
-
? this.getCellNumber(resolvedCell)
|
|
3388
|
-
: resolvedCell.type === 'checkbox'
|
|
3389
|
-
? this.getCellCheckbox(resolvedCell)
|
|
3390
|
-
: this.getCellValue(resolvedCell)}
|
|
3391
|
-
</div>
|
|
3392
|
-
`;
|
|
3393
|
-
})}
|
|
3394
|
-
</div>
|
|
3395
|
-
`}
|
|
3396
|
-
${this.settingsPopperOpen && this.activeSettingsCell
|
|
3397
|
-
? html `
|
|
3398
|
-
<div class="tweakpane-overlay" @click=${this.closeSettingsPopper}>
|
|
3399
|
-
<div class="tweakpane-panel" @click=${(e) => e.stopPropagation()}>
|
|
3400
|
-
${this.renderSettingsContent()}
|
|
3401
|
-
</div>
|
|
3402
|
-
</div>
|
|
3403
|
-
`
|
|
3404
|
-
: ''}
|
|
3405
|
-
${this.renderExpertModeModal()}
|
|
3406
|
-
`;
|
|
3407
|
-
}
|
|
3408
|
-
}
|
|
3409
|
-
LitCaseVariablesTab.VARIANT_CSS_VARS = {
|
|
3410
|
-
default: { var: '--background-paper', fallback: '#9ca3af' },
|
|
3411
|
-
primary: { var: '--color-primary-light', fallback: '#76b703' },
|
|
3412
|
-
secondary: { var: '--color-secondary-light', fallback: '#6b7280' },
|
|
3413
|
-
success: { var: '--color-success-light', fallback: '#22c55e' },
|
|
3414
|
-
warning: { var: '--color-warning-light', fallback: '#f59e0b' },
|
|
3415
|
-
error: { var: '--color-error-light', fallback: '#ef4444' },
|
|
3416
|
-
info: { var: '--color-info-light', fallback: '#3b82f6' },
|
|
3417
|
-
custom: { var: '--color-primary-light', fallback: '#8b5cf6' },
|
|
3418
|
-
ai: { var: '--color-primary-light', fallback: '#a855f7' },
|
|
3419
|
-
};
|
|
3420
|
-
LitCaseVariablesTab.styles = [
|
|
3421
|
-
// styles,
|
|
3422
|
-
css `
|
|
3423
|
-
:host {
|
|
3424
|
-
font-family: 'Inter', sans-serif;
|
|
3425
|
-
}
|
|
3426
|
-
|
|
3427
|
-
.header-cell {
|
|
3428
|
-
min-height: 1.25rem;
|
|
3429
|
-
display: flex;
|
|
3430
|
-
justify-content: space-between;
|
|
3431
|
-
align-items: center;
|
|
3432
|
-
}
|
|
3433
|
-
|
|
3434
|
-
.drag-handle {
|
|
3435
|
-
cursor: grab;
|
|
3436
|
-
opacity: 0.6;
|
|
3437
|
-
transition: opacity 0.2s;
|
|
3438
|
-
}
|
|
3439
|
-
|
|
3440
|
-
.drag-handle:hover {
|
|
3441
|
-
opacity: 1;
|
|
3442
|
-
}
|
|
3443
|
-
|
|
3444
|
-
.grid-container {
|
|
3445
|
-
display: grid;
|
|
3446
|
-
justify-content: start;
|
|
3447
|
-
align-items: start;
|
|
3448
|
-
gap: 0.5rem;
|
|
3449
|
-
border: 1px dashed transparent;
|
|
3450
|
-
border-radius: var(--border-radius-small, 8px);
|
|
3451
|
-
transition: border-color 0.2s;
|
|
3452
|
-
}
|
|
3453
|
-
|
|
3454
|
-
.grid-container.sortable-drag-over {
|
|
3455
|
-
border-color: var(--color-primary-main, #76b703);
|
|
3456
|
-
}
|
|
3457
|
-
|
|
3458
|
-
.process-data-heading {
|
|
3459
|
-
font-size: 0.75rem;
|
|
3460
|
-
color: var(--text-secondary, #5d6371);
|
|
3461
|
-
font-weight: 400 !important;
|
|
3462
|
-
display: flex;
|
|
3463
|
-
gap: 5px;
|
|
3464
|
-
align-items: center;
|
|
3465
|
-
}
|
|
3466
|
-
|
|
3467
|
-
.process-data-value {
|
|
3468
|
-
min-height: 1.25rem;
|
|
3469
|
-
font-size: 0.8125rem;
|
|
3470
|
-
color: var(--text-primary, #111827);
|
|
3471
|
-
margin: 0;
|
|
3472
|
-
font-weight: 500;
|
|
3473
|
-
display: flex;
|
|
3474
|
-
align-items: center;
|
|
3475
|
-
}
|
|
3476
|
-
|
|
3477
|
-
.status {
|
|
3478
|
-
color: var(--color-primary-main, #76b703);
|
|
3479
|
-
}
|
|
3480
|
-
|
|
3481
|
-
.link {
|
|
3482
|
-
font-size: 0.8125rem;
|
|
3483
|
-
text-decoration: none;
|
|
3484
|
-
color: var(--text-primary, #111827);
|
|
3485
|
-
border-bottom: 0.0625rem solid var(--color-primary-main, #76b703);
|
|
3486
|
-
}
|
|
3487
|
-
|
|
3488
|
-
.cell {
|
|
3489
|
-
padding: 0.375rem;
|
|
3490
|
-
border-radius: var(--border-radius-small, 8px);
|
|
3491
|
-
border: 1px solid transparent;
|
|
3492
|
-
transition: all 0.2s;
|
|
3493
|
-
min-height: 2.625rem;
|
|
3494
|
-
}
|
|
3495
|
-
|
|
3496
|
-
.cell.one-column {
|
|
3497
|
-
min-height: 0 !important;
|
|
3498
|
-
}
|
|
3499
|
-
|
|
3500
|
-
.cell.sortable-ghost {
|
|
3501
|
-
opacity: 0.5;
|
|
3502
|
-
border-color: var(--color-primary-main, #76b703);
|
|
3503
|
-
}
|
|
3504
|
-
|
|
3505
|
-
.cell.sortable-chosen {
|
|
3506
|
-
transform: scale(1.02);
|
|
3507
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
3508
|
-
}
|
|
3509
|
-
|
|
3510
|
-
.link:hover {
|
|
3511
|
-
color: var(--color-primary-main, #76b703);
|
|
3512
|
-
}
|
|
3513
|
-
|
|
3514
|
-
.settings-buttons {
|
|
3515
|
-
display: flex;
|
|
3516
|
-
align-items: center;
|
|
3517
|
-
}
|
|
3518
|
-
|
|
3519
|
-
.header-buttons {
|
|
3520
|
-
display: flex;
|
|
3521
|
-
gap: 0.5rem;
|
|
3522
|
-
color: var(--text-secondary, #777);
|
|
3523
|
-
}
|
|
3524
|
-
|
|
3525
|
-
.size-button {
|
|
3526
|
-
margin-right: 0.5rem;
|
|
3527
|
-
cursor: pointer;
|
|
3528
|
-
}
|
|
3529
|
-
|
|
3530
|
-
.size-button--active {
|
|
3531
|
-
text-decoration: underline;
|
|
3532
|
-
font-weight: bold;
|
|
3533
|
-
}
|
|
3534
|
-
|
|
3535
|
-
.popper-input {
|
|
3536
|
-
margin-bottom: 0.5rem;
|
|
3537
|
-
background-color: var(--background-paper, #fff);
|
|
3538
|
-
z-index: 1;
|
|
3539
|
-
}
|
|
3540
|
-
|
|
3541
|
-
.cell-background {
|
|
3542
|
-
width: 14px;
|
|
3543
|
-
height: 14px;
|
|
3544
|
-
border-radius: 4px;
|
|
3545
|
-
border: 1px solid #ccc;
|
|
3546
|
-
cursor: pointer;
|
|
3547
|
-
margin-right: 0.5rem;
|
|
3548
|
-
}
|
|
3549
|
-
|
|
3550
|
-
.bold-toggle {
|
|
3551
|
-
cursor: pointer;
|
|
3552
|
-
}
|
|
3553
|
-
|
|
3554
|
-
.bold-toggle--active {
|
|
3555
|
-
text-decoration: underline;
|
|
3556
|
-
font-weight: bold;
|
|
3557
|
-
}
|
|
3558
|
-
|
|
3559
|
-
.color-label {
|
|
3560
|
-
margin: 0.5rem 0 0.25rem 0;
|
|
3561
|
-
}
|
|
3562
|
-
|
|
3563
|
-
.cell-background--active {
|
|
3564
|
-
border-bottom: 1px solid white;
|
|
3565
|
-
margin-top: 1px;
|
|
3566
|
-
margin-right: 0.5rem;
|
|
3567
|
-
}
|
|
3568
|
-
|
|
3569
|
-
.add-variable-button {
|
|
3570
|
-
display: inline-block;
|
|
3571
|
-
}
|
|
3572
|
-
|
|
3573
|
-
@media (max-width: 600px) {
|
|
3574
|
-
.add-variable-button {
|
|
3575
|
-
display: block;
|
|
3576
|
-
width: 100%;
|
|
3577
|
-
}
|
|
3578
|
-
}
|
|
3579
|
-
|
|
3580
|
-
.cell--span0 {
|
|
3581
|
-
display: none;
|
|
3582
|
-
}
|
|
3583
|
-
.cell--span1 {
|
|
3584
|
-
grid-column: span 1 / span 1;
|
|
3585
|
-
}
|
|
3586
|
-
.cell--span2 {
|
|
3587
|
-
grid-column: span 2 / span 2;
|
|
3588
|
-
}
|
|
3589
|
-
.cell--span3 {
|
|
3590
|
-
grid-column: span 3 / span 3;
|
|
3591
|
-
}
|
|
3592
|
-
.cell--span4 {
|
|
3593
|
-
grid-column: span 4 / span 4;
|
|
3594
|
-
}
|
|
3595
|
-
|
|
3596
|
-
/* Responzívne nastavenie počtu stĺpcov */
|
|
3597
|
-
@media (min-width: 0px) {
|
|
3598
|
-
.grid-container {
|
|
3599
|
-
grid-template-columns: repeat(4, minmax(0, 1fr)); /* xs */
|
|
3600
|
-
}
|
|
3601
|
-
}
|
|
3602
|
-
|
|
3603
|
-
@media (min-width: var(--breakpoint-sm, 600px)) {
|
|
3604
|
-
.grid-container {
|
|
3605
|
-
grid-template-columns: repeat(4, minmax(0, 1fr)); /* sm */
|
|
3606
|
-
}
|
|
3607
|
-
}
|
|
3608
|
-
|
|
3609
|
-
@media (min-width: var(--breakpoint-md, 960px)) {
|
|
3610
|
-
.grid-container {
|
|
3611
|
-
grid-template-columns: repeat(4, minmax(0, 1fr)); /* md */
|
|
3612
|
-
}
|
|
3613
|
-
}
|
|
3614
|
-
|
|
3615
|
-
@media (min-width: var(--breakpoint-lg, 1280px)) {
|
|
3616
|
-
.grid-container {
|
|
3617
|
-
grid-template-columns: repeat(4, minmax(0, 1fr)); /* lg */
|
|
3618
|
-
}
|
|
3619
|
-
}
|
|
3620
|
-
|
|
3621
|
-
@media (min-width: var(--breakpoint-xl, 1536px)) {
|
|
3622
|
-
.grid-container {
|
|
3623
|
-
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
3624
|
-
}
|
|
3625
|
-
}
|
|
3626
|
-
|
|
3627
|
-
.hidden-cell {
|
|
3628
|
-
display: none;
|
|
3629
|
-
}
|
|
3630
|
-
|
|
3631
|
-
.tweakpane-container {
|
|
3632
|
-
min-width: 250px;
|
|
3633
|
-
max-width: 300px;
|
|
3634
|
-
}
|
|
3635
|
-
|
|
3636
|
-
/* Basic Tweakpane in tooltip styling - applying to document to bypass shadow DOM */
|
|
3637
|
-
:host([data-tweakpane-loaded]) {
|
|
3638
|
-
display: block;
|
|
3639
|
-
}
|
|
3640
|
-
`,
|
|
3641
|
-
];
|
|
3642
|
-
LitCaseVariablesTab.SUPPORTED_CURRENCIES = [
|
|
3643
|
-
'CZK', 'EUR', 'USD', 'GBP', 'CHF', 'PLN', 'HUF',
|
|
3644
|
-
'JPY', 'AUD', 'CAD', 'NOK', 'SEK', 'DKK', 'CNY', 'RUB',
|
|
3645
|
-
];
|
|
3646
|
-
__decorate([
|
|
3647
|
-
property({ type: Array })
|
|
3648
|
-
], LitCaseVariablesTab.prototype, "rows", void 0);
|
|
3649
|
-
__decorate([
|
|
3650
|
-
property({ type: Array })
|
|
3651
|
-
], LitCaseVariablesTab.prototype, "variables", void 0);
|
|
3652
|
-
__decorate([
|
|
3653
|
-
property({ type: Boolean })
|
|
3654
|
-
], LitCaseVariablesTab.prototype, "hideTabWhen", void 0);
|
|
3655
|
-
__decorate([
|
|
3656
|
-
property({ type: String })
|
|
3657
|
-
], LitCaseVariablesTab.prototype, "userLang", void 0);
|
|
3658
|
-
__decorate([
|
|
3659
|
-
property({ type: Array })
|
|
3660
|
-
], LitCaseVariablesTab.prototype, "allowedLang", void 0);
|
|
3661
|
-
__decorate([
|
|
3662
|
-
property({ type: String })
|
|
3663
|
-
], LitCaseVariablesTab.prototype, "dateFormat", void 0);
|
|
3664
|
-
__decorate([
|
|
3665
|
-
property({ type: Boolean })
|
|
3666
|
-
], LitCaseVariablesTab.prototype, "isLoading", void 0);
|
|
3667
|
-
__decorate([
|
|
3668
|
-
property({ type: Boolean })
|
|
3669
|
-
], LitCaseVariablesTab.prototype, "enableSettings", void 0);
|
|
3670
|
-
__decorate([
|
|
3671
|
-
property({ type: String })
|
|
3672
|
-
], LitCaseVariablesTab.prototype, "tabId", void 0);
|
|
3673
|
-
__decorate([
|
|
3674
|
-
property({ type: Boolean })
|
|
3675
|
-
], LitCaseVariablesTab.prototype, "gridVariables", void 0);
|
|
3676
|
-
__decorate([
|
|
3677
|
-
property({ type: Function })
|
|
3678
|
-
], LitCaseVariablesTab.prototype, "onSettingsChanged", void 0);
|
|
3679
|
-
__decorate([
|
|
3680
|
-
property({ type: String })
|
|
3681
|
-
], LitCaseVariablesTab.prototype, "hostURL", void 0);
|
|
3682
|
-
__decorate([
|
|
3683
|
-
property({ attribute: false })
|
|
3684
|
-
], LitCaseVariablesTab.prototype, "dataGridRef", void 0);
|
|
3685
|
-
__decorate([
|
|
3686
|
-
property({ attribute: false })
|
|
3687
|
-
], LitCaseVariablesTab.prototype, "dataGridRefs", void 0);
|
|
3688
|
-
__decorate([
|
|
3689
|
-
state()
|
|
3690
|
-
], LitCaseVariablesTab.prototype, "currentBreakpoint", void 0);
|
|
3691
|
-
__decorate([
|
|
3692
|
-
state()
|
|
3693
|
-
], LitCaseVariablesTab.prototype, "isOpen", void 0);
|
|
3694
|
-
__decorate([
|
|
3695
|
-
state()
|
|
3696
|
-
], LitCaseVariablesTab.prototype, "filterText", void 0);
|
|
3697
|
-
__decorate([
|
|
3698
|
-
state()
|
|
3699
|
-
], LitCaseVariablesTab.prototype, "isMobile", void 0);
|
|
3700
|
-
__decorate([
|
|
3701
|
-
state()
|
|
3702
|
-
], LitCaseVariablesTab.prototype, "expertModeModalOpen", void 0);
|
|
3703
|
-
__decorate([
|
|
3704
|
-
state()
|
|
3705
|
-
], LitCaseVariablesTab.prototype, "expertModeCell", void 0);
|
|
3706
|
-
__decorate([
|
|
3707
|
-
state()
|
|
3708
|
-
], LitCaseVariablesTab.prototype, "expertModeConfig", void 0);
|
|
3709
|
-
__decorate([
|
|
3710
|
-
state()
|
|
3711
|
-
], LitCaseVariablesTab.prototype, "activeSettingsCell", void 0);
|
|
3712
|
-
__decorate([
|
|
3713
|
-
state()
|
|
3714
|
-
], LitCaseVariablesTab.prototype, "settingsPopperOpen", void 0);
|
|
3715
|
-
if (!window.customElements.get('lit-case-variables-tab')) {
|
|
3716
|
-
window.customElements.define('lit-case-variables-tab', LitCaseVariablesTab);
|
|
3717
|
-
}
|
|
3718
|
-
//# sourceMappingURL=lit-case-variables-tab.js.map
|