@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
@@ -17,6 +17,7 @@ export type Props = {
17
17
  </script>
18
18
  <script setup lang="ts">
19
19
  import { computed } from "vue";
20
+ import { produce } from "immer";
20
21
  import { randomInt } from "@milaboratories/helpers";
21
22
  import { PlBtnSecondary, PlEditableTitle, PlSidebarItem } from "@milaboratories/uikit";
22
23
  import type { ListOptionBase, PObjectId, SUniversalPColumnId } from "@platforma-sdk/model";
@@ -29,33 +30,54 @@ import type {
29
30
  PlAdvancedFilter,
30
31
  } from "../../PlAdvancedFilter";
31
32
  import type { Filter } from "../types";
33
+ import { validateTitle } from "../utils";
32
34
 
33
35
  import $commonStyle from "./style.module.css";
34
- import { validateTitle } from "../utils";
35
36
 
36
- // Models
37
- const step = defineModel<Filter>("step", { required: true });
38
- // Props
39
- const props = defineProps<Props>();
40
- // State
37
+ const props = defineProps<
38
+ Props & {
39
+ step: Filter;
40
+ onUpdateStep: (step: Filter) => void;
41
+ }
42
+ >();
43
+
41
44
  const withSelection = computed(() => {
42
45
  return props.hasSelectedColumns !== undefined && props.getValuesForSelectedColumns !== undefined;
43
46
  });
44
- // Actions
45
- const addFilterPlaceholder = () => {
46
- step.value.filter.filters.push({
47
- id: randomInt(),
48
- isExpanded: true,
49
- type: "or",
50
- filters: [
51
- {
52
- id: randomInt(),
53
- type: "isNA",
54
- column: props.columns[0].id as SUniversalPColumnId,
55
- },
56
- ],
47
+
48
+ function produceStepUpdate(updater: (draft: Filter) => void) {
49
+ props.onUpdateStep(produce(props.step, updater));
50
+ }
51
+
52
+ function updateLabel(label: string) {
53
+ produceStepUpdate((draft) => {
54
+ draft.label = label;
57
55
  });
58
- };
56
+ }
57
+
58
+ function updateFilter(filter: PlAdvancedFilter) {
59
+ produceStepUpdate((draft) => {
60
+ draft.filter = filter as typeof draft.filter;
61
+ });
62
+ }
63
+
64
+ function addFilterPlaceholder() {
65
+ if (props.columns.length === 0) return;
66
+ produceStepUpdate((draft) => {
67
+ draft.filter.filters.push({
68
+ id: randomInt(),
69
+ isExpanded: true,
70
+ type: "or",
71
+ filters: [
72
+ {
73
+ id: randomInt(),
74
+ type: "isNA",
75
+ column: props.columns[0].id as SUniversalPColumnId,
76
+ },
77
+ ],
78
+ });
79
+ });
80
+ }
59
81
 
60
82
  async function addFilterFromSelected() {
61
83
  if (props.hasSelectedColumns === undefined || props.getValuesForSelectedColumns === undefined)
@@ -68,17 +90,19 @@ async function addFilterFromSelected() {
68
90
  const shortReminder =
69
91
  values.slice(0, 3).join(", ") + (values.length > 3 ? ` and ${values.length - 3} more` : "");
70
92
 
71
- step.value.filter.filters.push({
72
- id: randomInt(),
73
- name: `Selected list (${shortReminder})`,
74
- isExpanded: false,
75
- type: "or",
76
- filters: values.map((value, i) => ({
77
- id: i,
78
- type: "patternEquals",
79
- column: columnId as SUniversalPColumnId,
80
- value,
81
- })),
93
+ produceStepUpdate((draft) => {
94
+ draft.filter.filters.push({
95
+ id: randomInt(),
96
+ name: `Selected list (${shortReminder})`,
97
+ isExpanded: false,
98
+ type: "or",
99
+ filters: values.map((value, i) => ({
100
+ id: i,
101
+ type: "patternEquals",
102
+ column: columnId as SUniversalPColumnId,
103
+ value,
104
+ })),
105
+ });
82
106
  });
83
107
  }
84
108
 
@@ -101,29 +125,30 @@ const supportedFilters = [
101
125
  </script>
102
126
 
103
127
  <template>
104
- <PlSidebarItem v-if="step">
128
+ <PlSidebarItem v-if="props.step">
105
129
  <template #header-content>
106
130
  <PlEditableTitle
107
- :key="step.id"
108
- v-model="step.label"
109
- :class="{ [$commonStyle.flashing]: step.label.length === 0 }"
131
+ :key="props.step.id"
132
+ :model-value="props.step.label"
133
+ :class="{ [$commonStyle.flashing]: props.step.label.length === 0 }"
110
134
  :max-length="40"
111
135
  max-width="600px"
112
136
  placeholder="Label"
113
- :autofocus="step.label.length === 0"
137
+ :autofocus="props.step.label.length === 0"
114
138
  :validate="validateTitle"
139
+ @update:model-value="updateLabel"
115
140
  />
116
141
  </template>
117
142
  <template #body-content>
118
143
  <PlAdvancedFilterComponent
119
- :filters="step.filter as PlAdvancedFilter"
120
- :class="[$style.root, { [$commonStyle.disabled]: step.label.length === 0 }]"
144
+ :class="[$style.root, { [$commonStyle.disabled]: props.step.label.length === 0 }]"
121
145
  :options="props.columns"
146
+ :filters="props.step.filter as PlAdvancedFilter"
147
+ :on-update-filters="updateFilter"
122
148
  :supported-filters="supportedFilters"
123
149
  :get-suggest-options="props.getSuggestOptions"
124
150
  :enable-dnd="false"
125
151
  :enable-add-group-button="true"
126
- @update-filters="(v) => (step = { ...step, filter: v as typeof step.filter })"
127
152
  >
128
153
  <template #add-group-buttons>
129
154
  <div :class="$style.actions">
@@ -131,7 +156,7 @@ const supportedFilters = [
131
156
  <PlBtnSecondary
132
157
  v-if="withSelection"
133
158
  icon="add"
134
- :disabled="!props.hasSelectedColumns"
159
+ :disabled="props.hasSelectedColumns !== true"
135
160
  @click="addFilterFromSelected"
136
161
  >
137
162
  From selection
@@ -1,6 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { Props as BaseProps } from "./FilterSidebar.vue";
3
- export type Props = BaseProps & {
3
+ export type Props = Omit<BaseProps, "step" | "onUpdateStep"> & {
4
+ annotation: Annotation;
5
+ onUpdateAnnotation: (annotation: Annotation) => void;
4
6
  onDeleteSchema?: () => void;
5
7
  };
6
8
  </script>
@@ -9,65 +11,79 @@ export type Props = BaseProps & {
9
11
  import { computed, effect, shallowRef } from "vue";
10
12
 
11
13
  import { isNil } from "@milaboratories/helpers";
14
+ import { produce } from "immer";
12
15
  import { PlSidebarGroup, useConfirm } from "@milaboratories/uikit";
13
16
 
14
- import type { Annotation } from "../types";
17
+ import type { Annotation, Filter } from "../types";
15
18
  import AnnotationsSidebar from "./AnnotationsSidebar.vue";
16
19
  import FilterSidebar from "./FilterSidebar.vue";
17
20
 
18
- // Models
19
- const annotation = defineModel<Annotation>("annotation", { required: true });
20
- // Props
21
21
  const props = defineProps<Props>();
22
- // State
23
- const selectedStepId = shallowRef<number | undefined>(undefined);
22
+
23
+ const selectedStepId = shallowRef<undefined | number>(undefined);
24
+
24
25
  const selectedStep = computed(() => {
25
- return isNil(selectedStepId.value) || isNil(annotation.value)
26
+ return isNil(selectedStepId.value) || isNil(props.annotation)
26
27
  ? undefined
27
- : annotation.value.steps.find((step) => step.id === selectedStepId.value);
28
+ : props.annotation.steps.find((step) => step.id === selectedStepId.value);
28
29
  });
29
30
 
30
- // Watchers
31
31
  effect(function setDefaultStepId() {
32
- if (selectedStepId.value === undefined && annotation.value.steps.length > 0) {
33
- selectedStepId.value = annotation.value.steps[0].id;
32
+ if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {
33
+ selectedStepId.value = props.annotation.steps[0].id;
34
34
  }
35
35
  });
36
- // Hooks
36
+
37
37
  const confirmResetSchema = useConfirm({
38
38
  title: "Reset Schema",
39
39
  message: "Are you sure you want to reset the schema? This action cannot be undone.",
40
40
  confirmLabel: "Yes, reset",
41
41
  cancelLabel: "No, cancel",
42
42
  });
43
- // Actions
43
+
44
44
  async function handleDeleteSchema() {
45
45
  if (await confirmResetSchema()) {
46
46
  selectedStepId.value = undefined;
47
47
  props.onDeleteSchema?.();
48
48
  }
49
49
  }
50
+
51
+ function updateSelectedStepId(id: undefined | number) {
52
+ selectedStepId.value = id;
53
+ }
54
+
55
+ function updateSelectedStep(step: Filter) {
56
+ props.onUpdateAnnotation(
57
+ produce(props.annotation, (draft) => {
58
+ const idx = draft.steps.findIndex((s) => s.id === step.id);
59
+ if (idx !== -1) {
60
+ draft.steps[idx] = step;
61
+ }
62
+ }),
63
+ );
64
+ }
50
65
  </script>
51
66
 
52
67
  <template>
53
68
  <PlSidebarGroup>
54
69
  <template #item-0>
55
70
  <AnnotationsSidebar
56
- v-model:annotation="annotation"
57
- v-model:selectedStepId="selectedStepId"
71
+ :annotation="props.annotation"
72
+ :selected-step-id="selectedStepId"
73
+ :on-update-annotation="props.onUpdateAnnotation"
74
+ :on-update-selected-step-id="updateSelectedStepId"
58
75
  :class="$style.sidebarItem"
59
- :columns="props.columns"
60
76
  @delete-schema="handleDeleteSchema"
61
77
  />
62
78
  </template>
63
79
  <template #item-1>
64
80
  <FilterSidebar
65
81
  v-if="selectedStep"
66
- v-model:step="selectedStep"
82
+ :step="selectedStep"
83
+ :on-update-step="updateSelectedStep"
67
84
  :class="$style.sidebarItem"
68
85
  :columns="props.columns"
69
86
  :get-suggest-options="props.getSuggestOptions"
70
- :selectedStepId="selectedStepId"
71
87
  :hasSelectedColumns="props.hasSelectedColumns"
72
88
  :getValuesForSelectedColumns="props.getValuesForSelectedColumns"
73
89
  />
@@ -1,41 +1,38 @@
1
1
  <script setup lang="ts">
2
2
  import { PlPureSlideModal } from "@milaboratories/uikit";
3
- import { effect, shallowRef } from "vue";
4
3
 
5
- import type { Annotation } from "../types";
6
4
  import type { Props } from "./PlAnnotations.vue";
7
5
  import PlAnnotations from "./PlAnnotations.vue";
8
6
 
9
- // Models
10
- const annotation = defineModel<Annotation>("annotation", { required: true });
11
- const opened = defineModel<boolean>("opened", { required: true });
12
- // Props
13
- const props = defineProps<Props>();
14
- // State
15
- const selectedStepId = shallowRef<number | undefined>(undefined);
16
- // Watchers
17
- effect(function setDefaultStepId() {
18
- if (selectedStepId.value === undefined && annotation.value.steps.length > 0) {
19
- selectedStepId.value = annotation.value.steps[0].id;
7
+ const props = defineProps<
8
+ Props & {
9
+ opened: boolean;
10
+ onUpdateOpened: (opened: boolean) => void;
20
11
  }
21
- });
22
- // Actions
12
+ >();
13
+
23
14
  async function handleDeleteSchema() {
24
- opened.value = false;
15
+ props.onUpdateOpened(false);
25
16
  props.onDeleteSchema?.();
26
17
  }
27
18
  </script>
28
19
 
29
20
  <template>
30
- <PlPureSlideModal v-model="opened" :class="$style.modal" width="768px">
21
+ <PlPureSlideModal
22
+ :model-value="props.opened"
23
+ :class="$style.modal"
24
+ width="768px"
25
+ @update:model-value="props.onUpdateOpened"
26
+ >
31
27
  <PlAnnotations
32
- v-model:annotation="annotation"
33
28
  :class="$style.content"
34
29
  :columns="props.columns"
35
- :get-suggest-options="props.getSuggestOptions"
30
+ :annotation="props.annotation"
31
+ :on-update-annotation="props.onUpdateAnnotation"
32
+ :on-delete-schema="handleDeleteSchema"
36
33
  :has-selected-columns="props.hasSelectedColumns"
37
- :getValuesForSelectedColumns="props.getValuesForSelectedColumns"
38
- @delete-schema="handleDeleteSchema"
34
+ :get-suggest-options="props.getSuggestOptions"
35
+ :get-values-for-selected-columns="props.getValuesForSelectedColumns"
39
36
  />
40
37
  </PlPureSlideModal>
41
38
  </template>