@dataloop-ai/components 0.20.156 → 0.20.158

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": "@dataloop-ai/components",
3
- "version": "0.20.156",
3
+ "version": "0.20.158",
4
4
  "exports": {
5
5
  ".": "./index.ts",
6
6
  "./models": "./models.ts",
@@ -17,7 +17,7 @@
17
17
  ? defaultIconColor
18
18
  : statusIconColor || defaultIconColor
19
19
  "
20
- size="12px"
20
+ size="16px"
21
21
  :inline="false"
22
22
  />
23
23
  </div>
@@ -49,7 +49,7 @@
49
49
  :disabled="disabled"
50
50
  @mousedown="onClear"
51
51
  />
52
- <dl-tooltip> Clear Query </dl-tooltip>
52
+ <dl-tooltip> Clear </dl-tooltip>
53
53
  </div>
54
54
  </div>
55
55
  <dl-tooltip
@@ -62,9 +62,7 @@
62
62
  self="top left"
63
63
  >
64
64
  <div style="padding: 10px">
65
- <div class="tooltip-title">
66
- Schema Based Search
67
- </div>
65
+ <div class="tooltip-title">Schema Based Search</div>
68
66
  <div class="tooltip-subtitle">
69
67
  A powerful and flexible search. Allows users to
70
68
  construct queries based on specific field selection
@@ -430,14 +428,12 @@ export default defineComponent({
430
428
 
431
429
  const _normalizeLogicalOperators = (value: string): string => {
432
430
  const logicalOperatorsRegEx = /\s(and|or)\s/g
433
- return value.replace(
434
- logicalOperatorsRegEx,
435
- (match, op, offset) => {
436
- const textBeforeTheMatch = value.substring(0, offset)
437
- const isMatchInsideQuotes = isInsideQuotedString(textBeforeTheMatch)
438
- return isMatchInsideQuotes ? match : ` ${op.toUpperCase()} `
439
- }
440
- )
431
+ return value.replace(logicalOperatorsRegEx, (match, op, offset) => {
432
+ const textBeforeTheMatch = value.substring(0, offset)
433
+ const isMatchInsideQuotes =
434
+ isInsideQuotedString(textBeforeTheMatch)
435
+ return isMatchInsideQuotes ? match : ` ${op.toUpperCase()} `
436
+ })
441
437
  }
442
438
 
443
439
  const setInputFromSuggestion = (suggestion: any) => {
@@ -448,7 +444,7 @@ export default defineComponent({
448
444
  const search = searchQuery.value ?? ''
449
445
  const tokens = tokenize(search)
450
446
  let leftTokenIndex = tokens.length
451
- while(leftTokenIndex-- > 0) {
447
+ while (leftTokenIndex-- > 0) {
452
448
  if (tokens[leftTokenIndex].pos < caretAt.value) {
453
449
  break
454
450
  }
@@ -459,15 +455,19 @@ export default defineComponent({
459
455
  caretPosition = value.length + 1
460
456
  } else {
461
457
  const token = tokens[leftTokenIndex]
462
- const tokenLeftText = token.text.substring(0, caretAt.value - token.pos)
463
- const tokenRightText = token.text.substring(caretAt.value - token.pos)
458
+ const tokenLeftText = token.text.substring(
459
+ 0,
460
+ caretAt.value - token.pos
461
+ )
462
+ const tokenRightText = token.text.substring(
463
+ caretAt.value - token.pos
464
+ )
464
465
 
465
466
  if (token.type === TokenType.WHITESPACE) {
466
467
  // caret after space
467
468
  token.text = ' ' + value + ' '
468
469
  caretPosition = token.pos + 1 + value.length + 1
469
- } else
470
- if (['AND', 'OR'].includes(value)) {
470
+ } else if (['AND', 'OR'].includes(value)) {
471
471
  // do not replace text if the value is AND or OR
472
472
  token.text = value + ' ' + token.text
473
473
  caretPosition = token.pos + value.length + 1
@@ -485,22 +485,36 @@ export default defineComponent({
485
485
  // if there are dots in left side expression...
486
486
  // looks like a bug in findSuggestions TODO find it - for now work around it here
487
487
  const leftover = tokenRightText.match(/^\S+/)?.[0] || ''
488
- token.text = tokenLeftText + leftover + ' ' + value + ' ' +
488
+ token.text =
489
+ tokenLeftText +
490
+ leftover +
491
+ ' ' +
492
+ value +
493
+ ' ' +
489
494
  tokenRightText.substring(leftover.length).trimStart()
490
- caretPosition = token.pos + tokenLeftText.length +
491
- leftover.length + 1 + value.length + 1
495
+ caretPosition =
496
+ token.pos +
497
+ tokenLeftText.length +
498
+ leftover.length +
499
+ 1 +
500
+ value.length +
501
+ 1
492
502
  } else {
493
503
  // this| situation: replace whatever is there on the left side with the value
494
504
  // this|situation: replace whatever is there on both sides with the value
495
- const newValue = token.type === TokenType.COMMA ? ', ' + value : value
505
+ const newValue =
506
+ token.type === TokenType.COMMA ? ', ' + value : value
496
507
  token.text = newValue
497
508
  caretPosition = token.pos + newValue.length
498
- if (tokens[leftTokenIndex + 1]?.type !== TokenType.WHITESPACE) {
509
+ if (
510
+ tokens[leftTokenIndex + 1]?.type !==
511
+ TokenType.WHITESPACE
512
+ ) {
499
513
  token.text += ' '
500
514
  caretPosition += 1
501
515
  }
502
516
  }
503
- stringValue = tokens.map(token => token.text).join('')
517
+ stringValue = tokens.map((token) => token.text).join('')
504
518
  }
505
519
 
506
520
  setInputValue(stringValue)
@@ -733,11 +747,7 @@ export default defineComponent({
733
747
  selection.deleteFromDocument()
734
748
  selection
735
749
  .getRangeAt(0)
736
- .insertNode(
737
- document.createTextNode(
738
- text
739
- )
740
- )
750
+ .insertNode(document.createTextNode(text))
741
751
  selection.collapseToEnd()
742
752
 
743
753
  e.preventDefault()
@@ -321,6 +321,21 @@ export default defineComponent({
321
321
  type: String,
322
322
  default: 'Cannot unselect child when parent is selected'
323
323
  },
324
+ /**
325
+ * Enforce restrictions that prevent parents from being dragged to child levels
326
+ * and children from being dragged to parent levels
327
+ */
328
+ enforceParentChildRestrictions: {
329
+ type: Boolean,
330
+ default: true
331
+ },
332
+ /**
333
+ * Enforce restrictions that prevent children from being dragged between different parents
334
+ */
335
+ enforceSameParentRestrictions: {
336
+ type: Boolean,
337
+ default: true
338
+ },
324
339
  ...useTableActionsProps,
325
340
  ...commonVirtScrollProps,
326
341
  ...useTableRowExpandProps,
@@ -773,13 +788,20 @@ export default defineComponent({
773
788
  draggedRow: draggedRow.value,
774
789
  targetRow: targetRow.value
775
790
  })
776
- emit(
777
- 'row-reorder',
778
- moveNestedRow(tableRows.value, event, sortingMovement.value)
791
+ const isDragValid = checkParentCondition(
792
+ draggedRow.value,
793
+ targetRow.value
779
794
  )
795
+ if (isDragValid) {
796
+ emit(
797
+ 'row-reorder',
798
+ moveNestedRow(tableRows.value, event, sortingMovement.value)
799
+ )
800
+ } else {
801
+ mainTableKey.value = v4()
802
+ }
780
803
  draggedRow.value = null
781
804
  targetRow.value = null
782
- mainTableKey.value = v4()
783
805
  }
784
806
 
785
807
  const handleChangeEvent = (event: any) => {
@@ -790,10 +812,30 @@ export default defineComponent({
790
812
  ) as HTMLElement
791
813
  if (passedElement) {
792
814
  const targetRowId = passedElement.dataset.id
793
- targetRow.value =
794
- tableRows.value.find(
795
- (row) => getRowKey.value(row) === targetRowId
796
- ) || null
815
+ const targetLevel = passedElement.getAttribute('data-level')
816
+
817
+ if (!targetRowId) {
818
+ return
819
+ }
820
+
821
+ let foundRow = tableRows.value.find(
822
+ (row: DlTableRow) => row.id === targetRowId
823
+ )
824
+ if (!foundRow) {
825
+ foundRow = findRowInNestedStructure(targetRowId, props.rows)
826
+ }
827
+ if (!foundRow) {
828
+ console.warn(
829
+ `Row with ID ${targetRowId} not found in data structure`
830
+ )
831
+ return
832
+ }
833
+
834
+ targetRow.value = foundRow
835
+ if (targetLevel) {
836
+ targetRow.value.level = parseInt(targetLevel)
837
+ }
838
+
797
839
  emit('row-drag-over', {
798
840
  draggedRow: draggedRow.value,
799
841
  targetRow: targetRow.value
@@ -812,12 +854,141 @@ export default defineComponent({
812
854
  const handleStartEvent = (event: any) => {
813
855
  prevMouseY = event.originalEvent.clientY
814
856
  const rowIndex = event.oldIndex
815
- if (rowIndex !== undefined && rowIndex >= 0) {
857
+ const draggedElement = event.item
858
+ if (!draggedElement) {
859
+ return
860
+ }
861
+
862
+ const draggedLevel = draggedElement.getAttribute('data-level')
863
+ let draggedId = draggedElement.getAttribute('data-id')
864
+
865
+ if (!draggedId && draggedElement.tagName === 'TBODY') {
866
+ const firstTr = draggedElement.querySelector('tr')
867
+ if (firstTr) {
868
+ draggedId = firstTr.getAttribute('data-id')
869
+ }
870
+ }
871
+
872
+ if (draggedId) {
873
+ let foundRow = tableRows.value.find(
874
+ (row: DlTableRow) => row.id === draggedId
875
+ )
876
+ if (!foundRow) {
877
+ foundRow = findRowInNestedStructure(draggedId, props.rows)
878
+ }
879
+ if (!foundRow) {
880
+ console.warn(
881
+ `Dragged row with ID ${draggedId} not found in data structure`
882
+ )
883
+ return
884
+ }
885
+
886
+ draggedRow.value = foundRow
887
+ if (draggedLevel) {
888
+ draggedRow.value.level = parseInt(draggedLevel)
889
+ }
890
+ } else if (rowIndex !== undefined && rowIndex >= 0) {
816
891
  draggedRow.value = tableRows.value[rowIndex] || null
817
- emit('row-drag-start', {
818
- draggedRow: draggedRow.value
819
- })
820
892
  }
893
+ emit('row-drag-start', {
894
+ draggedRow: draggedRow.value,
895
+ targetRow: targetRow.value
896
+ })
897
+ }
898
+
899
+ const checkParentCondition = (
900
+ draggedRow: DlTableRow,
901
+ targetRow: DlTableRow
902
+ ): boolean => {
903
+ if (!draggedRow || !targetRow) {
904
+ return false
905
+ }
906
+
907
+ const originalRows = props.rows
908
+ const draggedIsTopLevel = originalRows.some(
909
+ (row: DlTableRow) => row.id === draggedRow.id
910
+ )
911
+ const targetIsTopLevel = originalRows.some(
912
+ (row: DlTableRow) => row.id === targetRow.id
913
+ )
914
+ if (
915
+ props.enforceParentChildRestrictions &&
916
+ draggedIsTopLevel !== targetIsTopLevel
917
+ ) {
918
+ return false
919
+ }
920
+ if (!draggedIsTopLevel && props.enforceSameParentRestrictions) {
921
+ const draggedParent = findParentForChild(
922
+ draggedRow.id,
923
+ originalRows
924
+ )
925
+ const targetParent = findParentForChild(
926
+ targetRow.id,
927
+ originalRows
928
+ )
929
+ if (draggedParent !== targetParent) {
930
+ return false
931
+ }
932
+ }
933
+ return true
934
+ }
935
+
936
+ const buildParentMap = (rows: DlTableRow[]): Map<string, string> => {
937
+ const parentMap = new Map<string, string>()
938
+ const traverse = (rowList: DlTableRow[]) => {
939
+ for (const row of rowList) {
940
+ if (row.children) {
941
+ for (const child of row.children) {
942
+ parentMap.set(child.id, row.id)
943
+ }
944
+ traverse(row.children)
945
+ }
946
+ }
947
+ }
948
+ traverse(rows)
949
+ return parentMap
950
+ }
951
+
952
+ const findParentForChild = (
953
+ childId: string,
954
+ rows: DlTableRow[]
955
+ ): string | null => {
956
+ const parentMap = buildParentMap(rows)
957
+ return parentMap.get(childId) || null
958
+ }
959
+
960
+ const calculateRowLevel = (row: DlTableRow): number => {
961
+ const parentMap = buildParentMap(props.rows)
962
+ let level = 1
963
+ let currentId = row.id
964
+ while (parentMap.has(currentId)) {
965
+ level++
966
+ currentId = parentMap.get(currentId)!
967
+ }
968
+ return level
969
+ }
970
+
971
+ const findRowInNestedStructure = (
972
+ rowId: string,
973
+ rows: DlTableRow[]
974
+ ): DlTableRow | null => {
975
+ const searchRecursively = (
976
+ rowList: DlTableRow[]
977
+ ): DlTableRow | null => {
978
+ for (const row of rowList) {
979
+ if (row.id === rowId) {
980
+ return row
981
+ }
982
+ if (row.children && row.children.length > 0) {
983
+ const found = searchRecursively(row.children)
984
+ if (found) {
985
+ return found
986
+ }
987
+ }
988
+ }
989
+ return null
990
+ }
991
+ return searchRecursively(rows)
821
992
  }
822
993
 
823
994
  const updateColumns = (newColumns: DlTableColumn[]) => {
@@ -851,11 +1022,12 @@ export default defineComponent({
851
1022
  const [renderRow] = rowBodySlot
852
1023
  ? rowBodySlot({ row })
853
1024
  : [renderTr(row, i)]
1025
+ const actualLevel = calculateRowLevel(row)
854
1026
  return renderComponent(
855
1027
  vue2h.value,
856
1028
  'tbody',
857
1029
  {
858
- 'data-level': 1,
1030
+ 'data-level': actualLevel,
859
1031
  key: getRowKey.value(row) + i,
860
1032
  class: 'nested-tbody'
861
1033
  },
@@ -75,10 +75,7 @@ import {
75
75
  refocusTargetFn,
76
76
  conditionalHandler
77
77
  } from './utils'
78
- import {
79
- addEvt,
80
- isMobileOrTablet
81
- } from '../../../utils'
78
+ import { addEvt, isMobileOrTablet } from '../../../utils'
82
79
  import { v4 } from 'uuid'
83
80
  import {
84
81
  arrowNavigationEvents,
@@ -223,12 +220,12 @@ export default defineComponent({
223
220
  const { anchorEl, canShow, anchorEvents } = useAnchor(
224
221
  props.hoverGroup && !isMobile.value
225
222
  ? {
226
- configureAnchorEl
227
- }
223
+ configureAnchorEl
224
+ }
228
225
  : {
229
- toggleKey: toggleKey.value,
230
- ignoreEvents: ignoreEvents.value
231
- }
226
+ toggleKey: toggleKey.value,
227
+ ignoreEvents: ignoreEvents.value
228
+ }
232
229
  )
233
230
 
234
231
  Object.assign(anchorEvents, { delayShow })
@@ -517,7 +514,8 @@ export default defineComponent({
517
514
  }
518
515
 
519
516
  if (props.hoverGroup) {
520
- hoverGroupHiders[props.hoverGroup] = hoverGroupHiders[props.hoverGroup] ?? []
517
+ hoverGroupHiders[props.hoverGroup] =
518
+ hoverGroupHiders[props.hoverGroup] ?? []
521
519
  hoverGroupHiders[props.hoverGroup].push(delayHide)
522
520
  }
523
521
 
@@ -89,11 +89,7 @@
89
89
  </dl-button>
90
90
 
91
91
  <dl-button label="Auto-opening Submenus">
92
- <dl-menu
93
- auto-close
94
- anchor="top end"
95
- self="top start"
96
- >
92
+ <dl-menu auto-close anchor="top end" self="top start">
97
93
  <dl-list bordered>
98
94
  <dl-list-item
99
95
  v-for="i in 3"