@platforma-sdk/ui-vue 1.65.10 → 1.66.1

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 (56) hide show
  1. package/.turbo/turbo-build.log +21 -21
  2. package/.turbo/turbo-formatter$colon$check.log +2 -2
  3. package/.turbo/turbo-linter$colon$check.log +2 -2
  4. package/.turbo/turbo-types$colon$check.log +1 -1
  5. package/CHANGELOG.md +13 -0
  6. package/dist/components/PlAdvancedFilter/FilterEditor.js.map +1 -1
  7. package/dist/components/PlAdvancedFilter/FilterEditor.style.js.map +1 -1
  8. package/dist/components/PlAdvancedFilter/FilterEditor.test.d.ts +2 -0
  9. package/dist/components/PlAdvancedFilter/FilterEditor.test.d.ts.map +1 -0
  10. package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts.map +1 -1
  11. package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js +142 -145
  12. package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js.map +1 -1
  13. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.js.map +1 -1
  14. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.style.js.map +1 -1
  15. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts.map +1 -1
  16. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js.map +1 -1
  17. package/dist/components/PlAdvancedFilter/types.d.ts +5 -6
  18. package/dist/components/PlAdvancedFilter/types.d.ts.map +1 -1
  19. package/dist/components/PlAdvancedFilter/utils.d.ts +1 -0
  20. package/dist/components/PlAdvancedFilter/utils.d.ts.map +1 -1
  21. package/dist/components/PlAdvancedFilter/utils.js +10 -1
  22. package/dist/components/PlAdvancedFilter/utils.js.map +1 -1
  23. package/dist/components/PlAnnotations/components/AnnotationsSidebar.js.map +1 -1
  24. package/dist/components/PlAnnotations/components/AnnotationsSidebar.style.js.map +1 -1
  25. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue.d.ts +7 -10
  26. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue.d.ts.map +1 -1
  27. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js +71 -50
  28. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js.map +1 -1
  29. package/dist/components/PlAnnotations/components/FilterSidebar.js.map +1 -1
  30. package/dist/components/PlAnnotations/components/FilterSidebar.style.js.map +1 -1
  31. package/dist/components/PlAnnotations/components/FilterSidebar.vue.d.ts +5 -7
  32. package/dist/components/PlAnnotations/components/FilterSidebar.vue.d.ts.map +1 -1
  33. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +81 -67
  34. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js.map +1 -1
  35. package/dist/components/PlAnnotations/components/PlAnnotations.js.map +1 -1
  36. package/dist/components/PlAnnotations/components/PlAnnotations.style.js.map +1 -1
  37. package/dist/components/PlAnnotations/components/PlAnnotations.vue.d.ts +4 -14
  38. package/dist/components/PlAnnotations/components/PlAnnotations.vue.d.ts.map +1 -1
  39. package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js +43 -38
  40. package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -1
  41. package/dist/components/PlAnnotations/components/PlAnnotationsModal.js.map +1 -1
  42. package/dist/components/PlAnnotations/components/PlAnnotationsModal.style.js.map +1 -1
  43. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue.d.ts +5 -13
  44. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue.d.ts.map +1 -1
  45. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js +37 -40
  46. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js.map +1 -1
  47. package/package.json +5 -5
  48. package/src/components/PlAdvancedFilter/FilterEditor.test.ts +315 -0
  49. package/src/components/PlAdvancedFilter/FilterEditor.vue +12 -18
  50. package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +1 -6
  51. package/src/components/PlAdvancedFilter/types.ts +6 -8
  52. package/src/components/PlAdvancedFilter/utils.ts +20 -0
  53. package/src/components/PlAnnotations/components/AnnotationsSidebar.vue +59 -30
  54. package/src/components/PlAnnotations/components/FilterSidebar.vue +65 -40
  55. package/src/components/PlAnnotations/components/PlAnnotations.vue +35 -19
  56. package/src/components/PlAnnotations/components/PlAnnotationsModal.vue +18 -21
@@ -1,11 +1,12 @@
1
1
  import { DEFAULT_FILTERS as e, DEFAULT_FILTER_TYPE as t } from "./constants.js";
2
2
  import n from "./OperandButton.js";
3
- import { getFilterInfo as r, getNormalizedSpec as i, isNumericFilter as a, isPositionFilter as o } from "./utils.js";
4
- import { Fragment as s, computed as c, createBlock as l, createCommentVNode as u, createElementBlock as d, createElementVNode as f, createVNode as p, defineComponent as m, normalizeClass as h, openBlock as g, renderList as _, toDisplayString as v, unref as y } from "vue";
5
- import { isFilteredPColumn as b, parseColumnId as x, stringifyColumnId as S } from "@platforma-sdk/model";
6
- import { PlAutocomplete as C, PlAutocompleteMulti as w, PlDropdown as T, PlIcon16 as E, PlNumberField as D, PlTextField as O, PlToggleSwitch as k, Slider as A } from "@milaboratories/uikit";
3
+ import { getFilterInfo as r, getNormalizedSpec as i, isNumericFilter as a, isPositionFilter as o, mergeFilterForTypeChange as s } from "./utils.js";
4
+ import { Fragment as c, computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createVNode as m, defineComponent as h, normalizeClass as g, openBlock as _, renderList as v, toDisplayString as y, unref as b } from "vue";
5
+ import { isFilteredPColumn as x, parseColumnId as S, stringifyColumnId as C } from "@platforma-sdk/model";
6
+ import { PlAutocomplete as w, PlAutocompleteMulti as T, PlDropdown as E, PlIcon16 as D, PlNumberField as O, PlTextField as k, PlToggleSwitch as A, Slider as j } from "@milaboratories/uikit";
7
+ import { isNil as M } from "es-toolkit";
7
8
  //#region src/components/PlAdvancedFilter/FilterEditor.vue?vue&type=script&setup=true&lang.ts
8
- var j = ["title"], M = /* @__PURE__ */ m({
9
+ var N = ["title"], P = /* @__PURE__ */ h({
9
10
  __name: "FilterEditor",
10
11
  props: {
11
12
  filter: {},
@@ -19,70 +20,66 @@ var j = ["title"], M = /* @__PURE__ */ m({
19
20
  onUpdateFilter: { type: Function },
20
21
  onChangeOperand: { type: Function }
21
22
  },
22
- setup(m) {
23
- let M = m;
24
- function N(e, t) {
25
- M.onUpdateFilter({
26
- ...M.filter,
23
+ setup(h) {
24
+ let P = h;
25
+ function F(e, t) {
26
+ P.onUpdateFilter({
27
+ ...P.filter,
27
28
  [e]: t
28
29
  });
29
30
  }
30
- async function P(e, t, n, r) {
31
- return M.getSuggestOptions({
31
+ async function I(e, t, n, r) {
32
+ return P.getSuggestOptions({
32
33
  columnId: e,
33
34
  axisIdx: r,
34
35
  searchType: t,
35
36
  searchStr: n
36
37
  });
37
38
  }
38
- async function F(e, t, n, r) {
39
- if (t === "label" && typeof n == "string") return P(e, t, n, r);
40
- if (t === "value" && Array.isArray(n)) return (await Promise.all(n.map((n) => P(e, t, n, r)))).map((e) => e[0]);
39
+ async function L(e, t, n, r) {
40
+ if (t === "label" && typeof n == "string") return I(e, t, n, r);
41
+ if (t === "value" && Array.isArray(n)) return (await Promise.all(n.map((n) => I(e, t, n, r)))).map((e) => e[0]);
41
42
  throw Error("Invalid arguments combination");
42
43
  }
43
- function I(t) {
44
- let n = e[t];
45
- M.onUpdateFilter(Object.entries(n).reduce((e, [t, n]) => (e[t] = M.filter[t] ?? n, e), {
46
- ...M.filter,
47
- type: t
48
- }));
44
+ function R(e) {
45
+ M(e) || P.onUpdateFilter(s(P.filter, e));
49
46
  }
50
- function L(n) {
47
+ function z(n) {
51
48
  if (!n) return;
52
- let a = M.columnOptions.find((e) => e.id === B(n));
49
+ let a = P.columnOptions.find((e) => e.id === H(n));
53
50
  if (!a) return;
54
- let o = r(M.filter.type), s = i(a?.spec);
55
- o.supportedFor(s) ? M.onUpdateFilter({
56
- ...M.filter,
51
+ let o = r(P.filter.type), s = i(a?.spec);
52
+ o.supportedFor(s) ? P.onUpdateFilter({
53
+ ...P.filter,
57
54
  column: n
58
- }) : M.onUpdateFilter({
55
+ }) : P.onUpdateFilter({
59
56
  ...e[t],
60
57
  column: n
61
58
  });
62
59
  }
63
- let R = c(() => M.columnOptions.find((e) => e.id === B(M.filter.column)) === void 0), z = c(() => {
64
- let e = M.columnOptions.map((e) => ({
60
+ let B = l(() => P.columnOptions.find((e) => e.id === H(P.filter.column)) === void 0), V = l(() => {
61
+ let e = P.columnOptions.map((e) => ({
65
62
  value: e.id,
66
63
  label: e.label ?? e
67
64
  }));
68
- return R.value && e.unshift({
69
- value: M.filter.column,
65
+ return B.value && e.unshift({
66
+ value: P.filter.column,
70
67
  label: "Inconsistent value"
71
68
  }), e;
72
69
  });
73
- function B(e) {
70
+ function H(e) {
74
71
  try {
75
- let t = x(e);
76
- return b(t) ? S(t.source) : e;
72
+ let t = S(e);
73
+ return x(t) ? C(t.source) : e;
77
74
  } catch {
78
75
  return e;
79
76
  }
80
77
  }
81
- function V(e) {
82
- let t = B(e), n = (M.columnOptions.find((e) => e.id === t)?.axesToBeFixed ?? []).reduce((e, t) => (e[t.idx] = void 0, e), {});
78
+ function U(e) {
79
+ let t = H(e), n = (P.columnOptions.find((e) => e.id === t)?.axesToBeFixed ?? []).reduce((e, t) => (e[t.idx] = void 0, e), {});
83
80
  try {
84
- let r = x(e);
85
- if (b(r)) return {
81
+ let r = S(e);
82
+ if (x(r)) return {
86
83
  source: t,
87
84
  axisFiltersByIndex: r.axisFilters.reduce((e, t) => (e[t[0]] = t[1], e), n)
88
85
  };
@@ -97,198 +94,198 @@ var j = ["title"], M = /* @__PURE__ */ m({
97
94
  axisFiltersByIndex: n
98
95
  };
99
96
  }
100
- function H(e) {
101
- return Object.keys(e.axisFiltersByIndex).length === 0 ? e.source : S({
102
- source: x(e.source),
97
+ function W(e) {
98
+ return Object.keys(e.axisFiltersByIndex).length === 0 ? e.source : C({
99
+ source: S(e.source),
103
100
  axisFilters: Object.entries(e.axisFiltersByIndex).map(([e, t]) => [Number(e), t])
104
101
  });
105
102
  }
106
- let U = c({
107
- get: () => V(M.filter.column),
103
+ let G = l({
104
+ get: () => U(P.filter.column),
108
105
  set: (e) => {
109
- M.onUpdateFilter({
110
- ...M.filter,
111
- column: H(e)
106
+ P.onUpdateFilter({
107
+ ...P.filter,
108
+ column: W(e)
112
109
  });
113
110
  }
114
111
  });
115
- function W(e, t) {
116
- U.value = {
117
- ...U.value,
112
+ function K(e, t) {
113
+ G.value = {
114
+ ...G.value,
118
115
  axisFiltersByIndex: {
119
- ...U.value.axisFiltersByIndex,
116
+ ...G.value.axisFiltersByIndex,
120
117
  [e]: t
121
118
  }
122
119
  };
123
120
  }
124
- let G = c(() => M.columnOptions.find((e) => e.id === U.value.source)), K = c(() => G.value?.spec ? i(G.value.spec) : null), q = c(() => K.value?.valueType), J = c(() => !!G.value?.error || R.value), Y = c(() => M.supportedFilters.filter((e) => M.filter.type === e || (K.value ? r(e).supportedFor(K.value) : !0)).map((e) => ({
121
+ let q = l(() => P.columnOptions.find((e) => e.id === G.value.source)), J = l(() => q.value?.spec ? i(q.value.spec) : null), Y = l(() => J.value?.valueType), X = l(() => !!q.value?.error || B.value), Z = l(() => P.supportedFilters.filter((e) => P.filter.type === e || (J.value ? r(e).supportedFor(J.value) : !0)).map((e) => ({
125
122
  value: e,
126
123
  label: r(e).label
127
- }))), X = c(() => M.filter.type === "patternFuzzyContainSubsequence" ? G.value?.alphabet === "nucleotide" ? [{
124
+ }))), Q = l(() => P.filter.type === "patternFuzzyContainSubsequence" ? q.value?.alphabet === "nucleotide" ? [{
128
125
  label: "N",
129
126
  value: "N"
130
- }] : G.value?.alphabet === "aminoacid" ? [{
127
+ }] : q.value?.alphabet === "aminoacid" ? [{
131
128
  label: "X",
132
129
  value: "X"
133
- }] : [...new Set(M.filter.value.split(""))].sort().map((e) => ({
130
+ }] : [...new Set(P.filter.value.split(""))].sort().map((e) => ({
134
131
  value: e,
135
132
  label: e
136
- })) : []), Z = c(() => {
137
- if (M.filter.type !== "patternMatchesRegularExpression") return !1;
133
+ })) : []), $ = l(() => {
134
+ if (P.filter.type !== "patternMatchesRegularExpression") return !1;
138
135
  try {
139
- return new RegExp(M.filter.value), !1;
136
+ return new RegExp(P.filter.value), !1;
140
137
  } catch {
141
138
  return !0;
142
139
  }
143
140
  });
144
- return (e, t) => (g(), d(s, null, [f("div", { class: h(e.$style.filterWrapper) }, [
145
- m.enableDnd ? (g(), d("div", {
141
+ return (e, t) => (_(), f(c, null, [p("div", { class: g(e.$style.filterWrapper) }, [
142
+ h.enableDnd ? (_(), f("div", {
146
143
  key: 0,
147
- class: h([
144
+ class: g([
148
145
  e.$style.top,
149
146
  e.$style.columnChip,
150
- { [e.$style.error]: J.value }
147
+ { [e.$style.error]: X.value }
151
148
  ])
152
149
  }, [
153
- f("div", { class: h([e.$style.typeIcon, { [e.$style.error]: J.value }]) }, [J.value ? (g(), l(y(E), {
150
+ p("div", { class: g([e.$style.typeIcon, { [e.$style.error]: X.value }]) }, [X.value ? (_(), u(b(D), {
154
151
  key: 0,
155
152
  name: "warning"
156
- })) : (g(), l(y(E), {
153
+ })) : (_(), u(b(D), {
157
154
  key: 1,
158
- name: q.value === "String" || q.value === void 0 ? "cell-type-txt" : "cell-type-num"
155
+ name: Y.value === "String" || Y.value === void 0 ? "cell-type-txt" : "cell-type-num"
159
156
  }, null, 8, ["name"]))], 2),
160
- f("div", {
161
- class: h(e.$style.titleWrapper),
162
- title: G.value?.label ?? ""
163
- }, [f("div", { class: h(e.$style.title) }, v(R.value ? "Inconsistent value" : G.value?.label ?? M.filter.column), 3)], 10, j),
164
- f("div", {
165
- class: h(e.$style.closeIcon),
166
- onClick: t[0] ||= (e) => m.onDelete(M.filter.column)
167
- }, [p(y(E), { name: "close" })], 2)
168
- ], 2)) : (g(), d("div", {
157
+ p("div", {
158
+ class: g(e.$style.titleWrapper),
159
+ title: q.value?.label ?? ""
160
+ }, [p("div", { class: g(e.$style.title) }, y(B.value ? "Inconsistent value" : q.value?.label ?? P.filter.column), 3)], 10, N),
161
+ p("div", {
162
+ class: g(e.$style.closeIcon),
163
+ onClick: t[0] ||= (e) => h.onDelete(P.filter.column)
164
+ }, [m(b(D), { name: "close" })], 2)
165
+ ], 2)) : (_(), f("div", {
169
166
  key: 1,
170
- class: h(e.$style.top)
171
- }, [p(y(T), {
172
- "model-value": U.value.source,
173
- errorStatus: J.value,
174
- options: z.value,
167
+ class: g(e.$style.top)
168
+ }, [m(b(E), {
169
+ "model-value": G.value.source,
170
+ errorStatus: X.value,
171
+ options: V.value,
175
172
  style: { width: "100%" },
176
173
  "group-position": "top-left",
177
- "onUpdate:modelValue": L
174
+ "onUpdate:modelValue": z
178
175
  }, null, 8, [
179
176
  "model-value",
180
177
  "errorStatus",
181
178
  "options"
182
- ]), f("div", {
183
- class: h(e.$style.closeButton),
184
- onClick: t[1] ||= (e) => m.onDelete(M.filter.column)
185
- }, [p(y(E), { name: "close" })], 2)], 2)),
186
- G.value?.axesToBeFixed?.length ? (g(), d("div", {
179
+ ]), p("div", {
180
+ class: g(e.$style.closeButton),
181
+ onClick: t[1] ||= (e) => h.onDelete(P.filter.column)
182
+ }, [m(b(D), { name: "close" })], 2)], 2)),
183
+ q.value?.axesToBeFixed?.length ? (_(), f("div", {
187
184
  key: 2,
188
- class: h(e.$style.fixedAxesBlock)
189
- }, [(g(!0), d(s, null, _(G.value?.axesToBeFixed, (e) => (g(), l(y(C), {
185
+ class: g(e.$style.fixedAxesBlock)
186
+ }, [(_(!0), f(c, null, v(q.value?.axesToBeFixed, (e) => (_(), u(b(w), {
190
187
  key: e.idx,
191
- "model-value": U.value.axisFiltersByIndex[e.idx],
188
+ "model-value": G.value.axisFiltersByIndex[e.idx],
192
189
  label: e.label,
193
- "options-search": (t, n) => P(U.value.source, n, t, e.idx),
194
- disabled: R.value,
190
+ "options-search": (t, n) => I(G.value.source, n, t, e.idx),
191
+ disabled: B.value,
195
192
  clearable: !0,
196
- "onUpdate:modelValue": (t) => W(e.idx, t)
193
+ "onUpdate:modelValue": (t) => K(e.idx, t)
197
194
  }, null, 8, [
198
195
  "model-value",
199
196
  "label",
200
197
  "options-search",
201
198
  "disabled",
202
199
  "onUpdate:modelValue"
203
- ]))), 128))], 2)) : u("", !0),
204
- f("div", { class: h(M.filter.type === "isNA" || M.filter.type === "isNotNA" ? e.$style.bottom : e.$style.middle) }, [p(y(T), {
205
- "model-value": M.filter.type,
206
- options: Y.value,
207
- "group-position": M.filter.type === "isNA" || M.filter.type === "isNotNA" ? "bottom" : "middle",
208
- "onUpdate:modelValue": t[2] ||= (e) => I(e)
200
+ ]))), 128))], 2)) : d("", !0),
201
+ p("div", { class: g(P.filter.type === "isNA" || P.filter.type === "isNotNA" ? e.$style.bottom : e.$style.middle) }, [m(b(E), {
202
+ "model-value": P.filter.type,
203
+ options: Z.value,
204
+ "group-position": P.filter.type === "isNA" || P.filter.type === "isNotNA" ? "bottom" : "middle",
205
+ "onUpdate:modelValue": R
209
206
  }, null, 8, [
210
207
  "model-value",
211
208
  "options",
212
209
  "group-position"
213
210
  ])], 2),
214
- M.filter.type === "patternFuzzyContainSubsequence" ? (g(), d(s, { key: 3 }, [f("div", { class: h(e.$style.middle) }, [p(y(O), {
215
- "model-value": M.filter.value,
211
+ P.filter.type === "patternFuzzyContainSubsequence" ? (_(), f(c, { key: 3 }, [p("div", { class: g(e.$style.middle) }, [m(b(k), {
212
+ "model-value": P.filter.value,
216
213
  placeholder: "Substring",
217
214
  "group-position": "middle",
218
- "onUpdate:modelValue": t[3] ||= (e) => N("value", e)
219
- }, null, 8, ["model-value"])], 2), f("div", { class: h(e.$style.innerSection) }, [p(y(A), {
220
- "model-value": M.filter.maxEdits,
215
+ "onUpdate:modelValue": t[2] ||= (e) => F("value", e)
216
+ }, null, 8, ["model-value"])], 2), p("div", { class: g(e.$style.innerSection) }, [m(b(j), {
217
+ "model-value": P.filter.maxEdits,
221
218
  max: 5,
222
219
  breakpoints: "",
223
220
  label: "Maximum number of substitutions and indels",
224
- "onUpdate:modelValue": t[4] ||= (e) => N("maxEdits", e)
225
- }, null, 8, ["model-value"]), p(y(k), {
226
- "model-value": M.filter.substitutionsOnly,
221
+ "onUpdate:modelValue": t[3] ||= (e) => F("maxEdits", e)
222
+ }, null, 8, ["model-value"]), m(b(A), {
223
+ "model-value": P.filter.substitutionsOnly,
227
224
  label: "Substitutions only",
228
- "onUpdate:modelValue": t[5] ||= (e) => N("substitutionsOnly", e)
229
- }, null, 8, ["model-value"])], 2)], 64)) : u("", !0),
230
- f("div", { class: h(e.$style.bottom) }, [
231
- M.filter.type === "patternEquals" || M.filter.type === "patternNotEquals" ? (g(), l(y(C), {
225
+ "onUpdate:modelValue": t[4] ||= (e) => F("substitutionsOnly", e)
226
+ }, null, 8, ["model-value"])], 2)], 64)) : d("", !0),
227
+ p("div", { class: g(e.$style.bottom) }, [
228
+ P.filter.type === "patternEquals" || P.filter.type === "patternNotEquals" ? (_(), u(b(w), {
232
229
  key: 0,
233
- "model-value": M.filter.value,
234
- "options-search": (e, t) => P(U.value.source, t, e),
230
+ "model-value": P.filter.value,
231
+ "options-search": (e, t) => I(G.value.source, t, e),
235
232
  clearable: !0,
236
233
  "group-position": "bottom",
237
- "onUpdate:modelValue": t[6] ||= (e) => N("value", e)
238
- }, null, 8, ["model-value", "options-search"])) : u("", !0),
239
- M.filter.type === "inSet" || M.filter.type === "notInSet" ? (g(), l(y(w), {
234
+ "onUpdate:modelValue": t[5] ||= (e) => F("value", e)
235
+ }, null, 8, ["model-value", "options-search"])) : d("", !0),
236
+ P.filter.type === "inSet" || P.filter.type === "notInSet" ? (_(), u(b(T), {
240
237
  key: 1,
241
- "model-value": M.filter.value,
242
- "options-search": (e, t) => F(U.value.source, t, e),
243
- disabled: R.value,
238
+ "model-value": P.filter.value,
239
+ "options-search": (e, t) => L(G.value.source, t, e),
240
+ disabled: B.value,
244
241
  "group-position": "bottom",
245
- "onUpdate:modelValue": t[7] ||= (e) => N("value", e)
242
+ "onUpdate:modelValue": t[6] ||= (e) => F("value", e)
246
243
  }, null, 8, [
247
244
  "model-value",
248
245
  "options-search",
249
246
  "disabled"
250
- ])) : u("", !0),
251
- y(a)(M.filter) ? (g(), l(y(D), {
247
+ ])) : d("", !0),
248
+ b(a)(P.filter) ? (_(), u(b(O), {
252
249
  key: 2,
253
- "model-value": M.filter.x,
250
+ "model-value": P.filter.x,
254
251
  "group-position": "bottom",
255
- "onUpdate:modelValue": t[8] ||= (e) => N("x", e)
256
- }, null, 8, ["model-value"])) : u("", !0),
257
- y(o)(M.filter) ? (g(), l(y(D), {
252
+ "onUpdate:modelValue": t[7] ||= (e) => F("x", e)
253
+ }, null, 8, ["model-value"])) : d("", !0),
254
+ b(o)(P.filter) ? (_(), u(b(O), {
258
255
  key: 3,
259
- "model-value": M.filter.n,
256
+ "model-value": P.filter.n,
260
257
  "group-position": "bottom",
261
- "onUpdate:modelValue": t[9] ||= (e) => N("n", e)
262
- }, null, 8, ["model-value"])) : u("", !0),
263
- M.filter.type === "patternContainSubsequence" || M.filter.type === "patternNotContainSubsequence" ? (g(), l(y(O), {
258
+ "onUpdate:modelValue": t[8] ||= (e) => F("n", e)
259
+ }, null, 8, ["model-value"])) : d("", !0),
260
+ P.filter.type === "patternContainSubsequence" || P.filter.type === "patternNotContainSubsequence" ? (_(), u(b(k), {
264
261
  key: 4,
265
- "model-value": M.filter.value,
262
+ "model-value": P.filter.value,
266
263
  placeholder: "Substring",
267
264
  "group-position": "bottom",
268
- "onUpdate:modelValue": t[10] ||= (e) => N("value", e)
269
- }, null, 8, ["model-value"])) : u("", !0),
270
- M.filter.type === "patternMatchesRegularExpression" ? (g(), l(y(O), {
265
+ "onUpdate:modelValue": t[9] ||= (e) => F("value", e)
266
+ }, null, 8, ["model-value"])) : d("", !0),
267
+ P.filter.type === "patternMatchesRegularExpression" ? (_(), u(b(k), {
271
268
  key: 5,
272
- "model-value": M.filter.value,
273
- error: Z.value ? "Regular expression is not valid" : void 0,
269
+ "model-value": P.filter.value,
270
+ error: $.value ? "Regular expression is not valid" : void 0,
274
271
  placeholder: "Regular expression",
275
272
  "group-position": "bottom",
276
- "onUpdate:modelValue": t[11] ||= (e) => N("value", e)
277
- }, null, 8, ["model-value", "error"])) : u("", !0),
278
- M.filter.type === "patternFuzzyContainSubsequence" ? (g(), l(y(T), {
273
+ "onUpdate:modelValue": t[10] ||= (e) => F("value", e)
274
+ }, null, 8, ["model-value", "error"])) : d("", !0),
275
+ P.filter.type === "patternFuzzyContainSubsequence" ? (_(), u(b(E), {
279
276
  key: 6,
280
- "model-value": M.filter.wildcard,
277
+ "model-value": P.filter.wildcard,
281
278
  clearable: "",
282
279
  placeholder: "Wildcard value",
283
- options: X.value,
280
+ options: Q.value,
284
281
  "group-position": "bottom",
285
- "onUpdate:modelValue": t[12] ||= (e) => N("wildcard", e)
286
- }, null, 8, ["model-value", "options"])) : u("", !0)
282
+ "onUpdate:modelValue": t[11] ||= (e) => F("wildcard", e)
283
+ }, null, 8, ["model-value", "options"])) : d("", !0)
287
284
  ], 2)
288
- ], 2), p(n, {
289
- active: m.operand,
290
- disabled: m.isLast,
291
- onSelect: m.onChangeOperand
285
+ ], 2), m(n, {
286
+ active: h.operand,
287
+ disabled: h.isLast,
288
+ onSelect: h.onChangeOperand
292
289
  }, null, 8, [
293
290
  "active",
294
291
  "disabled",
@@ -297,6 +294,6 @@ var j = ["title"], M = /* @__PURE__ */ m({
297
294
  }
298
295
  });
299
296
  //#endregion
300
- export { M as default };
297
+ export { P as default };
301
298
 
302
299
  //# sourceMappingURL=FilterEditor.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterEditor.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../src/components/PlAdvancedFilter/FilterEditor.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport {\n PlAutocomplete,\n PlAutocompleteMulti,\n PlDropdown,\n PlIcon16,\n PlNumberField,\n PlTextField,\n PlToggleSwitch,\n Slider,\n} from \"@milaboratories/uikit\";\nimport type {\n AnchoredPColumnId,\n AxisFilterByIdx,\n AxisFilterValue,\n SUniversalPColumnId,\n} from \"@platforma-sdk/model\";\nimport {\n isFilteredPColumn,\n parseColumnId,\n stringifyColumnId,\n type ListOptionBase,\n} from \"@platforma-sdk/model\";\nimport { computed } from \"vue\";\nimport type { SUPPORTED_FILTER_TYPES } from \"./constants\";\nimport { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS } from \"./constants\";\nimport OperandButton from \"./OperandButton.vue\";\nimport type { EditableFilter, Operand, PlAdvancedFilterColumnId, SourceOptionInfo } from \"./types\";\nimport { getFilterInfo, getNormalizedSpec, isNumericFilter, isPositionFilter } from \"./utils\";\nimport { Entries } from \"@milaboratories/helpers\";\n\nconst props = defineProps<{\n filter: EditableFilter;\n isLast: boolean;\n operand: Operand;\n enableDnd: boolean;\n columnOptions: SourceOptionInfo[];\n supportedFilters: typeof SUPPORTED_FILTER_TYPES;\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchType: \"value\" | \"label\";\n searchStr: string;\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n onDelete: (columnId: PlAdvancedFilterColumnId) => void;\n onUpdateFilter: (filter: EditableFilter) => void;\n onChangeOperand: (op: Operand) => void;\n}>();\n\ntype AllKeys<U> = U extends unknown ? keyof U : never;\ntype ValueOf<U, K extends string> = U extends unknown ? (K extends keyof U ? U[K] : never) : never;\n\nfunction updateFilterProp<K extends AllKeys<EditableFilter> & string>(\n key: K,\n v: ValueOf<EditableFilter, K>,\n) {\n props.onUpdateFilter({ ...props.filter, [key]: v } as EditableFilter);\n}\n\nasync function getSuggestOptionsFn(\n id: PlAdvancedFilterColumnId,\n type: \"value\" | \"label\",\n str: string,\n axisIdx?: number,\n): Promise<ListOptionBase<string>[]> {\n return props.getSuggestOptions({\n columnId: id,\n axisIdx,\n searchType: type,\n searchStr: str,\n }) as Promise<ListOptionBase<string>[]>;\n}\n\nasync function getMultiSuggestOptionsFn(\n id: PlAdvancedFilterColumnId,\n type: \"value\" | \"label\",\n str: string | string[],\n axisIdx?: number,\n): Promise<ListOptionBase<string>[]> {\n if (type === \"label\" && typeof str === \"string\") {\n return getSuggestOptionsFn(id, type, str, axisIdx);\n }\n if (type === \"value\" && Array.isArray(str)) {\n const results = await Promise.all(str.map((s) => getSuggestOptionsFn(id, type, s, axisIdx)));\n return results.map((x) => x[0]);\n }\n throw new Error(\"Invalid arguments combination\");\n}\n\nfunction changeFilterType(newType: EditableFilter[\"type\"]) {\n const defaultFilter = DEFAULT_FILTERS[newType];\n\n props.onUpdateFilter(\n (Object.entries(defaultFilter) as Entries<EditableFilter>).reduce(\n (res, [key, val]) => {\n res[key] = props.filter[key] ?? val;\n return res;\n },\n { ...props.filter, type: newType } as Record<\n keyof EditableFilter,\n EditableFilter[keyof EditableFilter]\n >,\n ) as EditableFilter,\n );\n}\n\nfunction changeSourceId(newSourceId?: PlAdvancedFilterColumnId) {\n if (!newSourceId) {\n return;\n }\n const newSourceInfo = props.columnOptions.find((v) => v.id === getSourceId(newSourceId));\n if (!newSourceInfo) {\n return;\n }\n const filterInfo = getFilterInfo(props.filter.type);\n const newSourceSpec = getNormalizedSpec(newSourceInfo?.spec);\n if (filterInfo.supportedFor(newSourceSpec)) {\n props.onUpdateFilter({ ...props.filter, column: newSourceId });\n } else {\n props.onUpdateFilter({\n ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],\n column: newSourceId,\n });\n }\n}\n\nconst inconsistentSourceSelected = computed(() => {\n const selectedOption = props.columnOptions.find(\n (op) => op.id === getSourceId(props.filter.column),\n );\n return selectedOption === undefined;\n});\nconst sourceOptions = computed(() => {\n const options = props.columnOptions.map((v) => ({ value: v.id, label: v.label ?? v }));\n if (inconsistentSourceSelected.value) {\n options.unshift({ value: props.filter.column, label: \"Inconsistent value\" });\n }\n return options;\n});\n\nfunction getSourceId(column: PlAdvancedFilterColumnId): PlAdvancedFilterColumnId {\n try {\n const parsedColumnId = parseColumnId(column as SUniversalPColumnId);\n if (isFilteredPColumn(parsedColumnId)) {\n return stringifyColumnId(parsedColumnId.source);\n } else {\n return column;\n }\n } catch {\n return column;\n }\n}\n\n// similar to FilteredPColumnId but source is stringified and axis filters can be undefined\ntype ColumnAsSourceAndFixedAxes = {\n source: PlAdvancedFilterColumnId;\n axisFiltersByIndex: Record<number, AxisFilterValue | undefined>;\n};\nfunction getColumnAsSourceAndFixedAxes(\n column: PlAdvancedFilterColumnId,\n): ColumnAsSourceAndFixedAxes {\n const sourceId = getSourceId(column);\n const option = props.columnOptions.find((op) => op.id === sourceId);\n const axesToBeFixed = (option?.axesToBeFixed ?? []).reduce(\n (res, item) => {\n res[item.idx] = undefined;\n return res;\n },\n {} as Record<number, AxisFilterValue | undefined>,\n );\n try {\n const parsedColumnId = parseColumnId(column as SUniversalPColumnId);\n if (isFilteredPColumn(parsedColumnId)) {\n return {\n source: sourceId,\n axisFiltersByIndex: parsedColumnId.axisFilters.reduce((res, item) => {\n res[item[0]] = item[1];\n return res;\n }, axesToBeFixed),\n };\n }\n } catch {\n return { source: column, axisFiltersByIndex: axesToBeFixed };\n }\n return { source: column, axisFiltersByIndex: axesToBeFixed };\n}\n\nfunction stringifyColumn(value: ColumnAsSourceAndFixedAxes): PlAdvancedFilterColumnId {\n if (Object.keys(value.axisFiltersByIndex).length === 0) {\n return value.source;\n }\n return stringifyColumnId({\n source: parseColumnId(value.source as SUniversalPColumnId) as AnchoredPColumnId,\n axisFilters: Object.entries(value.axisFiltersByIndex).map(\n ([idx, value]) => [Number(idx), value] as AxisFilterByIdx,\n ),\n });\n}\n\nconst columnAsSourceAndFixedAxes = computed({\n get: () => {\n return getColumnAsSourceAndFixedAxes(props.filter.column);\n },\n set: (value) => {\n props.onUpdateFilter({ ...props.filter, column: stringifyColumn(value) });\n },\n});\nfunction updateAxisFilterValue(idx: number, value: AxisFilterValue | undefined) {\n columnAsSourceAndFixedAxes.value = {\n ...columnAsSourceAndFixedAxes.value,\n axisFiltersByIndex: { ...columnAsSourceAndFixedAxes.value.axisFiltersByIndex, [idx]: value },\n };\n}\n\nconst currentOption = computed(() =>\n props.columnOptions.find((op) => op.id === columnAsSourceAndFixedAxes.value.source),\n);\nconst currentSpec = computed(() =>\n currentOption.value?.spec ? getNormalizedSpec(currentOption.value.spec) : null,\n);\nconst currentType = computed(() => currentSpec.value?.valueType);\nconst currentError = computed(\n () => Boolean(currentOption.value?.error) || inconsistentSourceSelected.value,\n);\n\nconst filterTypesOptions = computed(() =>\n props.supportedFilters\n .filter(\n (v) =>\n props.filter.type === v ||\n (currentSpec.value ? getFilterInfo(v).supportedFor(currentSpec.value) : true),\n )\n .map((v) => ({ value: v, label: getFilterInfo(v).label })),\n);\n\nconst wildcardOptions = computed(() => {\n if (props.filter.type !== \"patternFuzzyContainSubsequence\") {\n return [];\n }\n if (currentOption.value?.alphabet === \"nucleotide\") {\n return [{ label: \"N\", value: \"N\" }];\n }\n if (currentOption.value?.alphabet === \"aminoacid\") {\n return [{ label: \"X\", value: \"X\" }];\n }\n return [...new Set(props.filter.value.split(\"\"))].sort().map((v) => ({ value: v, label: v }));\n});\n\nconst stringMatchesError = computed(() => {\n if (props.filter.type !== \"patternMatchesRegularExpression\") {\n return false;\n }\n try {\n new RegExp(props.filter.value);\n return false;\n } catch {\n return true;\n }\n});\n</script>\n<template>\n <div :class=\"$style.filterWrapper\">\n <!-- top element - column selector / column label - for all filter types-->\n <div\n v-if=\"enableDnd\"\n :class=\"[$style.top, $style.columnChip, { [$style.error]: currentError }]\"\n >\n <div :class=\"[$style.typeIcon, { [$style.error]: currentError }]\">\n <PlIcon16 v-if=\"currentError\" name=\"warning\" />\n <PlIcon16\n v-else\n :name=\"\n currentType === 'String' || currentType === undefined\n ? 'cell-type-txt'\n : 'cell-type-num'\n \"\n />\n </div>\n <div :class=\"$style.titleWrapper\" :title=\"currentOption?.label ?? ''\">\n <div :class=\"$style.title\">\n {{\n inconsistentSourceSelected\n ? \"Inconsistent value\"\n : (currentOption?.label ?? props.filter.column)\n }}\n </div>\n </div>\n <div :class=\"$style.closeIcon\" @click=\"onDelete(props.filter.column)\">\n <PlIcon16 name=\"close\" />\n </div>\n </div>\n <div v-else :class=\"$style.top\">\n <PlDropdown\n :model-value=\"columnAsSourceAndFixedAxes.source\"\n :errorStatus=\"currentError\"\n :options=\"sourceOptions\"\n :style=\"{ width: '100%' }\"\n group-position=\"top-left\"\n @update:model-value=\"changeSourceId\"\n />\n <div :class=\"$style.closeButton\" @click=\"onDelete(props.filter.column)\">\n <PlIcon16 name=\"close\" />\n </div>\n </div>\n\n <div v-if=\"currentOption?.axesToBeFixed?.length\" :class=\"$style.fixedAxesBlock\">\n <template v-for=\"value in currentOption?.axesToBeFixed\" :key=\"value.idx\">\n <PlAutocomplete\n :model-value=\"columnAsSourceAndFixedAxes.axisFiltersByIndex[value.idx]\"\n :label=\"value.label\"\n :options-search=\"\n (str, type) =>\n getSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str, value.idx)\n \"\n :disabled=\"inconsistentSourceSelected\"\n :clearable=\"true\"\n @update:model-value=\"(v) => updateAxisFilterValue(value.idx, v)\"\n />\n </template>\n </div>\n\n <!-- middle - filter type selector - for all filter types -->\n <div\n :class=\"\n props.filter.type === 'isNA' || props.filter.type === 'isNotNA'\n ? $style.bottom\n : $style.middle\n \"\n >\n <PlDropdown\n :model-value=\"props.filter.type\"\n :options=\"filterTypesOptions\"\n :group-position=\"\n props.filter.type === 'isNA' || props.filter.type === 'isNotNA' ? 'bottom' : 'middle'\n \"\n @update:model-value=\"(v) => changeFilterType(v!)\"\n />\n </div>\n\n <!-- middle - for fuzzy contains filter -->\n <template v-if=\"props.filter.type === 'patternFuzzyContainSubsequence'\">\n <div :class=\"$style.middle\">\n <PlTextField\n :model-value=\"props.filter.value\"\n placeholder=\"Substring\"\n group-position=\"middle\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n </div>\n <div :class=\"$style.innerSection\">\n <Slider\n :model-value=\"props.filter.maxEdits\"\n :max=\"5\"\n breakpoints\n label=\"Maximum number of substitutions and indels\"\n @update:model-value=\"(v) => updateFilterProp('maxEdits', v)\"\n />\n <PlToggleSwitch\n :model-value=\"props.filter.substitutionsOnly\"\n label=\"Substitutions only\"\n @update:model-value=\"(v) => updateFilterProp('substitutionsOnly', v)\"\n />\n </div>\n </template>\n\n <!-- bottom element - individual settings for every filter type -->\n <div :class=\"$style.bottom\">\n <PlAutocomplete\n v-if=\"props.filter.type === 'patternEquals' || props.filter.type === 'patternNotEquals'\"\n :model-value=\"props.filter.value\"\n :options-search=\"\n (str, type) => getSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)\n \"\n :clearable=\"true\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlAutocompleteMulti\n v-if=\"props.filter.type === 'inSet' || props.filter.type === 'notInSet'\"\n :model-value=\"props.filter.value\"\n :options-search=\"\n (str, type) => getMultiSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)\n \"\n :disabled=\"inconsistentSourceSelected\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlNumberField\n v-if=\"isNumericFilter(props.filter)\"\n :model-value=\"props.filter.x\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('x', v)\"\n />\n <PlNumberField\n v-if=\"isPositionFilter(props.filter)\"\n :model-value=\"props.filter.n\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('n', v)\"\n />\n <PlTextField\n v-if=\"\n props.filter.type === 'patternContainSubsequence' ||\n props.filter.type === 'patternNotContainSubsequence'\n \"\n :model-value=\"props.filter.value\"\n placeholder=\"Substring\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlTextField\n v-if=\"props.filter.type === 'patternMatchesRegularExpression'\"\n :model-value=\"props.filter.value\"\n :error=\"stringMatchesError ? 'Regular expression is not valid' : undefined\"\n placeholder=\"Regular expression\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlDropdown\n v-if=\"props.filter.type === 'patternFuzzyContainSubsequence'\"\n :model-value=\"props.filter.wildcard\"\n clearable\n placeholder=\"Wildcard value\"\n :options=\"wildcardOptions\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('wildcard', v)\"\n />\n </div>\n </div>\n <OperandButton :active=\"operand\" :disabled=\"isLast\" @select=\"onChangeOperand\" />\n</template>\n\n<style module>\n.filterWrapper {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n cursor: default;\n}\n\n.typeIcon {\n display: inline-flex;\n margin-right: 8px;\n}\n\n.typeIcon.error {\n --icon-color: var(--txt-error);\n}\n\n.closeIcon {\n display: inline-flex;\n margin-left: 12px;\n cursor: pointer;\n}\n\n.titleWrapper {\n flex-grow: 1;\n overflow: hidden;\n}\n.title {\n overflow: hidden;\n color: var(--txt-01);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 500;\n line-height: 20px;\n}\n\n.columnChip {\n width: 100%;\n display: flex;\n padding: 10px 12px;\n align-items: center;\n border-radius: 6px;\n border: 1px solid var(--txt-01);\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n\n &.error {\n border-color: var(--txt-error);\n }\n}\n\n.innerSection {\n border: 1px solid var(--txt-01);\n border-top: none;\n padding: 16px 12px;\n}\n\n.closeButton {\n border: 1px solid var(--txt-01);\n border-top-right-radius: 6px;\n border-left: none;\n width: 40px;\n height: 40px;\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n cursor: pointer;\n}\n\n.top {\n position: relative;\n display: flex;\n width: 100%;\n z-index: 1;\n background: #fff;\n}\n\n.fixedAxesBlock {\n position: relative;\n display: flex;\n flex-direction: column;\n padding: 12px 8px;\n gap: 12px;\n border-left: 1px solid var(--txt-01);\n border-right: 1px solid var(--txt-01);\n}\n\n.fixedAxesBlock > * {\n background: #fff;\n}\n\n.middle,\n.bottom {\n position: relative;\n margin-top: -1px;\n background: #fff;\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"FilterEditor.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../src/components/PlAdvancedFilter/FilterEditor.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport {\n PlAutocomplete,\n PlAutocompleteMulti,\n PlDropdown,\n PlIcon16,\n PlNumberField,\n PlTextField,\n PlToggleSwitch,\n Slider,\n} from \"@milaboratories/uikit\";\nimport type {\n AnchoredPColumnId,\n AxisFilterByIdx,\n AxisFilterValue,\n SUniversalPColumnId,\n} from \"@platforma-sdk/model\";\nimport {\n isFilteredPColumn,\n parseColumnId,\n stringifyColumnId,\n type ListOptionBase,\n} from \"@platforma-sdk/model\";\nimport { computed } from \"vue\";\nimport type { SUPPORTED_FILTER_TYPES } from \"./constants\";\nimport { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS } from \"./constants\";\nimport OperandButton from \"./OperandButton.vue\";\nimport type { EditableFilter, Operand, PlAdvancedFilterColumnId, SourceOptionInfo } from \"./types\";\nimport {\n getFilterInfo,\n getNormalizedSpec,\n isNumericFilter,\n isPositionFilter,\n mergeFilterForTypeChange,\n} from \"./utils\";\nimport { isNil } from \"es-toolkit\";\n\nconst props = defineProps<{\n filter: EditableFilter;\n isLast: boolean;\n operand: Operand;\n enableDnd: boolean;\n columnOptions: SourceOptionInfo[];\n supportedFilters: typeof SUPPORTED_FILTER_TYPES;\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchType: \"value\" | \"label\";\n searchStr: string;\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n onDelete: (columnId: PlAdvancedFilterColumnId) => void;\n onUpdateFilter: (filter: EditableFilter) => void;\n onChangeOperand: (op: Operand) => void;\n}>();\n\ntype AllKeys<U> = U extends unknown ? keyof U : never;\ntype ValueOf<U, K extends string> = U extends unknown ? (K extends keyof U ? U[K] : never) : never;\n\nfunction updateFilterProp<K extends AllKeys<EditableFilter> & string>(\n key: K,\n v: ValueOf<EditableFilter, K>,\n) {\n props.onUpdateFilter({ ...props.filter, [key]: v } as EditableFilter);\n}\n\nasync function getSuggestOptionsFn(\n id: PlAdvancedFilterColumnId,\n type: \"value\" | \"label\",\n str: string,\n axisIdx?: number,\n): Promise<ListOptionBase<string>[]> {\n return props.getSuggestOptions({\n columnId: id,\n axisIdx,\n searchType: type,\n searchStr: str,\n }) as Promise<ListOptionBase<string>[]>;\n}\n\nasync function getMultiSuggestOptionsFn(\n id: PlAdvancedFilterColumnId,\n type: \"value\" | \"label\",\n str: string | string[],\n axisIdx?: number,\n): Promise<ListOptionBase<string>[]> {\n if (type === \"label\" && typeof str === \"string\") {\n return getSuggestOptionsFn(id, type, str, axisIdx);\n }\n if (type === \"value\" && Array.isArray(str)) {\n const results = await Promise.all(str.map((s) => getSuggestOptionsFn(id, type, s, axisIdx)));\n return results.map((x) => x[0]);\n }\n throw new Error(\"Invalid arguments combination\");\n}\n\nfunction changeFilterType(newType?: EditableFilter[\"type\"]) {\n if (isNil(newType)) return;\n props.onUpdateFilter(mergeFilterForTypeChange(props.filter, newType));\n}\n\nfunction changeSourceId(newSourceId?: PlAdvancedFilterColumnId) {\n if (!newSourceId) {\n return;\n }\n const newSourceInfo = props.columnOptions.find((v) => v.id === getSourceId(newSourceId));\n if (!newSourceInfo) {\n return;\n }\n const filterInfo = getFilterInfo(props.filter.type);\n const newSourceSpec = getNormalizedSpec(newSourceInfo?.spec);\n if (filterInfo.supportedFor(newSourceSpec)) {\n props.onUpdateFilter({ ...props.filter, column: newSourceId });\n } else {\n props.onUpdateFilter({\n ...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],\n column: newSourceId,\n });\n }\n}\n\nconst inconsistentSourceSelected = computed(() => {\n const selectedOption = props.columnOptions.find(\n (op) => op.id === getSourceId(props.filter.column),\n );\n return selectedOption === undefined;\n});\nconst sourceOptions = computed(() => {\n const options = props.columnOptions.map((v) => ({ value: v.id, label: v.label ?? v }));\n if (inconsistentSourceSelected.value) {\n options.unshift({ value: props.filter.column, label: \"Inconsistent value\" });\n }\n return options;\n});\n\nfunction getSourceId(column: PlAdvancedFilterColumnId): PlAdvancedFilterColumnId {\n try {\n const parsedColumnId = parseColumnId(column as SUniversalPColumnId);\n if (isFilteredPColumn(parsedColumnId)) {\n return stringifyColumnId(parsedColumnId.source);\n } else {\n return column;\n }\n } catch {\n return column;\n }\n}\n\n// similar to FilteredPColumnId but source is stringified and axis filters can be undefined\ntype ColumnAsSourceAndFixedAxes = {\n source: PlAdvancedFilterColumnId;\n axisFiltersByIndex: Record<number, AxisFilterValue | undefined>;\n};\nfunction getColumnAsSourceAndFixedAxes(\n column: PlAdvancedFilterColumnId,\n): ColumnAsSourceAndFixedAxes {\n const sourceId = getSourceId(column);\n const option = props.columnOptions.find((op) => op.id === sourceId);\n const axesToBeFixed = (option?.axesToBeFixed ?? []).reduce(\n (res, item) => {\n res[item.idx] = undefined;\n return res;\n },\n {} as Record<number, AxisFilterValue | undefined>,\n );\n try {\n const parsedColumnId = parseColumnId(column as SUniversalPColumnId);\n if (isFilteredPColumn(parsedColumnId)) {\n return {\n source: sourceId,\n axisFiltersByIndex: parsedColumnId.axisFilters.reduce((res, item) => {\n res[item[0]] = item[1];\n return res;\n }, axesToBeFixed),\n };\n }\n } catch {\n return { source: column, axisFiltersByIndex: axesToBeFixed };\n }\n return { source: column, axisFiltersByIndex: axesToBeFixed };\n}\n\nfunction stringifyColumn(value: ColumnAsSourceAndFixedAxes): PlAdvancedFilterColumnId {\n if (Object.keys(value.axisFiltersByIndex).length === 0) {\n return value.source;\n }\n return stringifyColumnId({\n source: parseColumnId(value.source as SUniversalPColumnId) as AnchoredPColumnId,\n axisFilters: Object.entries(value.axisFiltersByIndex).map(\n ([idx, value]) => [Number(idx), value] as AxisFilterByIdx,\n ),\n });\n}\n\nconst columnAsSourceAndFixedAxes = computed({\n get: () => {\n return getColumnAsSourceAndFixedAxes(props.filter.column);\n },\n set: (value) => {\n props.onUpdateFilter({ ...props.filter, column: stringifyColumn(value) });\n },\n});\nfunction updateAxisFilterValue(idx: number, value: AxisFilterValue | undefined) {\n columnAsSourceAndFixedAxes.value = {\n ...columnAsSourceAndFixedAxes.value,\n axisFiltersByIndex: { ...columnAsSourceAndFixedAxes.value.axisFiltersByIndex, [idx]: value },\n };\n}\n\nconst currentOption = computed(() =>\n props.columnOptions.find((op) => op.id === columnAsSourceAndFixedAxes.value.source),\n);\nconst currentSpec = computed(() =>\n currentOption.value?.spec ? getNormalizedSpec(currentOption.value.spec) : null,\n);\nconst currentType = computed(() => currentSpec.value?.valueType);\nconst currentError = computed(\n () => Boolean(currentOption.value?.error) || inconsistentSourceSelected.value,\n);\n\nconst filterTypesOptions = computed(() =>\n props.supportedFilters\n .filter(\n (v) =>\n props.filter.type === v ||\n (currentSpec.value ? getFilterInfo(v).supportedFor(currentSpec.value) : true),\n )\n .map((v) => ({ value: v, label: getFilterInfo(v).label })),\n);\n\nconst wildcardOptions = computed(() => {\n if (props.filter.type !== \"patternFuzzyContainSubsequence\") {\n return [];\n }\n if (currentOption.value?.alphabet === \"nucleotide\") {\n return [{ label: \"N\", value: \"N\" }];\n }\n if (currentOption.value?.alphabet === \"aminoacid\") {\n return [{ label: \"X\", value: \"X\" }];\n }\n return [...new Set(props.filter.value.split(\"\"))].sort().map((v) => ({ value: v, label: v }));\n});\n\nconst stringMatchesError = computed(() => {\n if (props.filter.type !== \"patternMatchesRegularExpression\") {\n return false;\n }\n try {\n new RegExp(props.filter.value);\n return false;\n } catch {\n return true;\n }\n});\n</script>\n<template>\n <div :class=\"$style.filterWrapper\">\n <!-- top element - column selector / column label - for all filter types-->\n <div\n v-if=\"enableDnd\"\n :class=\"[$style.top, $style.columnChip, { [$style.error]: currentError }]\"\n >\n <div :class=\"[$style.typeIcon, { [$style.error]: currentError }]\">\n <PlIcon16 v-if=\"currentError\" name=\"warning\" />\n <PlIcon16\n v-else\n :name=\"\n currentType === 'String' || currentType === undefined\n ? 'cell-type-txt'\n : 'cell-type-num'\n \"\n />\n </div>\n <div :class=\"$style.titleWrapper\" :title=\"currentOption?.label ?? ''\">\n <div :class=\"$style.title\">\n {{\n inconsistentSourceSelected\n ? \"Inconsistent value\"\n : (currentOption?.label ?? props.filter.column)\n }}\n </div>\n </div>\n <div :class=\"$style.closeIcon\" @click=\"onDelete(props.filter.column)\">\n <PlIcon16 name=\"close\" />\n </div>\n </div>\n <div v-else :class=\"$style.top\">\n <PlDropdown\n :model-value=\"columnAsSourceAndFixedAxes.source\"\n :errorStatus=\"currentError\"\n :options=\"sourceOptions\"\n :style=\"{ width: '100%' }\"\n group-position=\"top-left\"\n @update:model-value=\"changeSourceId\"\n />\n <div :class=\"$style.closeButton\" @click=\"onDelete(props.filter.column)\">\n <PlIcon16 name=\"close\" />\n </div>\n </div>\n\n <div v-if=\"currentOption?.axesToBeFixed?.length\" :class=\"$style.fixedAxesBlock\">\n <template v-for=\"value in currentOption?.axesToBeFixed\" :key=\"value.idx\">\n <PlAutocomplete\n :model-value=\"columnAsSourceAndFixedAxes.axisFiltersByIndex[value.idx]\"\n :label=\"value.label\"\n :options-search=\"\n (str, type) =>\n getSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str, value.idx)\n \"\n :disabled=\"inconsistentSourceSelected\"\n :clearable=\"true\"\n @update:model-value=\"(v) => updateAxisFilterValue(value.idx, v)\"\n />\n </template>\n </div>\n\n <!-- middle - filter type selector - for all filter types -->\n <div\n :class=\"\n props.filter.type === 'isNA' || props.filter.type === 'isNotNA'\n ? $style.bottom\n : $style.middle\n \"\n >\n <PlDropdown\n :model-value=\"props.filter.type\"\n :options=\"filterTypesOptions\"\n :group-position=\"\n props.filter.type === 'isNA' || props.filter.type === 'isNotNA' ? 'bottom' : 'middle'\n \"\n @update:model-value=\"changeFilterType\"\n />\n </div>\n\n <!-- middle - for fuzzy contains filter -->\n <template v-if=\"props.filter.type === 'patternFuzzyContainSubsequence'\">\n <div :class=\"$style.middle\">\n <PlTextField\n :model-value=\"props.filter.value\"\n placeholder=\"Substring\"\n group-position=\"middle\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n </div>\n <div :class=\"$style.innerSection\">\n <Slider\n :model-value=\"props.filter.maxEdits\"\n :max=\"5\"\n breakpoints\n label=\"Maximum number of substitutions and indels\"\n @update:model-value=\"(v) => updateFilterProp('maxEdits', v)\"\n />\n <PlToggleSwitch\n :model-value=\"props.filter.substitutionsOnly\"\n label=\"Substitutions only\"\n @update:model-value=\"(v) => updateFilterProp('substitutionsOnly', v)\"\n />\n </div>\n </template>\n\n <!-- bottom element - individual settings for every filter type -->\n <div :class=\"$style.bottom\">\n <PlAutocomplete\n v-if=\"props.filter.type === 'patternEquals' || props.filter.type === 'patternNotEquals'\"\n :model-value=\"props.filter.value\"\n :options-search=\"\n (str, type) => getSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)\n \"\n :clearable=\"true\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlAutocompleteMulti\n v-if=\"props.filter.type === 'inSet' || props.filter.type === 'notInSet'\"\n :model-value=\"props.filter.value\"\n :options-search=\"\n (str, type) => getMultiSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)\n \"\n :disabled=\"inconsistentSourceSelected\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlNumberField\n v-if=\"isNumericFilter(props.filter)\"\n :model-value=\"props.filter.x\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('x', v)\"\n />\n <PlNumberField\n v-if=\"isPositionFilter(props.filter)\"\n :model-value=\"props.filter.n\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('n', v)\"\n />\n <PlTextField\n v-if=\"\n props.filter.type === 'patternContainSubsequence' ||\n props.filter.type === 'patternNotContainSubsequence'\n \"\n :model-value=\"props.filter.value\"\n placeholder=\"Substring\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlTextField\n v-if=\"props.filter.type === 'patternMatchesRegularExpression'\"\n :model-value=\"props.filter.value\"\n :error=\"stringMatchesError ? 'Regular expression is not valid' : undefined\"\n placeholder=\"Regular expression\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('value', v)\"\n />\n <PlDropdown\n v-if=\"props.filter.type === 'patternFuzzyContainSubsequence'\"\n :model-value=\"props.filter.wildcard\"\n clearable\n placeholder=\"Wildcard value\"\n :options=\"wildcardOptions\"\n group-position=\"bottom\"\n @update:model-value=\"(v) => updateFilterProp('wildcard', v)\"\n />\n </div>\n </div>\n <OperandButton :active=\"operand\" :disabled=\"isLast\" @select=\"onChangeOperand\" />\n</template>\n\n<style module>\n.filterWrapper {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n cursor: default;\n}\n\n.typeIcon {\n display: inline-flex;\n margin-right: 8px;\n}\n\n.typeIcon.error {\n --icon-color: var(--txt-error);\n}\n\n.closeIcon {\n display: inline-flex;\n margin-left: 12px;\n cursor: pointer;\n}\n\n.titleWrapper {\n flex-grow: 1;\n overflow: hidden;\n}\n.title {\n overflow: hidden;\n color: var(--txt-01);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 500;\n line-height: 20px;\n}\n\n.columnChip {\n width: 100%;\n display: flex;\n padding: 10px 12px;\n align-items: center;\n border-radius: 6px;\n border: 1px solid var(--txt-01);\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n\n &.error {\n border-color: var(--txt-error);\n }\n}\n\n.innerSection {\n border: 1px solid var(--txt-01);\n border-top: none;\n padding: 16px 12px;\n}\n\n.closeButton {\n border: 1px solid var(--txt-01);\n border-top-right-radius: 6px;\n border-left: none;\n width: 40px;\n height: 40px;\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n cursor: pointer;\n}\n\n.top {\n position: relative;\n display: flex;\n width: 100%;\n z-index: 1;\n background: #fff;\n}\n\n.fixedAxesBlock {\n position: relative;\n display: flex;\n flex-direction: column;\n padding: 12px 8px;\n gap: 12px;\n border-left: 1px solid var(--txt-01);\n border-right: 1px solid var(--txt-01);\n}\n\n.fixedAxesBlock > * {\n background: #fff;\n}\n\n.middle,\n.bottom {\n position: relative;\n margin-top: -1px;\n background: #fff;\n}\n</style>\n"],"mappings":"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"}