@platforma-sdk/ui-vue 1.63.12 → 1.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.turbo/turbo-build.log +38 -32
  2. package/.turbo/turbo-formatter$colon$check.log +2 -2
  3. package/.turbo/turbo-linter$colon$check.log +2 -2
  4. package/.turbo/turbo-types$colon$check.log +1 -1
  5. package/CHANGELOG.md +24 -0
  6. package/dist/components/PlAdvancedFilter/FilterEditor.js.map +1 -1
  7. package/dist/components/PlAdvancedFilter/FilterEditor.style.js.map +1 -1
  8. package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts +3 -8
  9. package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts.map +1 -1
  10. package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js +164 -151
  11. package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js.map +1 -1
  12. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.js.map +1 -1
  13. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.style.js +8 -7
  14. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.style.js.map +1 -1
  15. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.css +1 -1
  16. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts +24 -8
  17. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts.map +1 -1
  18. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js +176 -110
  19. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js.map +1 -1
  20. package/dist/components/PlAdvancedFilter/types.d.ts +2 -0
  21. package/dist/components/PlAdvancedFilter/types.d.ts.map +1 -1
  22. package/dist/components/PlAgDataTable/PlAgDataTableV2.js.map +1 -1
  23. package/dist/components/PlAgDataTable/PlAgDataTableV2.style.js.map +1 -1
  24. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -1
  25. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +116 -109
  26. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
  27. package/dist/components/PlAgDataTable/compositions/useFilterableColumns.js +3 -3
  28. package/dist/components/PlAgDataTable/compositions/useFilterableColumns.js.map +1 -1
  29. package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts +6 -5
  30. package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts.map +1 -1
  31. package/dist/components/PlAgDataTable/sources/table-source-v2.js +122 -88
  32. package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
  33. package/dist/components/PlAgDataTable/sources/table-state-v2.d.ts +6 -3
  34. package/dist/components/PlAgDataTable/sources/table-state-v2.d.ts.map +1 -1
  35. package/dist/components/PlAgDataTable/sources/table-state-v2.js +182 -97
  36. package/dist/components/PlAgDataTable/sources/table-state-v2.js.map +1 -1
  37. package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.js.map +1 -1
  38. package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.style.js.map +1 -1
  39. package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.d.ts.map +1 -1
  40. package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js +37 -42
  41. package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js.map +1 -1
  42. package/dist/components/PlAgGridColumnManager/useFilteredItems.d.ts +5 -5
  43. package/dist/components/PlAgGridColumnManager/useFilteredItems.d.ts.map +1 -1
  44. package/dist/components/PlAgGridColumnManager/useFilteredItems.js +2 -2
  45. package/dist/components/PlAgGridColumnManager/useFilteredItems.js.map +1 -1
  46. package/dist/components/PlAgGridColumnManager/useGridColumns.js +14 -0
  47. package/dist/components/PlAgGridColumnManager/useGridColumns.js.map +1 -0
  48. package/dist/components/PlAnnotations/components/FilterSidebar.js.map +1 -1
  49. package/dist/components/PlAnnotations/components/FilterSidebar.style.js.map +1 -1
  50. package/dist/components/PlAnnotations/components/FilterSidebar.vue.d.ts.map +1 -1
  51. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +7 -4
  52. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js.map +1 -1
  53. package/dist/components/PlTableFilters/PlTableFiltersV2.js.map +1 -1
  54. package/dist/components/PlTableFilters/PlTableFiltersV2.style.js +5 -1
  55. package/dist/components/PlTableFilters/PlTableFiltersV2.style.js.map +1 -1
  56. package/dist/components/PlTableFilters/PlTableFiltersV2.vue.css +1 -1
  57. package/dist/components/PlTableFilters/PlTableFiltersV2.vue.d.ts +7 -9
  58. package/dist/components/PlTableFilters/PlTableFiltersV2.vue.d.ts.map +1 -1
  59. package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js +72 -47
  60. package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js.map +1 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +2 -0
  63. package/dist/index.js.map +1 -1
  64. package/dist/lib/util/helpers/dist/functions.js.map +1 -1
  65. package/dist/lib/util/helpers/dist/objects.js +4 -1
  66. package/dist/lib/util/helpers/dist/objects.js.map +1 -1
  67. package/package.json +8 -7
  68. package/src/components/PlAdvancedFilter/FilterEditor.vue +99 -55
  69. package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +163 -95
  70. package/src/components/PlAdvancedFilter/types.ts +6 -1
  71. package/src/components/PlAgDataTable/PlAgDataTableV2.vue +26 -7
  72. package/src/components/PlAgDataTable/compositions/useFilterableColumns.ts +4 -4
  73. package/src/components/PlAgDataTable/sources/table-source-v2.ts +231 -131
  74. package/src/components/PlAgDataTable/sources/table-state-v2.ts +249 -70
  75. package/src/components/PlAgGridColumnManager/PlAgGridColumnManager.vue +17 -35
  76. package/src/components/PlAgGridColumnManager/useFilteredItems.ts +9 -11
  77. package/src/components/PlAgGridColumnManager/useGridColumns.ts +26 -0
  78. package/src/components/PlAnnotations/components/FilterSidebar.vue +3 -2
  79. package/src/components/PlTableFilters/PlTableFiltersV2.vue +76 -26
  80. package/src/index.ts +4 -0
@@ -1,7 +1,8 @@
1
1
  <script lang="ts" setup generic="T extends RootFilter">
2
2
  import { PlBtnSecondary, PlCheckbox, PlElementList } from "@milaboratories/uikit";
3
3
  import type { ListOptionBase } from "@platforma-sdk/model";
4
- import { computed, toRaw } from "vue";
4
+ import { produce } from "immer";
5
+ import { computed } from "vue";
5
6
  import FilterEditor from "./FilterEditor.vue";
6
7
  import OperandButton from "./OperandButton.vue";
7
8
  import { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS, SUPPORTED_FILTER_TYPES } from "./constants";
@@ -9,24 +10,35 @@ import type {
9
10
  CommonFilter,
10
11
  EditableFilter,
11
12
  NodeFilter,
13
+ Operand,
12
14
  PlAdvancedFilterColumnId,
13
15
  RootFilter,
14
16
  SourceOptionInfo,
15
17
  } from "./types";
16
18
  import { createNewGroup, getNewId, isValidColumnId } from "./utils";
17
19
 
18
- const model = defineModel<T>("filters", { required: true });
19
-
20
20
  const props = withDefaults(
21
21
  defineProps<{
22
+ filters: T;
23
+ onUpdateFilters: (filters: T) => void;
22
24
  /** List of ids of sources (columns, axes) that can be selected in filters */
23
- items: SourceOptionInfo[];
25
+ options: SourceOptionInfo[];
24
26
  /** List of supported filter types */
25
27
  supportedFilters?: typeof SUPPORTED_FILTER_TYPES;
26
28
  /** If true - new filter can be added by droppind element into filter group; else new column is added by button click */
27
29
  enableDnd?: boolean;
28
30
  /** If true - "Add group" button is shown below the filter groups */
29
31
  enableAddGroupButton?: boolean;
32
+ /** If true - eye icon is shown per group to toggle suppression */
33
+ enableToggling?: boolean;
34
+ /** Function to determine if a filter is pinned */
35
+ isPinned?: (item: NodeFilter, index: number) => boolean;
36
+ /** Function to determine if a filter is removable */
37
+ isRemovable?: (item: NodeFilter, index: number) => boolean;
38
+ /** Function to determine if a filter is draggable */
39
+ isDraggable?: (item: NodeFilter, index: number) => boolean;
40
+ /** Function to determine if a group is complete */
41
+ isCompletedGroup?: (group: NodeFilter, index: number) => boolean;
30
42
  /** Loading function for unique values for Equal/InSet filters and fixed axes options. */
31
43
  getSuggestOptions: (params: {
32
44
  columnId: PlAdvancedFilterColumnId;
@@ -37,14 +49,23 @@ const props = withDefaults(
37
49
  }>(),
38
50
  {
39
51
  supportedFilters: () => SUPPORTED_FILTER_TYPES,
52
+ isCompletedGroup: () => false,
53
+ isPinned: () => false,
54
+ isRemovable: () => true,
55
+ isDraggable: () => true,
56
+
40
57
  getSuggestModel: undefined,
41
58
 
42
59
  enableDnd: false,
43
60
  enableAddGroupButton: false,
61
+ enableToggling: false,
44
62
  },
45
63
  );
64
+ const produceFiltersUpdate = (updater: (draft: T) => void) => {
65
+ props.onUpdateFilters(produce(props.filters, updater));
66
+ };
46
67
 
47
- const firstColumnId = computed(() => props.items[0]?.id);
68
+ const firstColumnId = computed(() => props.options[0]?.id);
48
69
  const emptyGroup: NodeFilter[] = [
49
70
  {
50
71
  id: -1,
@@ -54,93 +75,100 @@ const emptyGroup: NodeFilter[] = [
54
75
  },
55
76
  ];
56
77
 
78
+ const rootFilters = computed({
79
+ get: () => props.filters.filters,
80
+ set: (filters) => props.onUpdateFilters({ ...props.filters, filters: filters }),
81
+ });
82
+
57
83
  function getRootGroups() {
58
- if (model.value.type !== "or" && model.value.type !== "and") {
84
+ if (props.filters.type !== "or" && props.filters.type !== "and") {
59
85
  throw new Error('Invalid model structure, expected root to be "or" or "and" group');
60
86
  }
61
- return model.value.filters;
87
+ return props.filters.filters;
62
88
  }
63
89
 
64
- function getRootGroup(idx: number): NodeFilter {
65
- const groups = getRootGroups();
66
- const group = groups[idx];
67
- if (group.type !== "and" && group.type !== "or" && group.type !== "not") {
90
+ function getDraftGroupContent(
91
+ draft: RootFilter,
92
+ idx: number,
93
+ ): Exclude<NodeFilter, { type: "not" }> {
94
+ const group = draft.filters[idx];
95
+ if (group.type === "not") {
96
+ if (group.filter.type !== "and" && group.filter.type !== "or") {
97
+ throw new Error('Invalid group structure, expected "and" or "or" group inside "not"');
98
+ }
99
+ return group.filter;
100
+ }
101
+ if (group.type !== "and" && group.type !== "or") {
68
102
  throw new Error('Invalid group structure, expected "and", "or" or "not" group');
69
103
  }
70
104
  return group;
71
105
  }
72
106
 
73
- function getRootGroupContent(idx: number): Exclude<NodeFilter, { type: "not" }> {
74
- const group = getRootGroup(idx);
75
-
76
- if (group.type !== "not") {
77
- return group;
78
- }
79
-
80
- if (group.filter.type !== "and" && group.filter.type !== "or") {
81
- throw new Error('Invalid group structure, expected "and" or "or" group inside "not"');
82
- }
83
-
84
- return group.filter;
107
+ function getNotContent<T extends CommonFilter>(item: T): Exclude<T, { type: "not" }> {
108
+ return item.type === "not"
109
+ ? (item.filter as Exclude<T, { type: "not" }>)
110
+ : (item as Exclude<T, { type: "not" }>);
85
111
  }
86
112
 
87
113
  function addColumnToGroup(groupIdx: number, selectedSourceId: PlAdvancedFilterColumnId) {
88
- const group = getRootGroupContent(groupIdx);
89
-
90
- group.filters.push({
91
- ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],
92
- column: selectedSourceId,
93
- id: getNewId(),
94
- isExpanded: true,
95
- } as CommonFilter);
114
+ produceFiltersUpdate((draft: RootFilter) => {
115
+ const group = getDraftGroupContent(draft, groupIdx);
116
+ group.filters.push({
117
+ ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],
118
+ column: selectedSourceId,
119
+ id: getNewId(),
120
+ isExpanded: true,
121
+ } as CommonFilter);
122
+ });
96
123
  }
97
124
 
98
125
  function removeFilterFromGroup(groupIdx: number, filterIdx: number) {
99
- const group = getRootGroupContent(groupIdx);
100
-
101
- if (group.filters.length === 1 && filterIdx === 0) {
102
- removeGroup(groupIdx);
103
- } else {
104
- group.filters.splice(filterIdx, 1);
105
- }
126
+ produceFiltersUpdate((draft: RootFilter) => {
127
+ const group = getDraftGroupContent(draft, groupIdx);
128
+ if (group.filters.length === 1 && filterIdx === 0) {
129
+ draft.filters.splice(groupIdx, 1);
130
+ } else {
131
+ group.filters.splice(filterIdx, 1);
132
+ }
133
+ });
106
134
  }
135
+
107
136
  function inverseRootNode(groupIdx: number) {
108
- const groups = getRootGroups();
109
- const group = groups[groupIdx];
110
- if (group.type === "not") {
111
- if (group.filter.type !== "and" && group.filter.type !== "or") {
112
- throw new Error('Invalid group structure, expected "and" or "or" group inside "not"');
113
- }
114
- groups[groupIdx] = group.filter;
115
- } else {
116
- const type = groups[groupIdx].type;
117
- if (type !== "and" && type !== "or" && type !== "not") {
118
- throw new Error('Invalid group structure, expected "and", "or" or "not" group');
137
+ produceFiltersUpdate((draft: RootFilter) => {
138
+ const group = draft.filters[groupIdx];
139
+ if (group.type === "not") {
140
+ if (group.filter.type !== "and" && group.filter.type !== "or") {
141
+ throw new Error('Invalid group structure, expected "and" or "or" group inside "not"');
142
+ }
143
+ draft.filters[groupIdx] = {
144
+ ...draft.filters[groupIdx],
145
+ ...group.filter,
146
+ };
147
+ } else {
148
+ const type = draft.filters[groupIdx].type;
149
+ if (type !== "and" && type !== "or" && type !== "not") {
150
+ throw new Error('Invalid group structure, expected "and", "or" or "not" group');
151
+ }
152
+ draft.filters[groupIdx] = {
153
+ ...draft.filters[groupIdx],
154
+ id: getNewId(),
155
+ type: "not",
156
+ filter: draft.filters[groupIdx],
157
+ };
119
158
  }
120
-
121
- groups[groupIdx] = {
122
- id: getNewId(),
123
- isExpanded: true,
124
- type: "not",
125
- filter: groups[groupIdx],
126
- };
127
- }
159
+ });
128
160
  }
129
161
 
130
- function getNotContent<T extends CommonFilter>(item: T): Exclude<T, { type: "not" }> {
131
- return item.type === "not"
132
- ? (item.filter as Exclude<T, { type: "not" }>)
133
- : (item as Exclude<T, { type: "not" }>);
162
+ function addGroup(selectedSourceId: PlAdvancedFilterColumnId) {
163
+ produceFiltersUpdate((draft: RootFilter) => {
164
+ draft.filters.push(createNewGroup(selectedSourceId));
165
+ });
134
166
  }
135
167
 
136
- function removeGroup(groupIdx: number) {
137
- const groups = getRootGroups();
138
- groups.splice(groupIdx, 1);
139
- }
140
- function addGroup(selectedSourceId: PlAdvancedFilterColumnId) {
141
- const newGroup = createNewGroup(selectedSourceId);
142
- const groups = getRootGroups();
143
- groups.push(newGroup);
168
+ function updateFilter(groupIdx: number, filterIdx: number, updatedFilter: EditableFilter) {
169
+ produceFiltersUpdate((draft: RootFilter) => {
170
+ getDraftGroupContent(draft, groupIdx).filters[filterIdx] = updatedFilter as CommonFilter;
171
+ });
144
172
  }
145
173
 
146
174
  function handleDropToExistingGroup(groupIdx: number, event: DragEvent) {
@@ -152,6 +180,7 @@ function handleDropToExistingGroup(groupIdx: number, event: DragEvent) {
152
180
  }
153
181
  }
154
182
  }
183
+
155
184
  function handleDropToNewGroup(event: DragEvent) {
156
185
  const dataTransfer = event.dataTransfer;
157
186
  if (dataTransfer?.getData("text/plain")) {
@@ -161,10 +190,35 @@ function handleDropToNewGroup(event: DragEvent) {
161
190
  }
162
191
  }
163
192
  }
193
+
164
194
  function dragOver(event: DragEvent) {
165
195
  event.preventDefault();
166
196
  }
167
197
 
198
+ function toggleExpand(_: NodeFilter, index: number) {
199
+ produceFiltersUpdate((draft: RootFilter) => {
200
+ draft.filters[index].isExpanded = !draft.filters[index].isExpanded;
201
+ });
202
+ }
203
+
204
+ function toggleSuppress(_: NodeFilter, index: number) {
205
+ produceFiltersUpdate((draft: RootFilter) => {
206
+ draft.filters[index].isSuppressed = !draft.filters[index].isSuppressed;
207
+ });
208
+ }
209
+
210
+ function changeGroupOperand(index: number, v: Operand) {
211
+ produceFiltersUpdate((draft: RootFilter) => {
212
+ getDraftGroupContent(draft, index).type = v;
213
+ });
214
+ }
215
+
216
+ function changeRootOperand(v: Operand) {
217
+ produceFiltersUpdate((draft: RootFilter) => {
218
+ draft.type = v;
219
+ });
220
+ }
221
+
168
222
  function validateFilter<T extends CommonFilter>(item: T): EditableFilter {
169
223
  if (item.type === "and" || item.type === "or" || item.type === "not") {
170
224
  throw new Error("Invalid filter structure, expected leaf filter");
@@ -172,34 +226,38 @@ function validateFilter<T extends CommonFilter>(item: T): EditableFilter {
172
226
 
173
227
  return item as EditableFilter;
174
228
  }
175
-
176
- function updateFilter(filters: CommonFilter[], idx: number, updatedFilter: EditableFilter) {
177
- filters[idx] = toRaw(updatedFilter as CommonFilter);
178
- }
179
229
  </script>
180
230
  <template>
181
231
  <div>
182
232
  <PlElementList
183
- v-model:items="model.filters"
233
+ v-model:items="rootFilters"
184
234
  :get-item-key="(filter) => filter.id"
185
235
  :item-class="$style.filterGroup"
186
236
  :item-class-content="$style.filterGroupContent"
187
237
  :item-class-title="$style.filterGroupTitle"
188
238
  :is-expanded="(filter) => filter.isExpanded === true"
189
- :on-expand="
190
- (group) => {
191
- group.isExpanded = !group.isExpanded;
192
- }
193
- "
194
- :disableDragging="false"
195
- :disableRemoving="false"
196
- :disableToggling="true"
197
- :disablePinning="true"
239
+ :on-expand="toggleExpand"
240
+ :is-toggled="(item) => item.isSuppressed === true"
241
+ :on-toggle="toggleSuppress"
242
+ :is-pinned="(item, index) => props.isPinned?.(item, index) === true"
243
+ :is-pinnable="() => false"
244
+ :is-removable="(item, index) => props.isRemovable?.(item, index) === true"
245
+ :is-draggable="(item, index) => props.isDraggable?.(item, index) === true"
246
+ :disable-toggling="props.enableToggling !== true"
247
+ :disable-dragging="false"
248
+ :disable-removing="false"
198
249
  >
199
- <template #item-title> Filter group </template>
250
+ <template #item-title="{ item, index }">
251
+ <slot name="group-title" :item="item" :index="index">Filter group</slot>
252
+ </template>
200
253
  <template #item-content="{ item, index }">
201
254
  <div
202
- :class="$style.groupContent"
255
+ :class="[
256
+ $style.groupContent,
257
+ {
258
+ [$style.suppressedLabel]: item.isSuppressed,
259
+ },
260
+ ]"
203
261
  dropzone="true"
204
262
  @drop="(event) => handleDropToExistingGroup(index, event)"
205
263
  @dragover="dragOver"
@@ -215,22 +273,24 @@ function updateFilter(filters: CommonFilter[], idx: number, updatedFilter: Edita
215
273
  <FilterEditor
216
274
  :filter="validateFilter(getNotContent(item).filters[filterIdx])"
217
275
  :operand="getNotContent(item).type"
218
- :column-options="items"
276
+ :column-options="options"
219
277
  :supported-filters="props.supportedFilters"
220
278
  :get-suggest-options="props.getSuggestOptions"
221
279
  :enable-dnd="Boolean(props.enableDnd)"
222
280
  :is-last="filterIdx === getNotContent(item).filters.length - 1"
223
- :on-change-operand="(v) => (getNotContent(item).type = v)"
224
- :on-delete="() => removeFilterFromGroup(index, filterIdx)"
225
- @update:filter="
226
- (value) => updateFilter(getNotContent(item).filters, filterIdx, value)
227
- "
281
+ @delete="() => removeFilterFromGroup(index, filterIdx)"
282
+ @update-filter="(value) => updateFilter(index, filterIdx, value)"
283
+ @change-operand="(v) => changeGroupOperand(index, v)"
228
284
  />
229
285
  </template>
230
286
  <div v-if="props.enableDnd" :class="$style.dropzone">
231
287
  <div>Drop dimensions here</div>
232
288
  </div>
233
- <PlBtnSecondary v-else icon="add" @click="addColumnToGroup(index, firstColumnId)">
289
+ <PlBtnSecondary
290
+ v-else-if="!props.isCompletedGroup(item, index)"
291
+ icon="add"
292
+ @click="addColumnToGroup(index, firstColumnId)"
293
+ >
234
294
  Add filter
235
295
  </PlBtnSecondary>
236
296
  </div>
@@ -239,9 +299,9 @@ function updateFilter(filters: CommonFilter[], idx: number, updatedFilter: Edita
239
299
  <OperandButton
240
300
  v-if="props.enableAddGroupButton || index < getRootGroups().length - 1"
241
301
  :class="$style.buttonWrapper"
242
- :active="model.type"
302
+ :active="props.filters.type"
243
303
  :disabled="index === getRootGroups().length - 1"
244
- :on-select="(v) => (model.type = v)"
304
+ :on-select="changeRootOperand"
245
305
  />
246
306
  </template>
247
307
  </PlElementList>
@@ -263,7 +323,11 @@ function updateFilter(filters: CommonFilter[], idx: number, updatedFilter: Edita
263
323
  @drop="handleDropToNewGroup"
264
324
  @dragover="dragOver"
265
325
  >
266
- <template #item-title>Filter group</template>
326
+ <template #item-title="{ item, index }">
327
+ <slot name="group-title" :item="item" :index="index + getRootGroups().length"
328
+ >Filter group</slot
329
+ >
330
+ </template>
267
331
  <template #item-content>
268
332
  <div v-if="enableDnd" :class="$style.dropzone">
269
333
  <div>Drop dimensions here</div>
@@ -296,6 +360,10 @@ function updateFilter(filters: CommonFilter[], idx: number, updatedFilter: Edita
296
360
  .notCheckbox {
297
361
  margin: 4px 0;
298
362
  }
363
+ .suppressedLabel {
364
+ filter: grayscale(100%);
365
+ pointer-events: none;
366
+ }
299
367
  .dropzone {
300
368
  border-radius: 6px;
301
369
  border: 1.5px dashed var(--color-div-grey);
@@ -18,7 +18,12 @@ export type PlAdvancedFilterColumnId =
18
18
  | CanonicalizedJson<AxisId>
19
19
  | CanonicalizedJson<PTableColumnId>;
20
20
 
21
- export type RequiredMeta = { id: number; isExpanded?: boolean };
21
+ export type RequiredMeta = {
22
+ id: number;
23
+ isExpanded?: boolean;
24
+ isSuppressed?: boolean;
25
+ source?: string;
26
+ };
22
27
 
23
28
  export type FilterLeafContent = Extract<
24
29
  FilterSpecLeaf<PlAdvancedFilterColumnId>,
@@ -162,11 +162,17 @@ const [filterableColumns, visibleFilterableColumns] = useFilterableColumns(
162
162
  () => settings.value.sourceId,
163
163
  () => gridOptions.value.columnDefs ?? null,
164
164
  );
165
- const { gridState, sheetsState, filtersState, searchString } = useTableState(
166
- tableState,
167
- settings,
168
- visibleFilterableColumns,
165
+ const defaultFilters = computed(() =>
166
+ settings.value.sourceId !== null ? settings.value.model?.defaultFilters : undefined,
169
167
  );
168
+ const {
169
+ gridState,
170
+ sheetsState,
171
+ searchString,
172
+ filtersState,
173
+ defaultFiltersState,
174
+ resetDefaultFilters,
175
+ } = useTableState(tableState, settings, visibleFilterableColumns, defaultFilters);
170
176
  const sheetsSettings = computed<PlDataTableSheetsSettings>(() => {
171
177
  const settingsCopy = { ...settings.value };
172
178
  return settingsCopy.sourceId !== null
@@ -234,10 +240,11 @@ function normalizeColumnVisibility(
234
240
  function getDefaultHiddenColIds(api: GridApi<PlAgDataTableV2Row>): PlTableColumnIdJson[] {
235
241
  const cols = api.getAllGridColumns();
236
242
  if (!cols) return [];
243
+
237
244
  return cols
238
245
  .filter((col) => {
239
246
  const spec = col.getColDef().context as PTableColumnSpec | undefined;
240
- return spec && isColumnOptional(spec.spec);
247
+ return spec !== undefined && spec.type === "column" && isColumnOptional(spec.spec);
241
248
  })
242
249
  .map((col) => col.getColId() as PlTableColumnIdJson);
243
250
  }
@@ -370,6 +377,13 @@ watch(
370
377
  return;
371
378
  }
372
379
 
380
+ if (
381
+ settings.model?.fullTableHandle === undefined ||
382
+ settings.model?.visibleTableHandle === undefined
383
+ ) {
384
+ return;
385
+ }
386
+
373
387
  // Data source changed -> show full page loader, clear selection
374
388
  if (settings.sourceId !== oldSettings?.sourceId) {
375
389
  gridApi.updateGridOptions({
@@ -410,7 +424,8 @@ watch(
410
424
  calculateGridOptions({
411
425
  generation,
412
426
  pfDriver: getRawPlatformaInstance().pFrameDriver,
413
- model: settings.model,
427
+ fullTableHandle: settings.model?.fullTableHandle,
428
+ visibleTableHandle: settings.model?.visibleTableHandle,
414
429
  sheets: settings.sheets ?? [],
415
430
  dataRenderedTracker,
416
431
  hiddenColIds: gridState.value.columnVisibility?.hiddenColIds,
@@ -532,9 +547,13 @@ watchEffect(() => {
532
547
  <PlAgGridColumnManager v-if="gridApi && !disableColumnsPanel" :api="gridApi" />
533
548
  <PlTableFiltersV2
534
549
  v-if="!disableFiltersPanel"
535
- v-model="filtersState"
550
+ :filters="filtersState"
551
+ :default-filters="defaultFiltersState"
536
552
  :pframe-handle="'model' in settings ? settings?.model?.fullPframeHandle : undefined"
537
553
  :columns="filterableColumns"
554
+ @updateFilters="(v) => (filtersState = v)"
555
+ @resetDefaultFilters="resetDefaultFilters"
556
+ @updateDefaultFilters="(v) => (defaultFiltersState = v)"
538
557
  />
539
558
  <PlAgCsvExporter v-if="gridApi && showExportButton" :api="gridApi" />
540
559
  <PlAgDataTableSheets v-model="sheetsState" :settings="sheetsSettings">
@@ -32,13 +32,13 @@ export function useFilterableColumns(
32
32
  const dataColDefs = getDataColDefs(columnDefs);
33
33
  const cols = dataColDefs
34
34
  .filter((def): def is typeof def & { colId: string } => !isNil(def.colId))
35
- .flatMap((def) => ({
36
- id: parseJson(def.colId satisfies string as PlTableColumnIdJson).labeled,
35
+ .map((def) => ({
36
+ item: parseJson(def.colId satisfies string as PlTableColumnIdJson).labeled,
37
37
  hide: def.hide,
38
38
  }));
39
39
 
40
- filterableColumns.value = cols.map((c) => c.id);
41
- visibleFilterableColumns.value = cols.filter((c) => !c.hide).map((c) => c.id);
40
+ filterableColumns.value = cols.map((c) => c.item);
41
+ visibleFilterableColumns.value = cols.filter((c) => !c.hide).map((c) => c.item);
42
42
  },
43
43
  { immediate: true },
44
44
  );