@platforma-sdk/ui-vue 1.45.37 → 1.45.45

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 (78) hide show
  1. package/.turbo/turbo-build.log +23 -39
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +19 -0
  4. package/dist/components/PlAdvancedFilter/{SingleFilter.vue.d.ts → FilterEditor.vue.d.ts} +12 -18
  5. package/dist/components/PlAdvancedFilter/FilterEditor.vue.js +10 -0
  6. package/dist/components/PlAdvancedFilter/FilterEditor.vue.js.map +1 -0
  7. package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js +305 -0
  8. package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js.map +1 -0
  9. package/dist/components/PlAdvancedFilter/FilterEditor.vue3.js +33 -0
  10. package/dist/components/PlAdvancedFilter/FilterEditor.vue3.js.map +1 -0
  11. package/dist/components/PlAdvancedFilter/OperandButton.vue2.js.map +1 -1
  12. package/dist/components/PlAdvancedFilter/OperandButton.vue3.js +9 -9
  13. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts +35 -16
  14. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js +185 -145
  15. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js.map +1 -1
  16. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue3.js +13 -9
  17. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue3.js.map +1 -1
  18. package/dist/components/PlAdvancedFilter/constants.d.ts +4 -4
  19. package/dist/components/PlAdvancedFilter/constants.js +26 -22
  20. package/dist/components/PlAdvancedFilter/constants.js.map +1 -1
  21. package/dist/components/PlAdvancedFilter/index.d.ts +4 -0
  22. package/dist/components/PlAdvancedFilter/index.js +9 -0
  23. package/dist/components/PlAdvancedFilter/index.js.map +1 -0
  24. package/dist/components/PlAdvancedFilter/types.d.ts +30 -34
  25. package/dist/components/PlAdvancedFilter/utils.d.ts +26 -0
  26. package/dist/components/PlAdvancedFilter/utils.js +32 -131
  27. package/dist/components/PlAdvancedFilter/utils.js.map +1 -1
  28. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js +43 -41
  29. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js.map +1 -1
  30. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue3.js +2 -2
  31. package/dist/components/PlAnnotations/components/FilterSidebar.vue.d.ts +14 -2
  32. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +99 -90
  33. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js.map +1 -1
  34. package/dist/components/PlAnnotations/components/FilterSidebar.vue3.js +5 -5
  35. package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js +32 -30
  36. package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -1
  37. package/dist/components/PlAnnotations/components/PlAnnotations.vue3.js +5 -7
  38. package/dist/components/PlAnnotations/components/PlAnnotations.vue3.js.map +1 -1
  39. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js +26 -22
  40. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js.map +1 -1
  41. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue3.js +7 -9
  42. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue3.js.map +1 -1
  43. package/dist/components/PlAnnotations/components/style.module.css.js +13 -0
  44. package/dist/components/PlAnnotations/components/style.module.css.js.map +1 -0
  45. package/dist/components/PlAnnotations/index.d.ts +1 -0
  46. package/dist/index.js +35 -33
  47. package/dist/index.js.map +1 -1
  48. package/package.json +9 -8
  49. package/src/components/PlAdvancedFilter/{SingleFilter.vue → FilterEditor.vue} +53 -53
  50. package/src/components/PlAdvancedFilter/OperandButton.vue +1 -1
  51. package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +155 -59
  52. package/src/components/PlAdvancedFilter/constants.ts +17 -11
  53. package/src/components/PlAdvancedFilter/index.ts +6 -0
  54. package/src/components/PlAdvancedFilter/types.ts +23 -54
  55. package/src/components/PlAdvancedFilter/utils.ts +51 -163
  56. package/src/components/PlAnnotations/components/AnnotationsSidebar.vue +8 -8
  57. package/src/components/PlAnnotations/components/FilterSidebar.vue +64 -69
  58. package/src/components/PlAnnotations/components/PlAnnotations.vue +4 -7
  59. package/src/components/PlAnnotations/components/PlAnnotationsModal.vue +5 -8
  60. package/src/components/PlAnnotations/components/style.module.css +16 -0
  61. package/src/components/PlAnnotations/index.ts +2 -0
  62. package/dist/components/PlAdvancedFilter/SingleFilter.vue.js +0 -10
  63. package/dist/components/PlAdvancedFilter/SingleFilter.vue.js.map +0 -1
  64. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js +0 -306
  65. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js.map +0 -1
  66. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js +0 -35
  67. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js.map +0 -1
  68. package/dist/components/PlAdvancedFilter/types.js +0 -8
  69. package/dist/components/PlAdvancedFilter/types.js.map +0 -1
  70. package/dist/components/PlAnnotations/components/DynamicForm.vue.d.ts +0 -24
  71. package/dist/components/PlAnnotations/components/DynamicForm.vue.js +0 -10
  72. package/dist/components/PlAnnotations/components/DynamicForm.vue.js.map +0 -1
  73. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js +0 -109
  74. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js.map +0 -1
  75. package/dist/components/PlAnnotations/components/DynamicForm.vue3.js +0 -9
  76. package/dist/components/PlAnnotations/components/DynamicForm.vue3.js.map +0 -1
  77. package/dist/components/PlAnnotations/utils.js +0 -20
  78. package/dist/components/PlAnnotations/utils.js.map +0 -1
@@ -1,146 +1,25 @@
1
- import type { AnchoredPColumnId, AxisId, CanonicalizedJson, FilteredPColumnId, ValueType } from '@platforma-sdk/model';
2
- import { assertNever, getTypeFromPColumnOrAxisSpec, isAnchoredPColumnId, isFilteredPColumn, parseJson, type AxisSpec, type PColumnSpec, type SUniversalPColumnId } from '@platforma-sdk/model';
3
- import { type CommonFilterSpec, isSupportedFilterType, type Filter, type FilterType, type Group, type PlAdvancedFilterUI, type SupportedFilterTypes, type PlAdvancedFilterColumnId } from './types';
4
- import { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS, SUPPORTED_FILTER_TYPES } from './constants';
5
1
  import { filterUiMetadata } from '@milaboratories/uikit';
6
- import { ref, watch, type ModelRef } from 'vue';
7
- import { isAxisId } from '@platforma-sdk/model';
8
-
9
- function toInnerFilter(outerFilter: CommonFilterSpec): Filter | null {
10
- if (!('column' in outerFilter) || outerFilter.type === undefined || !isSupportedFilterType(outerFilter.type)) {
11
- return null;
12
- }
13
- if (outerFilter.type === 'patternFuzzyContainSubsequence') {
14
- return {
15
- ...outerFilter,
16
- value: outerFilter.value,
17
- wildcard: outerFilter.wildcard,
18
- maxEdits: outerFilter.maxEdits ?? 2,
19
- substitutionsOnly: outerFilter.substitutionsOnly ?? false,
20
- };
21
- }
22
-
23
- return { ...outerFilter } as Filter;
24
- }
25
-
26
- let groupIdCounter = 0;
27
- function getNewGroupId() {
28
- groupIdCounter++;
29
- return String(groupIdCounter);
30
- }
31
-
32
- function toInnerFiltersGroup(f: CommonFilterSpec): Group | null {
33
- if (f.type === 'not') {
34
- const group = toInnerFiltersGroup(f.filter);
35
- return group
36
- ? {
37
- not: !group.not,
38
- operand: group.operand,
39
- filters: group.filters,
40
- id: getNewGroupId(),
41
- expanded: group.expanded,
42
- }
43
- : null;
44
- }
45
- if (f.type === 'and' || f.type === 'or') {
46
- return {
47
- operand: f.type,
48
- not: false,
49
- filters: f.filters.map((f) => toInnerFilter(f)).filter((v) => v !== null) as Filter[],
50
- id: getNewGroupId(),
51
- expanded: f.expanded ?? true,
52
- };
53
- }
54
- if (SUPPORTED_FILTER_TYPES.has(f.type as SupportedFilterTypes)) {
55
- const filter = toInnerFilter(f);
56
- return {
57
- operand: 'or',
58
- not: false,
59
- filters: filter ? [filter] : [],
60
- id: getNewGroupId(),
61
- expanded: f.expanded ?? true,
62
- };
63
- }
64
- return null;
65
- }
66
-
67
- export function toInnerModel(m: CommonFilterSpec): PlAdvancedFilterUI {
68
- const res: PlAdvancedFilterUI = {
69
- operand: 'or',
70
- groups: [],
71
- };
72
- if (m.type === 'not') {
73
- return res; // not supported 'not' for all the groups in ui
74
- }
75
- if (m.type === 'and' || m.type === 'or') {
76
- // group
77
- res.operand = m.type;
78
- res.groups = m.filters.map(toInnerFiltersGroup).filter((v) => v !== null) as Group[];
79
- } else if (SUPPORTED_FILTER_TYPES.has(m.type as SupportedFilterTypes)) {
80
- // single filter
81
- const group = toInnerFiltersGroup(m);
82
- res.groups = group ? [group] : [];
83
- }
84
- res.groups = res.groups.filter((gr) => gr.filters.length > 0);
85
- return res;
86
- }
87
-
88
- function toOuterFilter(filter: Filter): CommonFilterSpec | null {
89
- if (
90
- filter.type === 'isNA' || filter.type === 'isNotNA'
91
- || filter.type === 'inSet' || filter.type === 'notInSet'
92
- ) {
93
- return filter;
94
- }
95
- if (
96
- filter.type === 'greaterThanOrEqual' || filter.type === 'lessThanOrEqual'
97
- || filter.type === 'greaterThan' || filter.type === 'lessThan'
98
- || filter.type === 'equal' || filter.type === 'notEqual'
99
- ) {
100
- return filter.x !== undefined ? { ...filter, x: filter.x } : null;
101
- }
102
- if (
103
- filter.type === 'patternEquals' || filter.type === 'patternNotEquals'
104
- || filter.type === 'patternContainSubsequence' || filter.type === 'patternNotContainSubsequence'
105
- || filter.type === 'patternMatchesRegularExpression'
106
- || filter.type === 'patternFuzzyContainSubsequence'
107
- ) {
108
- return filter.value !== undefined ? { ...filter, value: filter.value } : null;
109
- }
110
- assertNever(filter.type);
111
- }
2
+ import type { AnchoredPColumnId, AxisId, CanonicalizedJson, FilteredPColumnId, ValueType } from '@platforma-sdk/model';
3
+ import { getTypeFromPColumnOrAxisSpec, isAnchoredPColumnId, isAxisId, isFilteredPColumn, parseJson, type AxisSpec, type PColumnSpec, type SUniversalPColumnId } from '@platforma-sdk/model';
4
+ import { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS } from './constants';
5
+ import type { NodeFilter } from './types';
6
+ import { type CommonFilter, type EditableFilter, type PlAdvancedFilterColumnId, type SupportedFilterTypes } from './types';
112
7
 
113
- function toOuterFilterGroup(m: Group): CommonFilterSpec {
114
- const res: CommonFilterSpec = {
115
- type: m.operand,
116
- expanded: m.expanded,
117
- filters: m.filters.map(toOuterFilter).filter((v): v is CommonFilterSpec => v !== null),
118
- };
119
- if (m.not) {
120
- return {
121
- type: 'not',
122
- filter: res,
123
- } as CommonFilterSpec;
124
- }
125
- return res;
126
- }
127
- export function toOuterModel(m: PlAdvancedFilterUI): CommonFilterSpec {
128
- return {
129
- type: m.operand,
130
- filters: m.groups.map(toOuterFilterGroup),
131
- };
8
+ export function getNewId() {
9
+ return Date.now();
132
10
  }
133
11
 
134
- export function createNewGroup(selectedSourceId: string) {
12
+ export function createNewGroup(selectedSourceId: string): NodeFilter {
135
13
  return {
136
- id: getNewGroupId(),
137
- not: false,
138
- operand: 'and' as const,
139
- expanded: true,
14
+ id: getNewId(),
15
+ isExpanded: true,
16
+ type: 'and',
140
17
  filters: [{
18
+ id: getNewId(),
19
+ isExpanded: true,
141
20
  ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],
142
21
  column: selectedSourceId as SUniversalPColumnId,
143
- }],
22
+ } as CommonFilter],
144
23
  };
145
24
  }
146
25
 
@@ -169,39 +48,48 @@ export function isStringValueType(spec?: PColumnSpec | AxisSpec): boolean {
169
48
  return valueType === 'String';
170
49
  }
171
50
 
172
- export function isNumericFilter(filter: Filter): filter is Filter & { type: 'equal' | 'notEqual' | 'lessThan' | 'lessThanOrEqual' | 'greaterThan' | 'greaterThanOrEqual' } {
173
- return filter.type === 'equal' || filter.type === 'notEqual' || filter.type === 'lessThan' || filter.type === 'lessThanOrEqual' || filter.type === 'greaterThan' || filter.type === 'greaterThanOrEqual';
174
- }
175
- export function isStringFilter(filter: Filter): filter is Filter & { type: 'patternEquals' | 'patternNotEquals' | 'patternContainSubsequence' | 'patternNotContainSubsequence' | 'patternMatchesRegularExpression' | 'patternFuzzyContainSubsequence' } {
176
- return filter.type === 'patternEquals' || filter.type === 'patternNotEquals' || filter.type === 'patternContainSubsequence' || filter.type === 'patternNotContainSubsequence' || filter.type === 'patternMatchesRegularExpression' || filter.type === 'patternFuzzyContainSubsequence';
51
+ export function isNumericFilter(filter: EditableFilter): filter is Extract<EditableFilter, {
52
+ type: 'equal'
53
+ | 'notEqual'
54
+ | 'lessThan'
55
+ | 'lessThanOrEqual'
56
+ | 'greaterThan'
57
+ | 'greaterThanOrEqual';
58
+ }> {
59
+ return filter.type === 'equal'
60
+ || filter.type === 'notEqual'
61
+ || filter.type === 'lessThan'
62
+ || filter.type === 'lessThanOrEqual'
63
+ || filter.type === 'greaterThan'
64
+ || filter.type === 'greaterThanOrEqual';
65
+ }
66
+
67
+ export function isPositionFilter(filter: EditableFilter): filter is Extract<EditableFilter, { type: 'topN' | 'bottomN' }> {
68
+ return filter.type === 'topN'
69
+ || filter.type === 'bottomN'
70
+ ;
71
+ }
72
+
73
+ export function isStringFilter(filter: EditableFilter): filter is Extract<EditableFilter, {
74
+ type: 'patternEquals'
75
+ | 'patternNotEquals'
76
+ | 'patternContainSubsequence'
77
+ | 'patternNotContainSubsequence'
78
+ | 'patternMatchesRegularExpression'
79
+ | 'patternFuzzyContainSubsequence';
80
+ }> {
81
+ return filter.type === 'patternEquals'
82
+ || filter.type === 'patternNotEquals'
83
+ || filter.type === 'patternContainSubsequence'
84
+ || filter.type === 'patternNotContainSubsequence'
85
+ || filter.type === 'patternMatchesRegularExpression'
86
+ || filter.type === 'patternFuzzyContainSubsequence';
177
87
  }
178
88
 
179
- export function getFilterInfo(filterType: FilterType): { label: string; supportedFor: (spec: NormalizedSpecData) => boolean } {
89
+ export function getFilterInfo(filterType: SupportedFilterTypes): { label: string; supportedFor: (spec: NormalizedSpecData) => boolean } {
180
90
  return filterUiMetadata[filterType as keyof typeof filterUiMetadata];
181
91
  }
182
92
 
183
- export function useInnerModel<T, V>(
184
- toInnerModel: (v: T) => V,
185
- toOuterModel: (v: V) => T,
186
- model: ModelRef<T>,
187
- ) {
188
- const innerModel = ref<V>(toInnerModel(model.value));
189
- function updateOuterModelValue(v: V) {
190
- model.value = toOuterModel(v);
191
- }
192
- function updateInnerModelValue(v: T) {
193
- innerModel.value = toInnerModel(v);
194
- }
195
- watch(() => model.value, (v: T) => {
196
- updateInnerModelValue(v);
197
- }, { deep: true });
198
- watch(() => innerModel.value, (v: V) => {
199
- updateOuterModelValue(v);
200
- }, { deep: true });
201
-
202
- return innerModel;
203
- }
204
-
205
93
  export function isValidColumnId(id: unknown): id is PlAdvancedFilterColumnId {
206
94
  if (typeof id !== 'string') {
207
95
  return false;
@@ -8,6 +8,7 @@ import {
8
8
  PlSidebarItem,
9
9
  } from '@milaboratories/uikit';
10
10
  import type { Annotation } from '../types';
11
+ import $commonStyle from './style.module.css';
11
12
 
12
13
  // Models
13
14
  const annotation = defineModel<Annotation>('annotation', { required: true });
@@ -21,7 +22,7 @@ function handleAddStep() {
21
22
  const id = randomInt();
22
23
  annotation.value.steps.push({
23
24
  id,
24
- label: `Filter #${annotation.value.steps.length + 1}`,
25
+ label: '',
25
26
  filter: {
26
27
  id: randomInt(),
27
28
  type: 'and',
@@ -37,18 +38,15 @@ function handleAddStep() {
37
38
  <template #header-content>
38
39
  <PlEditableTitle
39
40
  v-model="annotation.title"
41
+ :class="{ [$commonStyle.flashing]: annotation.title.length === 0 }"
40
42
  :max-length="40"
41
43
  max-width="600px"
42
- placeholder="Annotation Name"
44
+ placeholder="Annotation Title"
43
45
  :autofocus="annotation.title.length === 0"
44
46
  />
45
47
  </template>
46
48
  <template v-if="annotation" #body-content>
47
- <div :class="$style.root">
48
- <PlBtnSecondary icon="add" @click="handleAddStep">
49
- Add annotation
50
- </PlBtnSecondary>
51
-
49
+ <div :class="[$style.root, { [$commonStyle.disabled]: annotation.title.length === 0 }]">
52
50
  <span :class="$style.tip">Lower annotations override the ones above. Rearrange them by dragging.</span>
53
51
 
54
52
  <PlElementList
@@ -63,6 +61,9 @@ function handleAddStep() {
63
61
  {{ item.label }}
64
62
  </template>
65
63
  </PlElementList>
64
+ <PlBtnSecondary icon="add" @click="handleAddStep">
65
+ Add label
66
+ </PlBtnSecondary>
66
67
  </div>
67
68
  </template>
68
69
  <template #footer-content>
@@ -88,7 +89,6 @@ function handleAddStep() {
88
89
  }
89
90
 
90
91
  .tip {
91
- margin-top: 12px;
92
92
  color: var(--txt-03);
93
93
  }
94
94
 
@@ -1,27 +1,32 @@
1
1
  <script lang="ts">
2
2
  export type Props = {
3
- columns: SimplifiedUniversalPColumnEntry[];
3
+ columns: PlAdvancedFilterItem[];
4
+
5
+ getSuggestOptions: (params: { columnId: PlAdvancedFilterColumnId; searchStr: string; axisIdx?: number }) =>
6
+ ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;
7
+ // @todo: can be optional
8
+ getSuggestModel?: (params: { columnId: PlAdvancedFilterColumnId; searchStr: string; axisIdx?: number }) =>
9
+ ListOptionBase<string | number> | Promise<ListOptionBase<string | number>>;
10
+
4
11
  hasSelectedColumns?: boolean;
5
12
  getValuesForSelectedColumns?: () => Promise<undefined | { columnId: PObjectId; values: string[] }>;
6
13
  };
7
14
  </script>
8
15
  <script setup lang="ts">
9
- import { isNil, randomInt } from '@milaboratories/helpers';
10
- import type {
11
- FilterSpecTypeFieldRecord,
12
- } from '@milaboratories/uikit';
16
+ import { randomInt } from '@milaboratories/helpers';
13
17
  import {
14
- getFilterUiMetadata,
15
18
  PlBtnSecondary,
16
19
  PlEditableTitle,
17
- PlElementList,
18
20
  PlSidebarItem,
19
21
  } from '@milaboratories/uikit';
20
- import type { FilterSpecLeaf, PObjectId, SimplifiedUniversalPColumnEntry, SUniversalPColumnId } from '@platforma-sdk/model';
22
+ import type { ListOptionBase, PObjectId, SUniversalPColumnId } from '@platforma-sdk/model';
21
23
  import { computed } from 'vue';
22
- import type { Filter, FilterSpec } from '../types';
23
- import { createDefaultFilterMetadata } from '../utils';
24
- import DynamicForm from './DynamicForm.vue';
24
+ import type { PlAdvancedFilterFilter, PlAdvancedFilterSupportedFilters } from '../../PlAdvancedFilter';
25
+ import { PlAdvancedFilter, type PlAdvancedFilterItem } from '../../PlAdvancedFilter';
26
+ import type { PlAdvancedFilterColumnId } from '../../PlAdvancedFilter/types';
27
+ import type { Filter } from '../types';
28
+
29
+ import $commonStyle from './style.module.css';
25
30
 
26
31
  // Models
27
32
  const step = defineModel<Filter>('step', { required: true });
@@ -36,7 +41,14 @@ const addFilterPlaceholder = () => {
36
41
  step.value.filter.filters.push({
37
42
  id: randomInt(),
38
43
  isExpanded: true,
39
- type: undefined,
44
+ type: 'or',
45
+ filters: [
46
+ {
47
+ id: randomInt(),
48
+ type: 'isNA',
49
+ column: props.columns[0].id as SUniversalPColumnId,
50
+ },
51
+ ],
40
52
  });
41
53
  };
42
54
 
@@ -63,26 +75,22 @@ async function addFilterFromSelected() {
63
75
  });
64
76
  }
65
77
 
66
- // Getters
67
- const getColumnLabel = (filter: FilterSpec) => {
68
- if (!isNil(filter.name)) return filter.name;
69
- return props.columns
70
- .find((c) => 'column' in filter ? c.id === filter.column : false)?.label
71
- ?? filter.type;
72
- };
73
-
74
- const getFormMetadata = (filter: FilterSpec): FilterSpecTypeFieldRecord<FilterSpecLeaf> => {
75
- return !isNil(filter.type)
76
- ? getFilterUiMetadata(filter.type).form as FilterSpecTypeFieldRecord<FilterSpecLeaf>
77
- : createDefaultFilterMetadata();
78
- };
79
-
80
- const getFilterValues = (filter: FilterSpec) => {
81
- if (filter.type === 'or' || filter.type === 'and') {
82
- return filter.filters.map((f) => 'value' in f && !isNil(f.value) ? f.value : null).filter((v) => !isNil(v)).join (', ');
83
- }
84
- return null;
85
- };
78
+ const supportedFilters = [
79
+ 'isNA',
80
+ 'isNotNA',
81
+ 'greaterThan',
82
+ 'greaterThanOrEqual',
83
+ 'lessThan',
84
+ 'lessThanOrEqual',
85
+ 'patternEquals',
86
+ 'patternNotEquals',
87
+ 'patternContainSubsequence',
88
+ 'patternNotContainSubsequence',
89
+ 'equal',
90
+ 'notEqual',
91
+ 'topN',
92
+ 'bottomN',
93
+ ] as typeof PlAdvancedFilterSupportedFilters[number][];
86
94
  </script>
87
95
 
88
96
  <template>
@@ -91,53 +99,40 @@ const getFilterValues = (filter: FilterSpec) => {
91
99
  <PlEditableTitle
92
100
  :key="step.id"
93
101
  v-model="step.label"
102
+ :class="{ [$commonStyle.flashing]: step.label.length === 0 }"
94
103
  :max-length="40"
95
104
  max-width="600px"
96
- placeholder="Annotation Name"
105
+ placeholder="Filter Name"
97
106
  :autofocus="step.label.length === 0"
98
107
  />
99
108
  </template>
100
109
  <template #body-content>
101
- <div :class="$style.root">
102
- <div :class="$style.actions">
103
- <PlBtnSecondary style="width: 100%;" icon="add" @click="addFilterPlaceholder">
104
- Filter
105
- </PlBtnSecondary>
106
- <PlBtnSecondary v-if="withSelection" style="width: 100%;" icon="add" :disabled="!props.hasSelectedColumns" @click="addFilterFromSelected">
107
- From selection
108
- </PlBtnSecondary>
109
- </div>
110
-
111
- <PlElementList
112
- v-model:items="step.filter.filters"
113
- :get-item-key="(item) => item.id"
114
- :is-expanded="(item) => Boolean(item.isExpanded)"
115
- :on-expand="(item) => item.isExpanded = !Boolean(item.isExpanded)"
116
- >
117
- <template #item-title="{ item }">
118
- {{ getColumnLabel(item) }}
119
- </template>
120
- <template #item-content="{ item, index }">
121
- <template v-if="item.type !== 'or' && item.type !== 'and'">
122
- <DynamicForm
123
- v-model="(step.filter.filters[index] as FilterSpecLeaf)"
124
- :columns="props.columns"
125
- :form-metadata="getFormMetadata(item)"
126
- />
127
- </template>
128
- <template v-else>
129
- <div>{{ getFilterValues(item) }}</div>
130
- </template>
131
- </template>
132
- </PlElementList>
133
- </div>
110
+ <PlAdvancedFilter
111
+ v-model:filters="(step.filter as PlAdvancedFilterFilter)"
112
+ :class="[$style.root, { [$commonStyle.disabled]: step.label.length === 0 }]"
113
+ :items="props.columns"
114
+ :supported-filters="supportedFilters"
115
+ :get-suggest-model="props.getSuggestModel"
116
+ :get-suggest-options="props.getSuggestOptions"
117
+ :enable-dnd="false"
118
+ :enable-add-group-button="true"
119
+ >
120
+ <template #add-group-buttons>
121
+ <div :class="$style.actions">
122
+ <PlBtnSecondary icon="add" @click="addFilterPlaceholder">
123
+ Add Filter
124
+ </PlBtnSecondary>
125
+ <PlBtnSecondary v-if="withSelection" icon="add" :disabled="!props.hasSelectedColumns" @click="addFilterFromSelected">
126
+ From selection
127
+ </PlBtnSecondary>
128
+ </div>
129
+ </template>
130
+ </PlAdvancedFilter>
134
131
  </template>
135
132
  </PlSidebarItem>
136
133
  </template>
137
134
 
138
- <style lang="scss" module>
139
- @use '@milaboratories/uikit/styles/variables' as *;
140
-
135
+ <style module>
141
136
  .root {
142
137
  display: flex;
143
138
  flex-direction: column;
@@ -51,7 +51,7 @@ async function handleDeleteSchema() {
51
51
  </script>
52
52
 
53
53
  <template>
54
- <PlSidebarGroup :class="$style.sidebarGroup">
54
+ <PlSidebarGroup>
55
55
  <template #item-0>
56
56
  <AnnotationsSidebar
57
57
  v-model:annotation="annotation"
@@ -67,6 +67,8 @@ async function handleDeleteSchema() {
67
67
  v-model:step="selectedStep"
68
68
  :class="$style.sidebarItem"
69
69
  :columns="props.columns"
70
+ :get-suggest-model="props.getSuggestModel"
71
+ :get-suggest-options="props.getSuggestOptions"
70
72
  :selectedStepId="selectedStepId"
71
73
  :hasSelectedColumns="props.hasSelectedColumns"
72
74
  :getValuesForSelectedColumns="props.getValuesForSelectedColumns"
@@ -75,12 +77,7 @@ async function handleDeleteSchema() {
75
77
  </PlSidebarGroup>
76
78
  </template>
77
79
 
78
- <style lang="scss" module>
79
- .sidebarGroup {
80
- width: 100%;
81
- height: 100%;
82
- }
83
-
80
+ <style module>
84
81
  .sidebarItem {
85
82
  width: 100%;
86
83
  height: 100%;
@@ -30,8 +30,10 @@ async function handleDeleteSchema() {
30
30
  <PlPureSlideModal v-model="opened" :class="$style.modal" width="768px">
31
31
  <PlAnnotations
32
32
  v-model:annotation="annotation"
33
- :class="$style.sidebarItem"
33
+ :class="$style.content"
34
34
  :columns="props.columns"
35
+ :get-suggest-model="props.getSuggestModel"
36
+ :get-suggest-options="props.getSuggestOptions"
35
37
  :has-selected-columns="props.hasSelectedColumns"
36
38
  :getValuesForSelectedColumns="props.getValuesForSelectedColumns"
37
39
  @delete-schema="handleDeleteSchema"
@@ -39,17 +41,12 @@ async function handleDeleteSchema() {
39
41
  </PlPureSlideModal>
40
42
  </template>
41
43
 
42
- <style lang="scss" module>
44
+ <style module>
43
45
  .modal {
44
46
  display: flex;
45
47
  }
46
48
 
47
- .sidebarGroup {
48
- width: 100%;
49
- height: 100%;
50
- }
51
-
52
- .sidebarItem {
49
+ .content {
53
50
  width: 100%;
54
51
  height: 100%;
55
52
  }
@@ -0,0 +1,16 @@
1
+ .flashing {
2
+ animation: flash 1s ease-in-out infinite alternate;
3
+ }
4
+ @keyframes flash {
5
+ 0% {
6
+ box-shadow: 0 0 6px 4px var(--border-color-focus);
7
+ }
8
+ 100% {
9
+ box-shadow: 0 0 2px 2px var(--border-color-focus);
10
+ }
11
+ }
12
+
13
+ .disabled {
14
+ pointer-events: none;
15
+ opacity: 0.5;
16
+ }
@@ -1,2 +1,4 @@
1
1
  export { default as PlAnnotations } from './components/PlAnnotations.vue';
2
2
  export { default as PlAnnotationsModal } from './components/PlAnnotationsModal.vue';
3
+
4
+ export type { Annotation, Filter, FilterSpec } from './types';
@@ -1,10 +0,0 @@
1
- import s from "./SingleFilter.vue2.js";
2
- import o from "./SingleFilter.vue3.js";
3
- import t from "../../_virtual/_plugin-vue_export-helper.js";
4
- const e = {
5
- $style: o
6
- }, c = /* @__PURE__ */ t(s, [["__cssModules", e]]);
7
- export {
8
- c as default
9
- };
10
- //# sourceMappingURL=SingleFilter.vue.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SingleFilter.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}