@platforma-sdk/ui-vue 1.14.2 → 1.14.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/ui-vue",
3
- "version": "1.14.2",
3
+ "version": "1.14.5",
4
4
  "type": "module",
5
5
  "main": "dist/lib.umd.cjs",
6
6
  "module": "dist/lib.js",
@@ -38,7 +38,7 @@
38
38
  "@ag-grid-enterprise/side-bar": "^32.3.3",
39
39
  "@ag-grid-enterprise/column-tool-panel": "^32.3.3",
40
40
  "@platforma-sdk/model": "^1.14.1",
41
- "@milaboratories/uikit": "^2.2.18"
41
+ "@milaboratories/uikit": "^2.2.19"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@faker-js/faker": "^9.2.0",
@@ -8,6 +8,7 @@ const entry = defineModel<PlTableFiltersStateEntry>({ required: true });
8
8
  const props = defineProps<{
9
9
  column: Readonly<PTableColumnSpec>;
10
10
  options: Readonly<ListOption<PlTableFilterType>[]>;
11
+ disabled?: boolean;
11
12
  }>();
12
13
  const { column, options } = toRefs(props);
13
14
  </script>
@@ -17,6 +18,7 @@ const { column, options } = toRefs(props);
17
18
  <PlDropdown
18
19
  :model-value="entry.filter.type"
19
20
  :options="options"
21
+ :disabled="disabled"
20
22
  label="Predicate"
21
23
  @update:model-value="(type) => (entry = changeFilterType(entry, type!))"
22
24
  />
@@ -30,13 +32,28 @@ const { column, options } = toRefs(props);
30
32
  entry.filter.type === 'number_greaterThanOrEqualTo'
31
33
  "
32
34
  >
33
- <PlTextField v-model="entry.filter.reference" :parse="(value: string): number => parseNumber(column, value)" label="Reference value" />
35
+ <PlTextField
36
+ v-model="entry.filter.reference"
37
+ :disabled="disabled"
38
+ :parse="(value: string): number => parseNumber(column, value)"
39
+ label="Reference value"
40
+ />
34
41
  </template>
35
42
  <template v-if="entry.filter.type === 'number_between'">
36
- <PlTextField v-model="entry.filter.lowerBound" :parse="(value: string): number => parseNumber(column, value)" label="Lower bound" />
37
- <PlToggleSwitch v-model="entry.filter.includeLowerBound" label="Include lower bound" />
38
- <PlTextField v-model="entry.filter.upperBound" :parse="(value: string): number => parseNumber(column, value)" label="Upper bound" />
39
- <PlToggleSwitch v-model="entry.filter.includeUpperBound" label="Include upper bound" />
43
+ <PlTextField
44
+ v-model="entry.filter.lowerBound"
45
+ :disabled="disabled"
46
+ :parse="(value: string): number => parseNumber(column, value)"
47
+ label="Lower bound"
48
+ />
49
+ <PlToggleSwitch v-model="entry.filter.includeLowerBound" :disabled="disabled" label="Include lower bound" />
50
+ <PlTextField
51
+ v-model="entry.filter.upperBound"
52
+ :disabled="disabled"
53
+ :parse="(value: string): number => parseNumber(column, value)"
54
+ label="Upper bound"
55
+ />
56
+ <PlToggleSwitch v-model="entry.filter.includeUpperBound" :disabled="disabled" label="Include upper bound" />
40
57
  </template>
41
58
  <template
42
59
  v-if="
@@ -46,16 +63,32 @@ const { column, options } = toRefs(props);
46
63
  entry.filter.type === 'string_doesNotContain'
47
64
  "
48
65
  >
49
- <PlTextField v-model="entry.filter.reference" :parse="(value: string): string => parseString(column, value)" label="Reference value" />
66
+ <PlTextField
67
+ v-model="entry.filter.reference"
68
+ :disabled="disabled"
69
+ :parse="(value: string): string => parseString(column, value)"
70
+ label="Reference value"
71
+ />
50
72
  </template>
51
73
  <template v-if="entry.filter.type === 'string_matches' || entry.filter.type === 'string_doesNotMatch'">
52
- <PlTextField v-model="entry.filter.reference" :parse="parseRegex" label="Reference value" />
74
+ <PlTextField v-model="entry.filter.reference" :disabled="disabled" :parse="parseRegex" label="Reference value" />
53
75
  </template>
54
76
  <template v-if="entry.filter.type === 'string_containsFuzzyMatch'">
55
- <PlTextField v-model="entry.filter.reference" :parse="(value: string): string => parseString(column, value)" label="Reference value" />
56
- <Slider v-model="entry.filter.maxEdits" :max="5" breakpoints label="Maximum nuber of substitutions and indels" />
57
- <PlToggleSwitch v-model="entry.filter.substitutionsOnly" label="Substitutions only" />
58
- <PlDropdown v-model="entry.filter.wildcard" :options="makeWildcardOptions(column, entry.filter.reference)" clearable label="Wildcard symbol" />
77
+ <PlTextField
78
+ v-model="entry.filter.reference"
79
+ :disabled="disabled"
80
+ :parse="(value: string): string => parseString(column, value)"
81
+ label="Reference value"
82
+ />
83
+ <Slider v-model="entry.filter.maxEdits" :max="5" :disabled="disabled" breakpoints label="Maximum nuber of substitutions and indels" />
84
+ <PlToggleSwitch v-model="entry.filter.substitutionsOnly" :disabled="disabled" label="Substitutions only" />
85
+ <PlDropdown
86
+ v-model="entry.filter.wildcard"
87
+ :disabled="disabled"
88
+ :options="makeWildcardOptions(column, entry.filter.reference)"
89
+ clearable
90
+ label="Wildcard symbol"
91
+ />
59
92
  </template>
60
93
  </div>
61
94
  </template>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" setup>
2
2
  import type { ListOption } from '@milaboratories/uikit';
3
3
  import { PlBtnGhost, PlIcon24, PlSlideModal, PlMaskIcon16, PlMaskIcon24 } from '@milaboratories/uikit';
4
- import { computed, onMounted, reactive, ref, toRefs, watch } from 'vue';
4
+ import { computed, onBeforeUnmount, onMounted, reactive, ref, toRefs, watch } from 'vue';
5
5
  import type {
6
6
  PlTableFiltersModel,
7
7
  PlTableFilterType,
@@ -176,6 +176,35 @@ const toggleExpandFilter = (columnId: PlTableFilterColumnId) => {
176
176
  if (!openState[columnId]) openState[columnId] = true;
177
177
  else delete openState[columnId];
178
178
  };
179
+
180
+ const scrollIsActive = ref(false);
181
+ const filterManager = ref<HTMLElement>();
182
+ let observer: ResizeObserver;
183
+ onMounted(() => {
184
+ observer = new ResizeObserver(() => {
185
+ const parent = filterManager.value?.parentElement;
186
+ if (!parent) return;
187
+ scrollIsActive.value = parent.scrollHeight > parent.clientHeight || parent.scrollWidth > parent.clientWidth;
188
+ });
189
+ if (filterManager.value && filterManager.value.parentElement) {
190
+ observer.observe(filterManager.value!.parentElement);
191
+ }
192
+ });
193
+
194
+ watch(filterManager, (newElement, oldElement) => {
195
+ if (oldElement?.parentElement) {
196
+ observer.unobserve(oldElement.parentElement);
197
+ }
198
+ if (newElement?.parentElement) {
199
+ observer.observe(newElement.parentElement);
200
+ }
201
+ });
202
+
203
+ onBeforeUnmount(() => {
204
+ if (observer !== undefined) {
205
+ observer.disconnect();
206
+ }
207
+ });
179
208
  </script>
180
209
 
181
210
  <template>
@@ -190,11 +219,11 @@ const toggleExpandFilter = (columnId: PlTableFilterColumnId) => {
190
219
 
191
220
  <PlSlideModal v-model="showManager" :close-on-outside-click="false">
192
221
  <template #title>Manage Filters</template>
193
- <div class="pl-filter-manager d-flex flex-column gap-6">
222
+ <div ref="filterManager" class="pl-filter-manager d-flex flex-column gap-6">
194
223
  <div
195
224
  v-for="(entry, index) in reactiveModel.state"
196
225
  :key="entry.columnId"
197
- :class="{ open: openState[entry.columnId] }"
226
+ :class="{ open: openState[entry.columnId], disabled: entry.disabled }"
198
227
  class="pl-filter-manager__filter"
199
228
  >
200
229
  <div class="pl-filter-manager__header d-flex align-center gap-8" @click="toggleExpandFilter(entry.columnId)">
@@ -202,7 +231,7 @@ const toggleExpandFilter = (columnId: PlTableFilterColumnId) => {
202
231
  <PlMaskIcon16 name="chevron-right" />
203
232
  </div>
204
233
 
205
- <div class="pl-filter-manager__title flex-grow-1 text-s">{{ getColumnName(columnsById[entry.columnId], index) }}</div>
234
+ <div class="pl-filter-manager__title flex-grow-1 text-s-btn">{{ getColumnName(columnsById[entry.columnId], index) }}</div>
206
235
 
207
236
  <div class="pl-filter-manager__actions d-flex gap-12">
208
237
  <div class="pl-filter-manager__toggle" @click.stop="entry.disabled = !entry.disabled">
@@ -216,10 +245,19 @@ const toggleExpandFilter = (columnId: PlTableFilterColumnId) => {
216
245
  </div>
217
246
 
218
247
  <div class="pl-filter-manager__content d-flex gap-24 p-24 flex-column">
219
- <PlTableFilterEntry v-model="reactiveModel.state[index]" :column="columnsById[entry.columnId]" :options="filterOptions[entry.columnId]" />
248
+ <PlTableFilterEntry
249
+ v-model="reactiveModel.state[index]"
250
+ :disabled="entry.disabled"
251
+ :column="columnsById[entry.columnId]"
252
+ :options="filterOptions[entry.columnId]"
253
+ />
220
254
 
221
255
  <div class="d-flex justify-center">
222
- <div class="pl-filter-manager__revert-btn text-s d-flex align-center gap-8" @click="resetFilter(index)">
256
+ <div
257
+ :class="{ disabled: entry.disabled }"
258
+ class="pl-filter-manager__revert-btn text-s-btn d-flex align-center gap-8"
259
+ @click="resetFilter(index)"
260
+ >
223
261
  Revert Settings to Default
224
262
  <PlMaskIcon24 name="reverse" />
225
263
  </div>
@@ -227,11 +265,13 @@ const toggleExpandFilter = (columnId: PlTableFilterColumnId) => {
227
265
  </div>
228
266
  </div>
229
267
 
230
- <div v-if="columnOptions.length > 0" class="pl-filter-manager__add-btn" @click="showAddFilter = true">
231
- <div class="pl-filter-manager__add-btn-icon">
232
- <PlMaskIcon16 name="add" />
268
+ <div :class="{ 'pt-24': scrollIsActive }" class="pl-filter-manager__add-action-wrapper">
269
+ <div v-if="columnOptions.length > 0" class="pl-filter-manager__add-btn" @click="showAddFilter = true">
270
+ <div class="pl-filter-manager__add-btn-icon">
271
+ <PlMaskIcon16 name="add" />
272
+ </div>
273
+ <div class="pl-filter-manager__add-btn-title text-s-btn">Add Filter</div>
233
274
  </div>
234
- <div class="pl-filter-manager__add-btn-title">Add Filter</div>
235
275
  </div>
236
276
 
237
277
  <div v-if="!filterOptionsPresent">No filters applicable</div>
@@ -1,11 +1,20 @@
1
1
  .pl-filter-manager {
2
2
  $this: &;
3
3
 
4
- &__add-btn {
5
- height: 40px;
4
+ .text-s {
5
+ font-weight: 600;
6
+ }
7
+
8
+ &__add-action-wrapper {
6
9
  position: sticky;
7
10
  bottom: -16px;
8
11
  background-color: var(--bg-elevated-01);
12
+ transition: all .15s ease-in-out;
13
+ }
14
+
15
+ &__add-btn {
16
+ height: 40px;
17
+ background-color: var(--bg-elevated-01);
9
18
  display: flex;
10
19
  align-items: center;
11
20
  gap: 8px;
@@ -17,6 +26,12 @@
17
26
  cursor: pointer;
18
27
  }
19
28
 
29
+ &__add-btn:hover {
30
+ border-radius: 6px;
31
+ border: 1px dashed var(--border-color-focus, #49CC49);
32
+ background: rgba(99, 224, 36, 0.12);
33
+ }
34
+
20
35
  &__add-btn-title {
21
36
  flex-grow: 1;
22
37
  }
@@ -51,11 +66,29 @@
51
66
 
52
67
  &__toggle,
53
68
  &__delete {
69
+ display: none;
70
+
54
71
  .mask-24 {
55
72
  background-color: var(--ic-02);
56
73
  }
57
74
  }
58
75
 
76
+ &__toggle:hover {
77
+ .mask-24 {
78
+ background-color: var(--ic-01);
79
+ }
80
+ }
81
+
82
+ &__delete:hover {
83
+ .mask-24 {
84
+ background-color: var(--ic-01);
85
+ }
86
+ }
87
+
88
+ &__filter:hover &__toggle,
89
+ &__filter:hover &__delete {
90
+ display: block;
91
+ }
59
92
 
60
93
  &__filter {
61
94
  border-radius: 6px;
@@ -65,6 +98,18 @@
65
98
  overflow: auto;
66
99
  }
67
100
 
101
+ &__filter.disabled {
102
+
103
+ #{$this}__expand-icon,
104
+ #{$this}__title {
105
+ opacity: 0.3;
106
+ }
107
+ }
108
+
109
+ &__filter:hover {
110
+ background-color: var(--bg-elevated-01);
111
+ }
112
+
68
113
  &__filter.open {
69
114
  background-color: var(--bg-elevated-01);
70
115
 
@@ -95,4 +140,9 @@
95
140
  &__revert-btn:hover {
96
141
  background-color: var(--btn-sec-hover-grey);
97
142
  }
98
- }
143
+
144
+ &__revert-btn.disabled {
145
+ opacity: 0.3;
146
+ pointer-events: none;
147
+ }
148
+ }