@platforma-sdk/ui-vue 1.45.34 → 1.45.35

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 (45) hide show
  1. package/.turbo/turbo-build.log +31 -6
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +10 -0
  4. package/dist/components/PlAdvancedFilter/OperandButton.vue.d.ts +8 -0
  5. package/dist/components/PlAdvancedFilter/OperandButton.vue.js +10 -0
  6. package/dist/components/PlAdvancedFilter/OperandButton.vue.js.map +1 -0
  7. package/dist/components/PlAdvancedFilter/OperandButton.vue2.js +25 -0
  8. package/dist/components/PlAdvancedFilter/OperandButton.vue2.js.map +1 -0
  9. package/dist/components/PlAdvancedFilter/OperandButton.vue3.js +13 -0
  10. package/dist/components/PlAdvancedFilter/OperandButton.vue3.js.map +1 -0
  11. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts +39 -0
  12. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.js +10 -0
  13. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.js.map +1 -0
  14. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js +199 -0
  15. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js.map +1 -0
  16. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue3.js +17 -0
  17. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue3.js.map +1 -0
  18. package/dist/components/PlAdvancedFilter/SingleFilter.vue.d.ts +37 -0
  19. package/dist/components/PlAdvancedFilter/SingleFilter.vue.js +10 -0
  20. package/dist/components/PlAdvancedFilter/SingleFilter.vue.js.map +1 -0
  21. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js +306 -0
  22. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js.map +1 -0
  23. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js +35 -0
  24. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js.map +1 -0
  25. package/dist/components/PlAdvancedFilter/constants.d.ts +4 -0
  26. package/dist/components/PlAdvancedFilter/constants.js +41 -0
  27. package/dist/components/PlAdvancedFilter/constants.js.map +1 -0
  28. package/dist/components/PlAdvancedFilter/index.d.ts +1 -0
  29. package/dist/components/PlAdvancedFilter/types.d.ts +57 -0
  30. package/dist/components/PlAdvancedFilter/types.js +8 -0
  31. package/dist/components/PlAdvancedFilter/types.js.map +1 -0
  32. package/dist/components/PlAdvancedFilter/utils.js +150 -0
  33. package/dist/components/PlAdvancedFilter/utils.js.map +1 -0
  34. package/dist/index.js +33 -31
  35. package/dist/index.js.map +1 -1
  36. package/dist/lib.d.ts +1 -0
  37. package/package.json +7 -7
  38. package/src/components/PlAdvancedFilter/OperandButton.vue +53 -0
  39. package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +209 -0
  40. package/src/components/PlAdvancedFilter/SingleFilter.vue +425 -0
  41. package/src/components/PlAdvancedFilter/constants.ts +42 -0
  42. package/src/components/PlAdvancedFilter/index.ts +1 -0
  43. package/src/components/PlAdvancedFilter/types.ts +77 -0
  44. package/src/components/PlAdvancedFilter/utils.ts +215 -0
  45. package/src/lib.ts +2 -0
@@ -0,0 +1,215 @@
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
+ 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
+ }
112
+
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
+ };
132
+ }
133
+
134
+ export function createNewGroup(selectedSourceId: string) {
135
+ return {
136
+ id: getNewGroupId(),
137
+ not: false,
138
+ operand: 'and' as const,
139
+ expanded: true,
140
+ filters: [{
141
+ ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],
142
+ column: selectedSourceId as SUniversalPColumnId,
143
+ }],
144
+ };
145
+ }
146
+
147
+ export type NormalizedSpecData = {
148
+ valueType: ValueType;
149
+ annotations: PColumnSpec['annotations'];
150
+ domain: PColumnSpec['domain'];
151
+ };
152
+ export function getNormalizedSpec(spec: PColumnSpec | AxisSpec): NormalizedSpecData {
153
+ return { valueType: getTypeFromPColumnOrAxisSpec(spec), annotations: spec.annotations, domain: spec.domain };
154
+ }
155
+
156
+ export function isNumericValueType(spec?: PColumnSpec | AxisSpec): boolean {
157
+ if (!spec) {
158
+ return false;
159
+ }
160
+ const valueType = getNormalizedSpec(spec).valueType;
161
+ return valueType === 'Int' || valueType === 'Long' || valueType === 'Float' || valueType === 'Double';
162
+ }
163
+
164
+ export function isStringValueType(spec?: PColumnSpec | AxisSpec): boolean {
165
+ if (!spec) {
166
+ return false;
167
+ }
168
+ const valueType = getNormalizedSpec(spec).valueType;
169
+ return valueType === 'String';
170
+ }
171
+
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';
177
+ }
178
+
179
+ export function getFilterInfo(filterType: FilterType): { label: string; supportedFor: (spec: NormalizedSpecData) => boolean } {
180
+ return filterUiMetadata[filterType as keyof typeof filterUiMetadata];
181
+ }
182
+
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
+ export function isValidColumnId(id: unknown): id is PlAdvancedFilterColumnId {
206
+ if (typeof id !== 'string') {
207
+ return false;
208
+ }
209
+ try {
210
+ const parsedId = parseJson<FilteredPColumnId | AnchoredPColumnId | AxisId>(id as CanonicalizedJson<FilteredPColumnId | AnchoredPColumnId | AxisId>);
211
+ return isFilteredPColumn(parsedId) || isAnchoredPColumnId(parsedId) || isAxisId(parsedId);
212
+ } catch {
213
+ return false;
214
+ }
215
+ }
package/src/lib.ts CHANGED
@@ -34,6 +34,8 @@ export * from './components/PlAnnotations';
34
34
 
35
35
  export * from './components/PlBtnExportArchive';
36
36
 
37
+ export * from './components/PlAdvancedFilter';
38
+
37
39
  export * from './defineApp';
38
40
 
39
41
  export * from './createModel';