@platforma-sdk/ui-vue 1.45.42 → 1.46.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 (79) hide show
  1. package/.turbo/turbo-build.log +23 -39
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +22 -0
  4. package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts +27 -0
  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 +302 -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 +29 -20
  14. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js +184 -146
  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 +10 -2
  32. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +98 -91
  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 +23 -23
  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 +19 -17
  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} +58 -62
  50. package/src/components/PlAdvancedFilter/OperandButton.vue +1 -1
  51. package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +152 -60
  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 +60 -69
  58. package/src/components/PlAnnotations/components/PlAnnotations.vue +3 -7
  59. package/src/components/PlAnnotations/components/PlAnnotationsModal.vue +4 -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.d.ts +0 -37
  63. package/dist/components/PlAdvancedFilter/SingleFilter.vue.js +0 -10
  64. package/dist/components/PlAdvancedFilter/SingleFilter.vue.js.map +0 -1
  65. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js +0 -306
  66. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js.map +0 -1
  67. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js +0 -35
  68. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js.map +0 -1
  69. package/dist/components/PlAdvancedFilter/types.js +0 -8
  70. package/dist/components/PlAdvancedFilter/types.js.map +0 -1
  71. package/dist/components/PlAnnotations/components/DynamicForm.vue.d.ts +0 -24
  72. package/dist/components/PlAnnotations/components/DynamicForm.vue.js +0 -10
  73. package/dist/components/PlAnnotations/components/DynamicForm.vue.js.map +0 -1
  74. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js +0 -109
  75. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js.map +0 -1
  76. package/dist/components/PlAnnotations/components/DynamicForm.vue3.js +0 -9
  77. package/dist/components/PlAnnotations/components/DynamicForm.vue3.js.map +0 -1
  78. package/dist/components/PlAnnotations/utils.js +0 -20
  79. 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,29 @@
1
1
  <script lang="ts">
2
2
  export type Props = {
3
- columns: SimplifiedUniversalPColumnEntry[];
3
+ columns: PlAdvancedFilterItem[];
4
+
5
+ getSuggestOptions: (params: { columnId: PlAdvancedFilterColumnId; axisIdx?: number; searchStr: string; searchType: 'value' | 'label' }) =>
6
+ ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;
7
+
4
8
  hasSelectedColumns?: boolean;
5
9
  getValuesForSelectedColumns?: () => Promise<undefined | { columnId: PObjectId; values: string[] }>;
6
10
  };
7
11
  </script>
8
12
  <script setup lang="ts">
9
- import { isNil, randomInt } from '@milaboratories/helpers';
10
- import type {
11
- FilterSpecTypeFieldRecord,
12
- } from '@milaboratories/uikit';
13
+ import { randomInt } from '@milaboratories/helpers';
13
14
  import {
14
- getFilterUiMetadata,
15
15
  PlBtnSecondary,
16
16
  PlEditableTitle,
17
- PlElementList,
18
17
  PlSidebarItem,
19
18
  } from '@milaboratories/uikit';
20
- import type { FilterSpecLeaf, PObjectId, SimplifiedUniversalPColumnEntry, SUniversalPColumnId } from '@platforma-sdk/model';
19
+ import type { ListOptionBase, PObjectId, SUniversalPColumnId } from '@platforma-sdk/model';
21
20
  import { computed } from 'vue';
22
- import type { Filter, FilterSpec } from '../types';
23
- import { createDefaultFilterMetadata } from '../utils';
24
- import DynamicForm from './DynamicForm.vue';
21
+ import type { PlAdvancedFilterFilter, PlAdvancedFilterSupportedFilters } from '../../PlAdvancedFilter';
22
+ import { PlAdvancedFilter, type PlAdvancedFilterItem } from '../../PlAdvancedFilter';
23
+ import type { PlAdvancedFilterColumnId } from '../../PlAdvancedFilter/types';
24
+ import type { Filter } from '../types';
25
+
26
+ import $commonStyle from './style.module.css';
25
27
 
26
28
  // Models
27
29
  const step = defineModel<Filter>('step', { required: true });
@@ -36,7 +38,14 @@ const addFilterPlaceholder = () => {
36
38
  step.value.filter.filters.push({
37
39
  id: randomInt(),
38
40
  isExpanded: true,
39
- type: undefined,
41
+ type: 'or',
42
+ filters: [
43
+ {
44
+ id: randomInt(),
45
+ type: 'isNA',
46
+ column: props.columns[0].id as SUniversalPColumnId,
47
+ },
48
+ ],
40
49
  });
41
50
  };
42
51
 
@@ -63,26 +72,22 @@ async function addFilterFromSelected() {
63
72
  });
64
73
  }
65
74
 
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
- };
75
+ const supportedFilters = [
76
+ 'isNA',
77
+ 'isNotNA',
78
+ 'greaterThan',
79
+ 'greaterThanOrEqual',
80
+ 'lessThan',
81
+ 'lessThanOrEqual',
82
+ 'patternEquals',
83
+ 'patternNotEquals',
84
+ 'patternContainSubsequence',
85
+ 'patternNotContainSubsequence',
86
+ 'equal',
87
+ 'notEqual',
88
+ 'topN',
89
+ 'bottomN',
90
+ ] as typeof PlAdvancedFilterSupportedFilters[number][];
86
91
  </script>
87
92
 
88
93
  <template>
@@ -91,53 +96,39 @@ const getFilterValues = (filter: FilterSpec) => {
91
96
  <PlEditableTitle
92
97
  :key="step.id"
93
98
  v-model="step.label"
99
+ :class="{ [$commonStyle.flashing]: step.label.length === 0 }"
94
100
  :max-length="40"
95
101
  max-width="600px"
96
- placeholder="Annotation Name"
102
+ placeholder="Filter Name"
97
103
  :autofocus="step.label.length === 0"
98
104
  />
99
105
  </template>
100
106
  <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>
107
+ <PlAdvancedFilter
108
+ v-model:filters="(step.filter as PlAdvancedFilterFilter)"
109
+ :class="[$style.root, { [$commonStyle.disabled]: step.label.length === 0 }]"
110
+ :items="props.columns"
111
+ :supported-filters="supportedFilters"
112
+ :get-suggest-options="props.getSuggestOptions"
113
+ :enable-dnd="false"
114
+ :enable-add-group-button="true"
115
+ >
116
+ <template #add-group-buttons>
117
+ <div :class="$style.actions">
118
+ <PlBtnSecondary icon="add" @click="addFilterPlaceholder">
119
+ Add Filter
120
+ </PlBtnSecondary>
121
+ <PlBtnSecondary v-if="withSelection" icon="add" :disabled="!props.hasSelectedColumns" @click="addFilterFromSelected">
122
+ From selection
123
+ </PlBtnSecondary>
124
+ </div>
125
+ </template>
126
+ </PlAdvancedFilter>
134
127
  </template>
135
128
  </PlSidebarItem>
136
129
  </template>
137
130
 
138
- <style lang="scss" module>
139
- @use '@milaboratories/uikit/styles/variables' as *;
140
-
131
+ <style module>
141
132
  .root {
142
133
  display: flex;
143
134
  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,7 @@ async function handleDeleteSchema() {
67
67
  v-model:step="selectedStep"
68
68
  :class="$style.sidebarItem"
69
69
  :columns="props.columns"
70
+ :get-suggest-options="props.getSuggestOptions"
70
71
  :selectedStepId="selectedStepId"
71
72
  :hasSelectedColumns="props.hasSelectedColumns"
72
73
  :getValuesForSelectedColumns="props.getValuesForSelectedColumns"
@@ -75,12 +76,7 @@ async function handleDeleteSchema() {
75
76
  </PlSidebarGroup>
76
77
  </template>
77
78
 
78
- <style lang="scss" module>
79
- .sidebarGroup {
80
- width: 100%;
81
- height: 100%;
82
- }
83
-
79
+ <style module>
84
80
  .sidebarItem {
85
81
  width: 100%;
86
82
  height: 100%;
@@ -30,8 +30,9 @@ 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-options="props.getSuggestOptions"
35
36
  :has-selected-columns="props.hasSelectedColumns"
36
37
  :getValuesForSelectedColumns="props.getValuesForSelectedColumns"
37
38
  @delete-schema="handleDeleteSchema"
@@ -39,17 +40,12 @@ async function handleDeleteSchema() {
39
40
  </PlPureSlideModal>
40
41
  </template>
41
42
 
42
- <style lang="scss" module>
43
+ <style module>
43
44
  .modal {
44
45
  display: flex;
45
46
  }
46
47
 
47
- .sidebarGroup {
48
- width: 100%;
49
- height: 100%;
50
- }
51
-
52
- .sidebarItem {
48
+ .content {
53
49
  width: 100%;
54
50
  height: 100%;
55
51
  }
@@ -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,37 +0,0 @@
1
- import { PlAdvancedFilterColumnId, Filter, Operand, SourceOptionInfo } from './types';
2
- import { SUniversalPColumnId, ListOptionBase } from '@platforma-sdk/model';
3
- type __VLS_Props = {
4
- operand: Operand;
5
- columnOptions: SourceOptionInfo[];
6
- enableDnd: boolean;
7
- isLast: boolean;
8
- getSuggestOptions: (params: {
9
- columnId: PlAdvancedFilterColumnId;
10
- searchStr: string;
11
- axisIdx?: number;
12
- }) => (Promise<ListOptionBase<string | number>[]>) | ((params: {
13
- columnId: SUniversalPColumnId;
14
- searchStr: string;
15
- axisIdx?: number;
16
- }) => ListOptionBase<string | number>[]);
17
- getSuggestModel: (params: {
18
- columnId: PlAdvancedFilterColumnId;
19
- searchStr: string;
20
- axisIdx?: number;
21
- }) => (Promise<ListOptionBase<string | number>>) | ((params: {
22
- columnId: PlAdvancedFilterColumnId;
23
- searchStr: string;
24
- axisIdx?: number;
25
- }) => ListOptionBase<string | number>);
26
- onDelete: (columnId: PlAdvancedFilterColumnId) => void;
27
- onChangeOperand: (op: Operand) => void;
28
- };
29
- type __VLS_PublicProps = {
30
- modelValue: Filter;
31
- } & __VLS_Props;
32
- declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
33
- "update:modelValue": (value: Filter) => any;
34
- }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
35
- "onUpdate:modelValue"?: ((value: Filter) => any) | undefined;
36
- }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
37
- export default _default;
@@ -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":";;;;;;"}