@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,150 @@
1
+ import { getTypeFromPColumnOrAxisSpec as c, parseJson as g, isFilteredPColumn as E, isAnchoredPColumnId as f, isAxisId as q, assertNever as x } from "@platforma-sdk/model";
2
+ import { isSupportedFilterType as T } from "./types.js";
3
+ import { DEFAULT_FILTERS as S, DEFAULT_FILTER_TYPE as h, SUPPORTED_FILTER_TYPES as d } from "./constants.js";
4
+ import { filterUiMetadata as m } from "@milaboratories/uikit";
5
+ import { ref as v, watch as o } from "vue";
6
+ function s(e) {
7
+ return !("column" in e) || e.type === void 0 || !T(e.type) ? null : e.type === "patternFuzzyContainSubsequence" ? {
8
+ ...e,
9
+ value: e.value,
10
+ wildcard: e.wildcard,
11
+ maxEdits: e.maxEdits ?? 2,
12
+ substitutionsOnly: e.substitutionsOnly ?? !1
13
+ } : { ...e };
14
+ }
15
+ let i = 0;
16
+ function u() {
17
+ return i++, String(i);
18
+ }
19
+ function p(e) {
20
+ if (e.type === "not") {
21
+ const n = p(e.filter);
22
+ return n ? {
23
+ not: !n.not,
24
+ operand: n.operand,
25
+ filters: n.filters,
26
+ id: u(),
27
+ expanded: n.expanded
28
+ } : null;
29
+ }
30
+ if (e.type === "and" || e.type === "or")
31
+ return {
32
+ operand: e.type,
33
+ not: !1,
34
+ filters: e.filters.map((n) => s(n)).filter((n) => n !== null),
35
+ id: u(),
36
+ expanded: e.expanded ?? !0
37
+ };
38
+ if (d.has(e.type)) {
39
+ const n = s(e);
40
+ return {
41
+ operand: "or",
42
+ not: !1,
43
+ filters: n ? [n] : [],
44
+ id: u(),
45
+ expanded: e.expanded ?? !0
46
+ };
47
+ }
48
+ return null;
49
+ }
50
+ function z(e) {
51
+ const n = {
52
+ operand: "or",
53
+ groups: []
54
+ };
55
+ if (e.type === "not")
56
+ return n;
57
+ if (e.type === "and" || e.type === "or")
58
+ n.operand = e.type, n.groups = e.filters.map(p).filter((t) => t !== null);
59
+ else if (d.has(e.type)) {
60
+ const t = p(e);
61
+ n.groups = t ? [t] : [];
62
+ }
63
+ return n.groups = n.groups.filter((t) => t.filters.length > 0), n;
64
+ }
65
+ function I(e) {
66
+ if (e.type === "isNA" || e.type === "isNotNA" || e.type === "inSet" || e.type === "notInSet")
67
+ return e;
68
+ if (e.type === "greaterThanOrEqual" || e.type === "lessThanOrEqual" || e.type === "greaterThan" || e.type === "lessThan" || e.type === "equal" || e.type === "notEqual")
69
+ return e.x !== void 0 ? { ...e, x: e.x } : null;
70
+ if (e.type === "patternEquals" || e.type === "patternNotEquals" || e.type === "patternContainSubsequence" || e.type === "patternNotContainSubsequence" || e.type === "patternMatchesRegularExpression" || e.type === "patternFuzzyContainSubsequence")
71
+ return e.value !== void 0 ? { ...e, value: e.value } : null;
72
+ x(e.type);
73
+ }
74
+ function C(e) {
75
+ const n = {
76
+ type: e.operand,
77
+ expanded: e.expanded,
78
+ filters: e.filters.map(I).filter((t) => t !== null)
79
+ };
80
+ return e.not ? {
81
+ type: "not",
82
+ filter: n
83
+ } : n;
84
+ }
85
+ function A(e) {
86
+ return {
87
+ type: e.operand,
88
+ filters: e.groups.map(C)
89
+ };
90
+ }
91
+ function P(e) {
92
+ return {
93
+ id: u(),
94
+ not: !1,
95
+ operand: "and",
96
+ expanded: !0,
97
+ filters: [{
98
+ ...S[h],
99
+ column: e
100
+ }]
101
+ };
102
+ }
103
+ function R(e) {
104
+ return { valueType: c(e), annotations: e.annotations, domain: e.domain };
105
+ }
106
+ function w(e) {
107
+ return e.type === "equal" || e.type === "notEqual" || e.type === "lessThan" || e.type === "lessThanOrEqual" || e.type === "greaterThan" || e.type === "greaterThanOrEqual";
108
+ }
109
+ function L(e) {
110
+ return e.type === "patternEquals" || e.type === "patternNotEquals" || e.type === "patternContainSubsequence" || e.type === "patternNotContainSubsequence" || e.type === "patternMatchesRegularExpression" || e.type === "patternFuzzyContainSubsequence";
111
+ }
112
+ function _(e) {
113
+ return m[e];
114
+ }
115
+ function G(e, n, t) {
116
+ const a = v(e(t.value));
117
+ function l(r) {
118
+ t.value = n(r);
119
+ }
120
+ function y(r) {
121
+ a.value = e(r);
122
+ }
123
+ return o(() => t.value, (r) => {
124
+ y(r);
125
+ }, { deep: !0 }), o(() => a.value, (r) => {
126
+ l(r);
127
+ }, { deep: !0 }), a;
128
+ }
129
+ function U(e) {
130
+ if (typeof e != "string")
131
+ return !1;
132
+ try {
133
+ const n = g(e);
134
+ return E(n) || f(n) || q(n);
135
+ } catch {
136
+ return !1;
137
+ }
138
+ }
139
+ export {
140
+ P as createNewGroup,
141
+ _ as getFilterInfo,
142
+ R as getNormalizedSpec,
143
+ w as isNumericFilter,
144
+ L as isStringFilter,
145
+ U as isValidColumnId,
146
+ z as toInnerModel,
147
+ A as toOuterModel,
148
+ G as useInnerModel
149
+ };
150
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sources":["../../../src/components/PlAdvancedFilter/utils.ts"],"sourcesContent":["import type { AnchoredPColumnId, AxisId, CanonicalizedJson, FilteredPColumnId, ValueType } from '@platforma-sdk/model';\nimport { assertNever, getTypeFromPColumnOrAxisSpec, isAnchoredPColumnId, isFilteredPColumn, parseJson, type AxisSpec, type PColumnSpec, type SUniversalPColumnId } from '@platforma-sdk/model';\nimport { type CommonFilterSpec, isSupportedFilterType, type Filter, type FilterType, type Group, type PlAdvancedFilterUI, type SupportedFilterTypes, type PlAdvancedFilterColumnId } from './types';\nimport { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS, SUPPORTED_FILTER_TYPES } from './constants';\nimport { filterUiMetadata } from '@milaboratories/uikit';\nimport { ref, watch, type ModelRef } from 'vue';\nimport { isAxisId } from '@platforma-sdk/model';\n\nfunction toInnerFilter(outerFilter: CommonFilterSpec): Filter | null {\n if (!('column' in outerFilter) || outerFilter.type === undefined || !isSupportedFilterType(outerFilter.type)) {\n return null;\n }\n if (outerFilter.type === 'patternFuzzyContainSubsequence') {\n return {\n ...outerFilter,\n value: outerFilter.value,\n wildcard: outerFilter.wildcard,\n maxEdits: outerFilter.maxEdits ?? 2,\n substitutionsOnly: outerFilter.substitutionsOnly ?? false,\n };\n }\n\n return { ...outerFilter } as Filter;\n}\n\nlet groupIdCounter = 0;\nfunction getNewGroupId() {\n groupIdCounter++;\n return String(groupIdCounter);\n}\n\nfunction toInnerFiltersGroup(f: CommonFilterSpec): Group | null {\n if (f.type === 'not') {\n const group = toInnerFiltersGroup(f.filter);\n return group\n ? {\n not: !group.not,\n operand: group.operand,\n filters: group.filters,\n id: getNewGroupId(),\n expanded: group.expanded,\n }\n : null;\n }\n if (f.type === 'and' || f.type === 'or') {\n return {\n operand: f.type,\n not: false,\n filters: f.filters.map((f) => toInnerFilter(f)).filter((v) => v !== null) as Filter[],\n id: getNewGroupId(),\n expanded: f.expanded ?? true,\n };\n }\n if (SUPPORTED_FILTER_TYPES.has(f.type as SupportedFilterTypes)) {\n const filter = toInnerFilter(f);\n return {\n operand: 'or',\n not: false,\n filters: filter ? [filter] : [],\n id: getNewGroupId(),\n expanded: f.expanded ?? true,\n };\n }\n return null;\n}\n\nexport function toInnerModel(m: CommonFilterSpec): PlAdvancedFilterUI {\n const res: PlAdvancedFilterUI = {\n operand: 'or',\n groups: [],\n };\n if (m.type === 'not') {\n return res; // not supported 'not' for all the groups in ui\n }\n if (m.type === 'and' || m.type === 'or') {\n // group\n res.operand = m.type;\n res.groups = m.filters.map(toInnerFiltersGroup).filter((v) => v !== null) as Group[];\n } else if (SUPPORTED_FILTER_TYPES.has(m.type as SupportedFilterTypes)) {\n // single filter\n const group = toInnerFiltersGroup(m);\n res.groups = group ? [group] : [];\n }\n res.groups = res.groups.filter((gr) => gr.filters.length > 0);\n return res;\n}\n\nfunction toOuterFilter(filter: Filter): CommonFilterSpec | null {\n if (\n filter.type === 'isNA' || filter.type === 'isNotNA'\n || filter.type === 'inSet' || filter.type === 'notInSet'\n ) {\n return filter;\n }\n if (\n filter.type === 'greaterThanOrEqual' || filter.type === 'lessThanOrEqual'\n || filter.type === 'greaterThan' || filter.type === 'lessThan'\n || filter.type === 'equal' || filter.type === 'notEqual'\n ) {\n return filter.x !== undefined ? { ...filter, x: filter.x } : null;\n }\n if (\n filter.type === 'patternEquals' || filter.type === 'patternNotEquals'\n || filter.type === 'patternContainSubsequence' || filter.type === 'patternNotContainSubsequence'\n || filter.type === 'patternMatchesRegularExpression'\n || filter.type === 'patternFuzzyContainSubsequence'\n ) {\n return filter.value !== undefined ? { ...filter, value: filter.value } : null;\n }\n assertNever(filter.type);\n}\n\nfunction toOuterFilterGroup(m: Group): CommonFilterSpec {\n const res: CommonFilterSpec = {\n type: m.operand,\n expanded: m.expanded,\n filters: m.filters.map(toOuterFilter).filter((v): v is CommonFilterSpec => v !== null),\n };\n if (m.not) {\n return {\n type: 'not',\n filter: res,\n } as CommonFilterSpec;\n }\n return res;\n}\nexport function toOuterModel(m: PlAdvancedFilterUI): CommonFilterSpec {\n return {\n type: m.operand,\n filters: m.groups.map(toOuterFilterGroup),\n };\n}\n\nexport function createNewGroup(selectedSourceId: string) {\n return {\n id: getNewGroupId(),\n not: false,\n operand: 'and' as const,\n expanded: true,\n filters: [{\n ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],\n column: selectedSourceId as SUniversalPColumnId,\n }],\n };\n}\n\nexport type NormalizedSpecData = {\n valueType: ValueType;\n annotations: PColumnSpec['annotations'];\n domain: PColumnSpec['domain'];\n};\nexport function getNormalizedSpec(spec: PColumnSpec | AxisSpec): NormalizedSpecData {\n return { valueType: getTypeFromPColumnOrAxisSpec(spec), annotations: spec.annotations, domain: spec.domain };\n}\n\nexport function isNumericValueType(spec?: PColumnSpec | AxisSpec): boolean {\n if (!spec) {\n return false;\n }\n const valueType = getNormalizedSpec(spec).valueType;\n return valueType === 'Int' || valueType === 'Long' || valueType === 'Float' || valueType === 'Double';\n}\n\nexport function isStringValueType(spec?: PColumnSpec | AxisSpec): boolean {\n if (!spec) {\n return false;\n }\n const valueType = getNormalizedSpec(spec).valueType;\n return valueType === 'String';\n}\n\nexport function isNumericFilter(filter: Filter): filter is Filter & { type: 'equal' | 'notEqual' | 'lessThan' | 'lessThanOrEqual' | 'greaterThan' | 'greaterThanOrEqual' } {\n return filter.type === 'equal' || filter.type === 'notEqual' || filter.type === 'lessThan' || filter.type === 'lessThanOrEqual' || filter.type === 'greaterThan' || filter.type === 'greaterThanOrEqual';\n}\nexport function isStringFilter(filter: Filter): filter is Filter & { type: 'patternEquals' | 'patternNotEquals' | 'patternContainSubsequence' | 'patternNotContainSubsequence' | 'patternMatchesRegularExpression' | 'patternFuzzyContainSubsequence' } {\n return filter.type === 'patternEquals' || filter.type === 'patternNotEquals' || filter.type === 'patternContainSubsequence' || filter.type === 'patternNotContainSubsequence' || filter.type === 'patternMatchesRegularExpression' || filter.type === 'patternFuzzyContainSubsequence';\n}\n\nexport function getFilterInfo(filterType: FilterType): { label: string; supportedFor: (spec: NormalizedSpecData) => boolean } {\n return filterUiMetadata[filterType as keyof typeof filterUiMetadata];\n}\n\nexport function useInnerModel<T, V>(\n toInnerModel: (v: T) => V,\n toOuterModel: (v: V) => T,\n model: ModelRef<T>,\n) {\n const innerModel = ref<V>(toInnerModel(model.value));\n function updateOuterModelValue(v: V) {\n model.value = toOuterModel(v);\n }\n function updateInnerModelValue(v: T) {\n innerModel.value = toInnerModel(v);\n }\n watch(() => model.value, (v: T) => {\n updateInnerModelValue(v);\n }, { deep: true });\n watch(() => innerModel.value, (v: V) => {\n updateOuterModelValue(v);\n }, { deep: true });\n\n return innerModel;\n}\n\nexport function isValidColumnId(id: unknown): id is PlAdvancedFilterColumnId {\n if (typeof id !== 'string') {\n return false;\n }\n try {\n const parsedId = parseJson<FilteredPColumnId | AnchoredPColumnId | AxisId>(id as CanonicalizedJson<FilteredPColumnId | AnchoredPColumnId | AxisId>);\n return isFilteredPColumn(parsedId) || isAnchoredPColumnId(parsedId) || isAxisId(parsedId);\n } catch {\n return false;\n }\n}\n"],"names":["toInnerFilter","outerFilter","isSupportedFilterType","groupIdCounter","getNewGroupId","toInnerFiltersGroup","f","group","v","SUPPORTED_FILTER_TYPES","filter","toInnerModel","m","res","gr","toOuterFilter","assertNever","toOuterFilterGroup","toOuterModel","createNewGroup","selectedSourceId","DEFAULT_FILTERS","DEFAULT_FILTER_TYPE","getNormalizedSpec","spec","getTypeFromPColumnOrAxisSpec","isNumericFilter","isStringFilter","getFilterInfo","filterType","filterUiMetadata","useInnerModel","model","innerModel","ref","updateOuterModelValue","updateInnerModelValue","watch","isValidColumnId","id","parsedId","parseJson","isFilteredPColumn","isAnchoredPColumnId","isAxisId"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -12,8 +12,8 @@ import { default as x } from "./components/PlAgDataTable/PlAgOverlayNoRows.vue.j
12
12
  import { default as A } from "./components/ValueOrErrorsComponent.vue.js";
13
13
  import { useAgGridOptions as C } from "./AgGridVue/useAgGridOptions.js";
14
14
  import { createAgGridColDef as b } from "./AgGridVue/createAgGridColDef.js";
15
- import { deselectAll as w, getSelectedRowsCount as R, getTotalRowsCount as S, isSelectionEnabled as T, selectAll as D } from "./AgGridVue/selection.js";
16
- import { default as v } from "./components/PlAgColumnHeader/PlAgColumnHeader.vue.js";
15
+ import { deselectAll as w, getSelectedRowsCount as R, getTotalRowsCount as S, isSelectionEnabled as T, selectAll as v } from "./AgGridVue/selection.js";
16
+ import { default as V } from "./components/PlAgColumnHeader/PlAgColumnHeader.vue.js";
17
17
  import { default as O } from "./components/PlAgCellFile/PlAgCellFile.vue.js";
18
18
  import { default as G } from "./components/PlAgCellProgress/PlAgCellProgress.vue.js";
19
19
  import { default as k } from "./components/PlAgCellStatusTag/PlAgCellStatusTag.vue.js";
@@ -34,26 +34,28 @@ import { default as ae } from "./components/PlMultiSequenceAlignment/PlMultiSequ
34
34
  import { default as me } from "./components/PlAnnotations/components/PlAnnotations.vue.js";
35
35
  import { default as pe } from "./components/PlAnnotations/components/PlAnnotationsModal.vue.js";
36
36
  import { default as de } from "./components/PlBtnExportArchive/PlBtnExportArchive.vue.js";
37
- import { defineApp as ne, useSdkPlugin as xe } from "./defineApp.js";
38
- import { createModel as Ae } from "./createModel.js";
39
- import { defineStore as Ce } from "./defineStore.js";
40
- import { AgGridTheme as be, activateAgGrid as Ee } from "./aggrid.js";
41
- import { MultiError as Re, UnresolvedError as Se, ensureError as Te, formatZodError as De, identity as Ve, isDefined as ve, isZodError as Me, unwrapValueOrErrors as Oe, wrapOptionalResult as he, wrapValueOrErrors as Ge } from "./utils.js";
42
- import { objectHash as ke } from "./objectHash.js";
43
- import { computedResult as Be } from "./computedResult.js";
44
- import { ReactiveFileContent as He } from "./composition/fileContent.js";
37
+ import { default as ne } from "./components/PlAdvancedFilter/PlAdvancedFilter.vue.js";
38
+ import { defineApp as ge, useSdkPlugin as Ae } from "./defineApp.js";
39
+ import { createModel as Ce } from "./createModel.js";
40
+ import { defineStore as be } from "./defineStore.js";
41
+ import { AgGridTheme as we, activateAgGrid as Re } from "./aggrid.js";
42
+ import { MultiError as Te, UnresolvedError as ve, ensureError as De, formatZodError as Ve, identity as Me, isDefined as Oe, isZodError as he, unwrapValueOrErrors as Ge, wrapOptionalResult as Ne, wrapValueOrErrors as ke } from "./utils.js";
43
+ import { objectHash as Be } from "./objectHash.js";
44
+ import { computedResult as He } from "./computedResult.js";
45
+ import { ReactiveFileContent as Le } from "./composition/fileContent.js";
45
46
  export * from "@milaboratories/uikit";
46
47
  export {
47
- be as AgGridTheme,
48
+ we as AgGridTheme,
48
49
  m as BlockLayout,
49
50
  J as DeferredCircular,
50
- Re as MultiError,
51
+ Te as MultiError,
52
+ ne as PlAdvancedFilter,
51
53
  O as PlAgCellFile,
52
54
  G as PlAgCellProgress,
53
55
  k as PlAgCellStatusTag,
54
56
  B as PlAgChartHistogramCell,
55
57
  H as PlAgChartStackedBarCell,
56
- v as PlAgColumnHeader,
58
+ V as PlAgColumnHeader,
57
59
  Y as PlAgCsvExporter,
58
60
  j as PlAgDataTableRowNumberColId,
59
61
  p as PlAgDataTableV2,
@@ -67,35 +69,35 @@ export {
67
69
  u as PlDataTableV2,
68
70
  ae as PlMultiSequenceAlignment,
69
71
  te as PlTableFiltersV2,
70
- He as ReactiveFileContent,
71
- Se as UnresolvedError,
72
+ Le as ReactiveFileContent,
73
+ ve as UnresolvedError,
72
74
  A as ValueOrErrorsComponent,
73
- Ee as activateAgGrid,
75
+ Re as activateAgGrid,
74
76
  q as autoSizeRowNumberColumn,
75
- Be as computedResult,
77
+ He as computedResult,
76
78
  b as createAgGridColDef,
77
- Ae as createModel,
79
+ Ce as createModel,
78
80
  W as defaultMainMenuItems,
79
- ne as defineApp,
80
- Ce as defineStore,
81
+ ge as defineApp,
82
+ be as defineStore,
81
83
  w as deselectAll,
82
- Te as ensureError,
84
+ De as ensureError,
83
85
  K as ensureNodeVisible,
84
- De as formatZodError,
86
+ Ve as formatZodError,
85
87
  R as getSelectedRowsCount,
86
88
  S as getTotalRowsCount,
87
- Ve as identity,
88
- ve as isDefined,
89
+ Me as identity,
90
+ Oe as isDefined,
89
91
  T as isSelectionEnabled,
90
- Me as isZodError,
92
+ he as isZodError,
91
93
  z as makeRowNumberColDef,
92
- ke as objectHash,
93
- D as selectAll,
94
- Oe as unwrapValueOrErrors,
94
+ Be as objectHash,
95
+ v as selectAll,
96
+ Ge as unwrapValueOrErrors,
95
97
  C as useAgGridOptions,
96
98
  L as usePlDataTableSettingsV2,
97
- xe as useSdkPlugin,
98
- he as wrapOptionalResult,
99
- Ge as wrapValueOrErrors
99
+ Ae as useSdkPlugin,
100
+ Ne as wrapOptionalResult,
101
+ ke as wrapValueOrErrors
100
102
  };
101
103
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/lib.d.ts CHANGED
@@ -19,6 +19,7 @@ export * from './components/PlTableFilters';
19
19
  export * from './components/PlMultiSequenceAlignment';
20
20
  export * from './components/PlAnnotations';
21
21
  export * from './components/PlBtnExportArchive';
22
+ export * from './components/PlAdvancedFilter';
22
23
  export * from './defineApp';
23
24
  export * from './createModel';
24
25
  export * from './types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/ui-vue",
3
- "version": "1.45.34",
3
+ "version": "1.45.35",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "styles": "dist/index.js",
@@ -27,9 +27,9 @@
27
27
  "zod": "~3.23.8",
28
28
  "@zip.js/zip.js": "^2.8.2",
29
29
  "@milaboratories/biowasm-tools": "2.0.0",
30
- "@milaboratories/uikit": "2.6.1",
31
- "@platforma-sdk/model": "1.45.30",
32
- "@milaboratories/ptabler-expression-js": "1.1.2"
30
+ "@milaboratories/ptabler-expression-js": "1.1.3",
31
+ "@platforma-sdk/model": "1.45.35",
32
+ "@milaboratories/uikit": "2.6.2"
33
33
  },
34
34
  "devDependencies": {
35
35
  "happy-dom": "^15.11.7",
@@ -44,11 +44,11 @@
44
44
  "yarpm": "^1.2.0",
45
45
  "fast-json-patch": "^3.1.1",
46
46
  "@faker-js/faker": "^9.2.0",
47
+ "@milaboratories/ts-configs": "1.0.6",
47
48
  "@milaboratories/eslint-config": "1.0.5",
49
+ "@milaboratories/ts-builder": "1.0.5",
48
50
  "@milaboratories/build-configs": "1.0.8",
49
- "@milaboratories/helpers": "1.12.0",
50
- "@milaboratories/ts-configs": "1.0.6",
51
- "@milaboratories/ts-builder": "1.0.5"
51
+ "@milaboratories/helpers": "1.12.0"
52
52
  },
53
53
  "scripts": {
54
54
  "test": "vitest run --passWithNoTests",
@@ -0,0 +1,53 @@
1
+ <script lang="ts" setup>
2
+ import type { Operand } from './types';
3
+
4
+ const props = defineProps<{
5
+ active: Operand;
6
+ disabled: boolean;
7
+ onSelect: (op: Operand) => void;
8
+ }>();
9
+
10
+ const OPTIONS: Operand[] = ['and', 'or'];
11
+ </script>
12
+ <template>
13
+ <div v-bind="$attrs" :class="$style.block">
14
+ <div
15
+ v-for="op in OPTIONS"
16
+ :key="op"
17
+ :class="[$style.operand, {[$style.active]: op === props.active && !props.disabled}]"
18
+ @click="!props.disabled && props.onSelect(op)"
19
+ >
20
+ {{ op }}
21
+ </div>
22
+ </div>
23
+ </template>
24
+ <style module>
25
+ .block {
26
+ width: 100%;
27
+ display: flex;
28
+ gap: 4px;
29
+ justify-content: center;
30
+ height: 72px;
31
+ align-items: center;
32
+ }
33
+ .operand {
34
+ border-radius: 16px;
35
+ width: 64px;
36
+ height: 32px;
37
+ display: flex;
38
+ justify-content: center;
39
+ align-items: center;
40
+ text-transform: uppercase;
41
+ font-weight: 600;
42
+
43
+ color: var(--txt-03);
44
+ border: 1px solid var(--color-div-grey);
45
+ background: transparent;
46
+ cursor: pointer;
47
+ }
48
+ .operand.active {
49
+ color: var(--txt-01);
50
+ background: #fff;
51
+ border: 1px solid var(--txt-01);
52
+ }
53
+ </style>
@@ -0,0 +1,209 @@
1
+ <script lang="ts" setup>
2
+ import SingleFilter from './SingleFilter.vue';
3
+ import { PlBtnSecondary, PlElementList, PlCheckbox, PlIcon16 } from '@milaboratories/uikit';
4
+ import type { PlAdvancedFilterColumnId, CommonFilterSpec, Group, PlAdvancedFilterUI, SourceOptionInfo } from './types';
5
+ import { computed } from 'vue';
6
+ import OperandButton from './OperandButton.vue';
7
+ import { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS } from './constants';
8
+ import type { ListOptionBase } from '@platforma-sdk/model';
9
+ import { createNewGroup, isValidColumnId, toInnerModel, toOuterModel, useInnerModel } from './utils';
10
+
11
+ const props = withDefaults(defineProps<{
12
+ /** List of ids of sources (columns, axes) that can be selected in filters */
13
+ items: SourceOptionInfo[];
14
+ /** If true - new filter can be added by droppind element into filter group; else new column is added by button click */
15
+ enableDnd?: boolean;
16
+ /** Loading function for unique values for Equal/InSet filters and fixed axes options. */
17
+ getSuggestOptions: (params: { columnId: PlAdvancedFilterColumnId; searchStr: string; axisIdx?: number }) => (Promise<ListOptionBase<string | number>[]>) |
18
+ ((params: { columnId: PlAdvancedFilterColumnId; searchStr: string; axisIdx?: number }) => ListOptionBase<string | number>[]);
19
+ /** Loading function for label of selected value for Equal/InSet filters and fixed axes options. */
20
+ getSuggestModel: (params: { columnId: PlAdvancedFilterColumnId; searchStr: string; axisIdx?: number }) => (Promise<ListOptionBase<string | number>>) |
21
+ ((params: { columnId: PlAdvancedFilterColumnId; searchStr: string; axisIdx?: number }) => ListOptionBase<string | number>);
22
+ }>(), { enableDnd: false });
23
+
24
+ const model = defineModel<CommonFilterSpec>({ required: true });
25
+ const innerModel = useInnerModel<CommonFilterSpec, PlAdvancedFilterUI>(toInnerModel, toOuterModel, model);
26
+
27
+ const firstColumnId = computed(() => props.items[0]?.id);
28
+ const emptyGroup: Group[] = [{
29
+ id: 'empty',
30
+ not: false,
31
+ operand: 'and',
32
+ filters: [],
33
+ expanded: true,
34
+ }];
35
+
36
+ function addColumnToGroup(groupIdx: number, selectedSourceId: PlAdvancedFilterColumnId) {
37
+ innerModel.value.groups[groupIdx].filters.push({
38
+ ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],
39
+ column: selectedSourceId,
40
+ });
41
+ }
42
+
43
+ function removeFilterFromGroup(groupIdx: number, filterIdx: number) {
44
+ if (innerModel.value.groups[groupIdx].filters.length === 1 && filterIdx === 0) {
45
+ removeGroup(groupIdx);
46
+ } else {
47
+ innerModel.value.groups[groupIdx].filters = innerModel.value.groups[groupIdx].filters.filter((_v, idx) => idx !== filterIdx);
48
+ }
49
+ }
50
+
51
+ function removeGroup(groupIdx: number) {
52
+ innerModel.value.groups = innerModel.value.groups.filter((v, idx) => idx !== groupIdx);
53
+ }
54
+ function addGroup(selectedSourceId: PlAdvancedFilterColumnId) {
55
+ const newGroup = createNewGroup(selectedSourceId);
56
+ innerModel.value.groups.push(newGroup);
57
+ }
58
+
59
+ function handleDropToExistingGroup(groupIdx: number, event: DragEvent) {
60
+ const dataTransfer = event.dataTransfer;
61
+ if (dataTransfer?.getData('text/plain')) {
62
+ const draggedId = dataTransfer.getData('text/plain');
63
+ if (isValidColumnId(draggedId)) {
64
+ addColumnToGroup(groupIdx, draggedId);
65
+ }
66
+ }
67
+ }
68
+ function handleDropToNewGroup(event: DragEvent) {
69
+ const dataTransfer = event.dataTransfer;
70
+ if (dataTransfer?.getData('text/plain')) {
71
+ const draggedId = dataTransfer.getData('text/plain');
72
+ if (isValidColumnId(draggedId)) {
73
+ addGroup(draggedId);
74
+ }
75
+ }
76
+ }
77
+ function dragOver(event: DragEvent) {
78
+ event.preventDefault();
79
+ }
80
+ </script>
81
+ <template>
82
+ <div>
83
+ <PlElementList
84
+ v-model:items="innerModel.groups"
85
+ :get-item-key="(group) => group.id"
86
+
87
+ :item-class="$style.filterGroup"
88
+ :item-class-content="$style.filterGroupContent"
89
+ :item-class-title="$style.filterGroupTitle"
90
+
91
+ :is-expanded="(group) => group.expanded"
92
+
93
+ :disableDragging="false"
94
+ :disableRemoving="false"
95
+ :disableToggling="true"
96
+ :disablePinning="true"
97
+
98
+ :on-expand="(group) => { group.expanded = !group.expanded}"
99
+ >
100
+ <template #item-title>
101
+ Filter group
102
+ </template>
103
+ <template #item-content="{ item, index }">
104
+ <div
105
+ :class="$style.groupContent" dropzone="true"
106
+ @drop="(event) => handleDropToExistingGroup(index, event)"
107
+ @dragover="dragOver"
108
+ >
109
+ <PlCheckbox v-model="item.not">NOT</PlCheckbox>
110
+ <SingleFilter
111
+ v-for="(filter, filterIdx) in item.filters"
112
+ :key="filterIdx"
113
+ v-model="item.filters[filterIdx]"
114
+ :operand="item.operand"
115
+ :column-options="items"
116
+ :get-suggest-model="getSuggestModel"
117
+ :get-suggest-options="getSuggestOptions"
118
+ :enable-dnd="enableDnd"
119
+ :is-last="filterIdx === item.filters.length - 1"
120
+ :on-change-operand="(v) => item.operand = v"
121
+ :on-delete="() => removeFilterFromGroup(index, filterIdx)"
122
+ />
123
+ <div v-if="enableDnd" :class="$style.dropzone">
124
+ <div>Drop dimensions here</div>
125
+ </div>
126
+ <PlBtnSecondary v-else @click="addColumnToGroup(index, firstColumnId)">
127
+ <PlIcon16 name="add" style="margin-right: 8px"/>Add column
128
+ </PlBtnSecondary>
129
+ </div>
130
+ </template>
131
+ <template #item-after="{ index }">
132
+ <OperandButton
133
+ :class="$style.buttonWrapper"
134
+ :active="innerModel.operand"
135
+ :disabled="index === innerModel.groups.length - 1"
136
+ :on-select="(v) => innerModel.operand = v"
137
+ />
138
+ </template>
139
+ </PlElementList>
140
+
141
+ <!-- Last group - always exists, always empty, just for adding new groups -->
142
+ <PlElementList
143
+ v-model:items="emptyGroup"
144
+ :get-item-key="(group) => group.id"
145
+ :item-class="$style.filterGroup"
146
+ :item-class-content="$style.filterGroupContent"
147
+ :item-class-title="$style.filterGroupTitle"
148
+
149
+ :is-expanded="() => true"
150
+
151
+ :disableDragging="true"
152
+ :disableRemoving="true"
153
+ :disableToggling="true"
154
+ :disablePinning="true"
155
+ dropzone="true"
156
+ @drop="handleDropToNewGroup"
157
+ @dragover="dragOver"
158
+ >
159
+ <template #item-title>Filter group</template>
160
+ <template #item-content="{item}">
161
+ <PlCheckbox v-model="item.not" disabled >NOT</PlCheckbox>
162
+ <div v-if="enableDnd" :class="$style.dropzone">
163
+ <div>Drop dimensions here</div>
164
+ </div>
165
+ <PlBtnSecondary v-else @click="addGroup(firstColumnId)">
166
+ <PlIcon16 name="add" style="margin-right: 8px"/>Add column
167
+ </PlBtnSecondary>
168
+ </template>
169
+ </PlElementList>
170
+ </div>
171
+ </template>
172
+ <style module>
173
+ .filterGroup {
174
+ background: var(--bg-base-light);
175
+ }
176
+ .filterGroup:hover {
177
+ background: rgba(99, 224, 36, 0.12);
178
+ }
179
+ .filterGroupTitle {
180
+ background: none;
181
+ }
182
+ .groupContent {
183
+ display: flex;
184
+ flex-direction: column;
185
+ gap: 12px;
186
+ }
187
+ .dropzone {
188
+ border-radius: 6px;
189
+ border: 1.5px dashed var(--color-div-grey);
190
+ color: var(--txt-03);
191
+ font-family: Manrope;
192
+ font-size: 14px;
193
+ font-style: normal;
194
+ font-weight: 500;
195
+ height: 40px;
196
+ cursor: default;
197
+ display: flex;
198
+ justify-content: center;
199
+ align-items: center;
200
+ }
201
+ .buttonWrapper {
202
+ height: 72px;
203
+ display: flex;
204
+ align-items: center;
205
+ }
206
+ :global(.sortable-chosen) .buttonWrapper {
207
+ visibility: hidden;
208
+ }
209
+ </style>