@globalbrain/sefirot 4.37.1 → 4.38.0

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.
@@ -97,7 +97,7 @@ const props = withDefaults(defineProps<Props>(), {
97
97
  canSort: true
98
98
  })
99
99
 
100
- const selected = defineModel<number[]>('selected')
100
+ const selected = defineModel<any[]>('selected')
101
101
  const hideConditions = defineModel<boolean>('hideConditions', { default: false })
102
102
 
103
103
  const emit = defineEmits<{
@@ -320,7 +320,7 @@ function onViewUpdated(newSelect: string[], newSelectable: string[], overrides:
320
320
  emit('overrides-updated', _overrides.value)
321
321
  }
322
322
 
323
- function onUpdateSelected(value: number[]) {
323
+ function onUpdateSelected(value: any[]) {
324
324
  selected.value = value
325
325
  }
326
326
 
@@ -339,6 +339,16 @@ function onNext() {
339
339
  }
340
340
 
341
341
  defineExpose({
342
+ /**
343
+ * Retrieve the current records in the catalog. This method is required when
344
+ * the parent component needs to access the records directly, for example, to
345
+ * handle mapping for selected records. Like `updateRecords`, this is also a
346
+ * hacky method and should be avoided if possible.
347
+ */
348
+ records(): Record<string, any>[] {
349
+ return result.value?.data ?? []
350
+ },
351
+
342
352
  /**
343
353
  * Mutates the fetched records directly. This exposed method can be used to
344
354
  * do in-place updates of records from the parent component. However, it's
@@ -17,7 +17,7 @@ import { useTrans } from '../../../composables/Lang'
17
17
  export interface Props {
18
18
  queryPh?: string
19
19
  filterPresets?: FilterPresets[]
20
- selected?: number[]
20
+ selected?: any[]
21
21
  showQuery?: boolean
22
22
  showFilters?: boolean
23
23
  isConditionActive?: boolean
@@ -14,11 +14,12 @@ const props = defineProps<{
14
14
  result?: LensResult
15
15
  overrides?: Record<string, Partial<FieldData>>
16
16
  loading: boolean
17
- selected?: number[]
17
+ selected?: any[]
18
+ indexField?: string
18
19
  }>()
19
20
 
20
21
  const emit = defineEmits<{
21
- 'update:selected': [value: number[]]
22
+ 'update:selected': [value: any[]]
22
23
  'filter-updated': [filter: any[]]
23
24
  'sort-updated': [sort: LensQuerySort]
24
25
  'cell-clicked': [value: any, record: any]
@@ -87,10 +88,11 @@ const table = useTable({
87
88
  records,
88
89
  orders,
89
90
  columns,
91
+ indexField: props.indexField,
90
92
  borderless: true
91
93
  })
92
94
 
93
- function onSelect(value?: number[]) {
95
+ function onSelect(value?: any[]) {
94
96
  emit('update:selected', value ?? [])
95
97
  }
96
98
 
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts" generic="S extends any = undefined">
2
2
  import { useVirtualizer } from '@tanstack/vue-virtual'
3
3
  import { useResizeObserver } from '@vueuse/core'
4
- import xor from 'lodash-es/xor'
4
+ import isEqual from 'lodash-es/isEqual'
5
5
  import { type CSSProperties, computed, nextTick, reactive, ref, toValue, unref, useTemplateRef, watch } from 'vue'
6
6
  import { type Table } from '../composables/Table'
7
7
  import { type VirtualRow, useTableAnimation } from '../composables/TableAnimation'
@@ -185,10 +185,9 @@ const control = computed({
185
185
  }
186
186
  })
187
187
 
188
- watch(indexes, (newValue, oldValue) => {
188
+ watch(indexes, (newValue) => {
189
189
  if (Array.isArray(selected.value)) {
190
- const removed = xor(newValue, oldValue)
191
- updateSelected(selected.value.filter((item) => !removed.includes(item)))
190
+ updateSelected(newValue.filter((item) => includesSelection(selected.value as any[], item)))
192
191
  }
193
192
  })
194
193
 
@@ -431,6 +430,10 @@ function getCell(key: string, index: number) {
431
430
  return isSummary(index) && col?.summaryCell ? col?.summaryCell : col?.cell
432
431
  }
433
432
 
433
+ function includesSelection(items: unknown[], target: unknown): boolean {
434
+ return items.some((item) => isEqual(item, target))
435
+ }
436
+
434
437
  function updateSelected(items: any) {
435
438
  if (Array.isArray(selected.value)) {
436
439
  selected.value = [...items] as any
@@ -440,11 +443,17 @@ function updateSelected(items: any) {
440
443
  }
441
444
 
442
445
  function addSelected(item: any) {
443
- updateSelected([...(selected.value as any), item])
446
+ const items = selected.value as any[]
447
+
448
+ if (includesSelection(items, item)) {
449
+ return
450
+ }
451
+
452
+ updateSelected([...items, item])
444
453
  }
445
454
 
446
455
  function removeSelected(item: any) {
447
- updateSelected((selected.value as any[]).filter((i) => i !== item))
456
+ updateSelected((selected.value as any[]).filter((i) => !isEqual(i, item)))
448
457
  }
449
458
 
450
459
  function getColWidth(key: string) {
@@ -603,13 +612,13 @@ function onResizeEnd(data: { columnName: string; finalWidth: string }) {
603
612
  <template v-if="key === '__select' && !isSummary(item.index)">
604
613
  <SInputCheckbox
605
614
  v-if="Array.isArray(selected)"
606
- :model-value="selected.includes(indexes[item.index])"
615
+ :model-value="includesSelection(selected, indexes[item.index])"
607
616
  :disabled="options.disableSelection?.(recordsWithSummary[item.index]) === true"
608
617
  @update:model-value="(c) => (c ? addSelected : removeSelected)(indexes[item.index])"
609
618
  />
610
619
  <SInputRadio
611
620
  v-else
612
- :model-value="selected === indexes[item.index]"
621
+ :model-value="isEqual(selected, indexes[item.index])"
613
622
  :disabled="options.disableSelection?.(recordsWithSummary[item.index]) === true"
614
623
  @update:model-value="(c) => updateSelected(c ? indexes[item.index] : null)"
615
624
  />
@@ -26,6 +26,10 @@ const props = defineProps<{
26
26
  const computedCell = computed<TableCell | undefined>(() =>
27
27
  typeof props.cell === 'function' ? props.cell(props.value, props.record) : props.cell
28
28
  )
29
+
30
+ const valueIsImagePath = computed(() => {
31
+ return typeof props.value === 'string' && props.value.includes('/')
32
+ })
29
33
  </script>
30
34
 
31
35
  <template>
@@ -89,8 +93,8 @@ const computedCell = computed<TableCell | undefined>(() =>
89
93
  v-else-if="computedCell.type === 'avatar'"
90
94
  :value
91
95
  :record
92
- :image="computedCell.image ?? ((value as string).includes('/') ? value : null)"
93
- :name="computedCell.name ?? ((value as string).includes('/') ? null : value)"
96
+ :image="computedCell.image ?? (valueIsImagePath ? value : null)"
97
+ :name="computedCell.name ?? (valueIsImagePath ? null : value)"
94
98
  :link="computedCell.link"
95
99
  :color="computedCell.color"
96
100
  :on-click="computedCell.onClick"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
- "version": "4.37.1",
3
+ "version": "4.38.0",
4
4
  "description": "Vue Components for Global Brain Design System.",
5
5
  "keywords": [
6
6
  "components",
@@ -59,8 +59,8 @@
59
59
  "@iconify-json/ph": "^1.2.2",
60
60
  "@iconify-json/ri": "^1.2.10",
61
61
  "@popperjs/core": "^2.11.8",
62
- "@sentry/browser": "^10.39.0",
63
- "@sentry/vue": "^10.39.0",
62
+ "@sentry/browser": "^10.40.0",
63
+ "@sentry/vue": "^10.40.0",
64
64
  "@tanstack/vue-virtual": "3.0.0-beta.62",
65
65
  "@tinyhttp/content-disposition": "^2.2.4",
66
66
  "@tinyhttp/cookie": "^2.1.1",
@@ -72,7 +72,7 @@
72
72
  "@types/markdown-it": "^14.1.2",
73
73
  "@types/qs": "^6.14.0",
74
74
  "@vitejs/plugin-vue": "^6.0.4",
75
- "@vue/reactivity": "^3.5.28",
75
+ "@vue/reactivity": "^3.5.29",
76
76
  "@vuelidate/core": "^2.0.3",
77
77
  "@vuelidate/validators": "^2.0.4",
78
78
  "@vueuse/core": "^14.2.1",
@@ -97,7 +97,7 @@
97
97
  "unplugin-icons": "^23.0.1",
98
98
  "v-calendar": "3.0.1",
99
99
  "vite": "^7.3.1",
100
- "vue": "^3.5.28",
100
+ "vue": "^3.5.29",
101
101
  "vue-draggable-plus": "^0.6.1",
102
102
  "vue-router": "^4.6.4"
103
103
  },
@@ -105,8 +105,8 @@
105
105
  "@globalbrain/eslint-config": "^3.0.1",
106
106
  "@histoire/plugin-vue": "1.0.0-beta.1",
107
107
  "@release-it/conventional-changelog": "^10.0.5",
108
- "@types/jsdom": "^27.0.0",
109
- "@types/node": "^25.3.0",
108
+ "@types/jsdom": "^28.0.0",
109
+ "@types/node": "^25.3.3",
110
110
  "@vitest/coverage-v8": "^4.0.18",
111
111
  "@vue/test-utils": "^2.4.6",
112
112
  "eslint": "^9.39.3",
@@ -118,5 +118,5 @@
118
118
  "vitest": "^4.0.18",
119
119
  "vue-tsc": "^3.2.5"
120
120
  },
121
- "packageManager": "pnpm@10.30.1"
121
+ "packageManager": "pnpm@10.30.3"
122
122
  }