@dataloop-ai/components 0.16.45 → 0.16.47

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 (145) hide show
  1. package/.eslintrc.js +2 -2
  2. package/package.json +10 -9
  3. package/src/App.vue +120 -58
  4. package/src/assets/globals.scss +2 -0
  5. package/src/components/basic/DlAlert/DlAlert.vue +1 -1
  6. package/src/components/basic/DlButton/DlButton.vue +13 -13
  7. package/src/components/basic/DlCard/DlCard.vue +234 -0
  8. package/src/components/basic/DlCard/index.ts +3 -0
  9. package/src/components/basic/DlCard/types.ts +20 -0
  10. package/src/components/basic/DlChip/DlChip.vue +1 -0
  11. package/src/components/basic/DlEllipsis/DlEllipsis.vue +90 -0
  12. package/src/components/basic/DlEllipsis/index.ts +2 -0
  13. package/src/components/basic/DlListItem/DlListItem.vue +11 -5
  14. package/src/components/basic/index.ts +2 -0
  15. package/src/components/compound/DlCharts/charts/DlBarChart/DlBarChart.vue +8 -1
  16. package/src/components/compound/DlCharts/charts/DlColumnChart/DlColumnChart.vue +22 -6
  17. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/DlConfusionMatrix.vue +542 -0
  18. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/index.ts +2 -0
  19. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/utils.ts +96 -0
  20. package/src/components/compound/DlCharts/charts/DlDoughnutChart/DlDoughnutChart.vue +2 -2
  21. package/src/components/compound/DlCharts/charts/DlLineChart/DlLineChart.vue +22 -6
  22. package/src/components/compound/DlCharts/charts/index.ts +1 -0
  23. package/src/components/compound/DlCharts/components/DlBrush.vue +8 -1
  24. package/src/components/compound/DlCharts/components/DlChartScrollBar.vue +34 -21
  25. package/src/components/compound/DlCharts/types/DlConfusionMatrix.types.ts +19 -0
  26. package/src/components/compound/DlCharts/types/index.ts +2 -1
  27. package/src/components/compound/DlCharts/types/props.ts +14 -0
  28. package/src/components/compound/DlDialogBox/DlDialogBox.vue +1 -1
  29. package/src/components/compound/DlDialogBox/components/DlDialogBoxFooter.vue +1 -0
  30. package/src/components/compound/DlDropdownButton/DlDropdownButton.vue +58 -12
  31. package/src/components/compound/DlInput/DlInput.vue +45 -23
  32. package/src/components/compound/DlJsonEditor/DlJsonEditor.vue +13 -29
  33. package/src/components/compound/DlPagination/DlPagination.vue +14 -4
  34. package/src/components/compound/DlPagination/components/PageNavigation.vue +24 -25
  35. package/src/components/compound/DlPagination/components/PaginationLegend.vue +2 -1
  36. package/src/components/compound/DlPagination/components/QuickNavigation.vue +1 -0
  37. package/src/components/compound/DlSearches/DlSmartSearch/DlSmartSearch.vue +86 -49
  38. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchInput.vue +86 -69
  39. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSuggestionsDropdown.vue +43 -4
  40. package/src/components/compound/DlSearches/DlSmartSearch/utils/highlightSyntax.ts +1 -55
  41. package/src/components/compound/DlSearches/DlSmartSearch/utils/index.ts +42 -10
  42. package/src/components/compound/DlSearches/DlSmartSearch/utils/utils.ts +107 -0
  43. package/src/components/compound/DlSelect/DlSelect.vue +41 -8
  44. package/src/components/compound/DlTable/DlTable.vue +13 -10
  45. package/src/components/compound/DlTable/styles/dl-table-styles.scss +16 -4
  46. package/src/components/compound/DlToggleButton/DlToggleButton.vue +109 -0
  47. package/src/components/compound/DlToggleButton/config.ts +27 -0
  48. package/src/components/compound/DlToggleButton/index.ts +3 -0
  49. package/src/components/compound/DlToggleButton/types.ts +4 -0
  50. package/src/components/compound/index.ts +1 -0
  51. package/src/components/compound/types.ts +1 -0
  52. package/src/components/essential/DlColorPicker/DlColorPicker.vue +4 -1
  53. package/src/components/essential/DlColorPicker/components/DlColors.vue +2 -6
  54. package/src/components/essential/DlIcon/DlIcon.vue +5 -1
  55. package/src/components/essential/DlMenu/DlMenu.vue +30 -2
  56. package/src/components/essential/DlSeparator/DlSeparator.vue +66 -0
  57. package/src/components/essential/DlSeparator/index.ts +2 -0
  58. package/src/components/essential/DlSpinner/DlSpinner.vue +53 -217
  59. package/src/components/essential/DlSpinner/components/DlSpinnerCircle.vue +156 -0
  60. package/src/components/essential/DlSpinner/components/DlSpinnerClock.vue +191 -0
  61. package/src/components/essential/DlSpinner/components/DlSpinnerDots.vue +225 -0
  62. package/src/components/essential/DlSpinner/components/DlSpinnerGrid.vue +278 -0
  63. package/src/components/essential/DlSpinner/components/DlSpinnerLogo.vue +264 -0
  64. package/src/components/essential/DlSpinner/index.ts +14 -1
  65. package/src/components/essential/DlSpinner/types.ts +7 -0
  66. package/src/components/essential/index.ts +1 -0
  67. package/src/components/essential/types.ts +1 -0
  68. package/src/components/shared/DlItemSection/DlItemSection.vue +21 -15
  69. package/src/components/shared/DlVirtualScroll/DlVirtualScroll.vue +36 -21
  70. package/src/components/shared/DlVirtualScroll/useVirtualScroll.ts +8 -10
  71. package/src/{demo → demos}/DlButtonDemo.vue +15 -0
  72. package/src/demos/DlCardDemo.vue +47 -0
  73. package/src/{demo → demos}/DlColorPickerDemo.vue +16 -1
  74. package/src/demos/DlConfusionMatrixDemo.vue +53 -0
  75. package/src/{demo → demos}/DlDialogBoxDemo.vue +4 -1
  76. package/src/demos/DlDropdownButtonDemo.vue +386 -0
  77. package/src/demos/DlEllipsisDemo.vue +30 -0
  78. package/src/{demo → demos}/DlLineChartDemo.vue +8 -8
  79. package/src/{demo → demos}/DlMenuDemo.vue +61 -2
  80. package/src/{demo → demos}/DlSearchDemo.vue +3 -2
  81. package/src/demos/DlSeparatorDemo.vue +44 -0
  82. package/src/demos/DlSpinnerDemo.vue +59 -0
  83. package/src/{demo → demos}/DlTableDemo.vue +117 -29
  84. package/src/demos/DlToggleButtonDemo.vue +55 -0
  85. package/src/{demo → demos}/DlTooltipDemo.vue +43 -2
  86. package/src/{demo → demos}/DlWidgetDemo.vue +34 -19
  87. package/src/{demo → demos}/SmartSearchDemo/DlSmartSearchDemo.vue +2 -50
  88. package/src/{demo → demos}/index.ts +14 -56
  89. package/src/hooks/use-arrow-navigation.ts +58 -0
  90. package/src/hooks/use-suggestions.ts +97 -74
  91. package/src/utils/colors.ts +1 -1
  92. package/src/utils/draggable-table.ts +2 -2
  93. package/src/utils/index.ts +1 -0
  94. package/src/utils/parse-smart-query.ts +87 -0
  95. package/src/components/compound/DlCharts/types.ts +0 -1
  96. package/src/demo/DlDropdownButtonDemo.vue +0 -260
  97. package/src/demo/DlSpinnerDemo.vue +0 -20
  98. /package/src/{demo → demos}/BarChartDemo.vue +0 -0
  99. /package/src/{demo → demos}/ColumnChartDemo.vue +0 -0
  100. /package/src/{demo → demos}/DlAccordionDemo.vue +0 -0
  101. /package/src/{demo → demos}/DlAlertDemo.vue +0 -0
  102. /package/src/{demo → demos}/DlAvatarDemo.vue +0 -0
  103. /package/src/{demo → demos}/DlBadgeDemo.vue +0 -0
  104. /package/src/{demo → demos}/DlChartDoughnutDemo.vue +0 -0
  105. /package/src/{demo → demos}/DlCheckboxDemo.vue +0 -0
  106. /package/src/{demo → demos}/DlChipDemo.vue +0 -0
  107. /package/src/{demo → demos}/DlCounterDemo.vue +0 -0
  108. /package/src/{demo → demos}/DlDateTimeRangeDemo.vue +0 -0
  109. /package/src/{demo → demos}/DlIconDemo.vue +0 -0
  110. /package/src/{demo → demos}/DlInputDemo.vue +0 -0
  111. /package/src/{demo → demos}/DlKpiDemo.vue +0 -0
  112. /package/src/{demo → demos}/DlLinkDemo.vue +0 -0
  113. /package/src/{demo → demos}/DlListDemo.vue +0 -0
  114. /package/src/{demo → demos}/DlOptionGroupDemo.vue +0 -0
  115. /package/src/{demo → demos}/DlPaginationDemo.vue +0 -0
  116. /package/src/{demo → demos}/DlPanelContainerDemo.vue +0 -0
  117. /package/src/{demo → demos}/DlPopupDemo.vue +0 -0
  118. /package/src/{demo → demos}/DlProgressBarDemo.vue +0 -0
  119. /package/src/{demo → demos}/DlProgressChartDemo.vue +0 -0
  120. /package/src/{demo → demos}/DlRadioDemo.vue +0 -0
  121. /package/src/{demo → demos}/DlRangeDemo.vue +0 -0
  122. /package/src/{demo → demos}/DlSelectDemo.vue +0 -0
  123. /package/src/{demo → demos}/DlSkeletonDemo.vue +0 -0
  124. /package/src/{demo → demos}/DlSliderDemo.vue +0 -0
  125. /package/src/{demo → demos}/DlStepperDemo/CenteredStepperInDialogBox.vue +0 -0
  126. /package/src/{demo → demos}/DlStepperDemo/DlStepperDemo.vue +0 -0
  127. /package/src/{demo → demos}/DlStepperDemo/SimpleStepper.vue +0 -0
  128. /package/src/{demo → demos}/DlStepperDemo/StepperInDialogBox.vue +0 -0
  129. /package/src/{demo → demos}/DlStepperDemo/index.ts +0 -0
  130. /package/src/{demo → demos}/DlStepperDemo/steps/AssignmentsStep.vue +0 -0
  131. /package/src/{demo → demos}/DlStepperDemo/steps/DataStep.vue +0 -0
  132. /package/src/{demo → demos}/DlStepperDemo/steps/GeneralStep.vue +0 -0
  133. /package/src/{demo → demos}/DlStepperDemo/steps/InstructionStep.vue +0 -0
  134. /package/src/{demo → demos}/DlStepperDemo/steps/QualityStep.vue +0 -0
  135. /package/src/{demo → demos}/DlSwitchDemo.vue +0 -0
  136. /package/src/{demo → demos}/DlTabsDemo.vue +0 -0
  137. /package/src/{demo → demos}/DlTdDemo.vue +0 -0
  138. /package/src/{demo → demos}/DlTextAreaDemo.vue +0 -0
  139. /package/src/{demo → demos}/DlTextHolderDemo.vue +0 -0
  140. /package/src/{demo → demos}/DlThDemo.vue +0 -0
  141. /package/src/{demo → demos}/DlToastDemo.vue +0 -0
  142. /package/src/{demo → demos}/DlTrDemo.vue +0 -0
  143. /package/src/{demo → demos}/DlTrendDemo.vue +0 -0
  144. /package/src/{demo → demos}/DlTypographyDemo.vue +0 -0
  145. /package/src/{demo → demos}/SmartSearchDemo/schema.ts +0 -0
@@ -7,7 +7,7 @@
7
7
  <div :class="searchBarClasses">
8
8
  <div class="dl-smart-search-input__status-icon-wrapper">
9
9
  <dl-icon
10
- v-if="withSearchIcon || status"
10
+ v-if="withSearchIcon || (!focused && status)"
11
11
  :icon="statusIcon"
12
12
  :color="statusIconColor"
13
13
  size="18px"
@@ -65,7 +65,7 @@
65
65
  icon="icon-dl-save"
66
66
  size="16px"
67
67
  flat
68
- :disabled="disabled"
68
+ :disabled="saveStatus"
69
69
  @click="save"
70
70
  >
71
71
  <dl-tooltip> Save Query </dl-tooltip>
@@ -74,10 +74,10 @@
74
74
  icon="icon-dl-loop"
75
75
  size="16px"
76
76
  flat
77
+ transform="none"
77
78
  text-color="dl-color-darker"
78
- :disabled="disabled"
79
- uppercase
80
- label="dql"
79
+ :disabled="saveStatus"
80
+ label="switch to DQL"
81
81
  @click="edit"
82
82
  >
83
83
  <dl-tooltip> Switch to DQL </dl-tooltip>
@@ -86,7 +86,7 @@
86
86
  </div>
87
87
  </div>
88
88
  <label
89
- v-show="status.message"
89
+ v-if="status.message !== 'info'"
90
90
  ref="label"
91
91
  class="dl-smart-search-input__search-label"
92
92
  for="search-input"
@@ -117,7 +117,7 @@
117
117
  </div>
118
118
  </template>
119
119
  <script lang="ts">
120
- import { defineComponent, ref, PropType } from 'vue-demi'
120
+ import { defineComponent, ref, PropType, computed } from 'vue-demi'
121
121
  import { DlButton } from '../../../../basic'
122
122
  import { DlDatePicker } from '../../../DlDateTime'
123
123
  import { DlMenu, DlIcon } from '../../../../essential'
@@ -131,10 +131,10 @@ import { DateInterval } from '../../../DlDateTime/types'
131
131
  import {
132
132
  isEndingWithDateIntervalPattern,
133
133
  replaceDateInterval,
134
- isEligibleToChange,
135
134
  setCaret,
136
135
  updateEditor
137
136
  } from '../utils'
137
+ import { isEligibleToChange } from '../utils/utils'
138
138
 
139
139
  export default defineComponent({
140
140
  components: {
@@ -218,6 +218,10 @@ export default defineComponent({
218
218
  const styledTexarea = ref(null)
219
219
  const styledInput = ref(null)
220
220
 
221
+ const focused = ref(false)
222
+ const isOverflow = ref(false)
223
+ const isTyping = ref(false)
224
+
221
225
  const { hasEllipsis } = useSizeObserver(input)
222
226
 
223
227
  const suggestionModal = ref(false)
@@ -253,35 +257,16 @@ export default defineComponent({
253
257
  emit('update:modelValue', stringValue)
254
258
  }
255
259
 
256
- return {
257
- input,
258
- label,
259
- hasEllipsis,
260
- suggestionModal,
261
- setInputValue,
262
- menuOffset,
263
- cancelBlur,
264
- expanded,
265
- styledTexarea,
266
- styledInput,
267
- datePickerSelection,
268
- isDatePickerVisible
269
- }
270
- },
271
- data(): {
272
- focused: boolean
273
- isOverflow: boolean
274
- isTyping: boolean
275
- } {
276
- return {
277
- focused: false,
278
- isOverflow: false,
279
- isTyping: false
280
- }
281
- },
282
- computed: {
283
- statusIcon(): string {
284
- switch (this.status.type) {
260
+ const saveStatus = computed(() => {
261
+ return (
262
+ props.disabled ||
263
+ !props.modelValue ||
264
+ props.status?.type === 'error'
265
+ )
266
+ })
267
+
268
+ const statusIcon = computed(() => {
269
+ switch (props.status?.type) {
285
270
  case 'success':
286
271
  return 'icon-dl-approve-filled'
287
272
  case 'error':
@@ -291,9 +276,10 @@ export default defineComponent({
291
276
  default:
292
277
  return ''
293
278
  }
294
- },
295
- statusIconColor(): string {
296
- switch (this.status.type) {
279
+ })
280
+
281
+ const statusIconColor = computed(() => {
282
+ switch (props.status?.type) {
297
283
  case 'success':
298
284
  return 'dl-color-positive'
299
285
  case 'error':
@@ -303,58 +289,89 @@ export default defineComponent({
303
289
  default:
304
290
  return ''
305
291
  }
306
- },
307
- screenIcon(): string {
308
- return this.expanded
309
- ? 'icon-dl-fit-to-screen'
310
- : 'icon-dl-full-screen'
311
- },
312
- searchBarClasses(): string {
292
+ })
293
+
294
+ const screenIcon = computed(() => {
295
+ return expanded ? 'icon-dl-fit-to-screen' : 'icon-dl-full-screen'
296
+ })
297
+
298
+ const searchBarClasses = computed(() => {
313
299
  let classes = 'dl-smart-search-input__search-bar'
314
300
 
315
- if (this.status.type === 'error') {
316
- classes += ' dl-smart-search-input__search-bar--error'
317
- } else if (this.status.type === 'warning') {
318
- classes += ' dl-smart-search-input__search-bar--warning'
301
+ if (focused && props.status?.type === 'info') {
302
+ classes += ' dl-smart-search-input__search-bar--focused'
319
303
  } else {
320
- if (this.focused) {
321
- classes += ' dl-smart-search-input__search-bar--focused'
304
+ if (props.status?.type === 'error') {
305
+ classes += ' dl-smart-search-input__search-bar--error'
306
+ } else if (props.status?.type === 'warning') {
307
+ classes += ' dl-smart-search-input__search-bar--warning'
322
308
  }
323
309
  }
324
310
 
325
- if (this.expanded) {
311
+ if (expanded) {
326
312
  classes += ' dl-smart-search-input__search-bar--expanded'
327
313
  }
328
314
 
329
- if (this.disabled) {
315
+ if (props.disabled) {
330
316
  classes += ' dl-smart-search-input__search-bar--disabled'
331
317
  }
332
318
 
333
319
  return classes
334
- },
335
- labelStyles(): Record<string, any> {
320
+ })
321
+
322
+ const labelStyles = computed(() => {
336
323
  return {
337
- color: this.status.type === 'error' ? 'red' : 'gray'
324
+ color: props.status?.type === 'error' ? 'red' : 'gray'
338
325
  }
339
- },
340
- messageClasses(): string {
326
+ })
327
+
328
+ const messageClasses = computed(() => {
341
329
  let classes = 'dl-smart-search-input__message'
342
330
 
343
- if (this.status) {
344
- classes += ` dl-smart-search-input__message--${this.status}`
331
+ if (props.status) {
332
+ classes += ` dl-smart-search-input__message--${props.status}`
345
333
  }
346
334
 
347
335
  return classes
348
- },
349
- withClearBtn(): boolean {
350
- return this.modelValue.length > 0
351
- },
352
- cssVars(): Record<string, string> {
336
+ })
337
+
338
+ const withClearBtn = computed(() => {
339
+ return props.modelValue?.length > 0
340
+ })
341
+
342
+ const cssVars = computed(() => {
353
343
  return {
354
344
  '--dl-smart-search-bar-wrapper-height':
355
- this.expandedInputHeight,
356
- '--dl-smart-search-input-height': this.inputHeight
345
+ props.expandedInputHeight,
346
+ '--dl-smart-search-input-height': props.inputHeight
357
347
  }
348
+ })
349
+
350
+ return {
351
+ input,
352
+ label,
353
+ hasEllipsis,
354
+ suggestionModal,
355
+ setInputValue,
356
+ menuOffset,
357
+ cancelBlur,
358
+ expanded,
359
+ styledTexarea,
360
+ styledInput,
361
+ datePickerSelection,
362
+ isDatePickerVisible,
363
+ focused,
364
+ isOverflow,
365
+ isTyping,
366
+ saveStatus,
367
+ statusIcon,
368
+ statusIconColor,
369
+ screenIcon,
370
+ searchBarClasses,
371
+ labelStyles,
372
+ messageClasses,
373
+ withClearBtn,
374
+ cssVars
358
375
  }
359
376
  },
360
377
  watch: {
@@ -9,14 +9,20 @@
9
9
  :disabled="disabled"
10
10
  fit-container
11
11
  :model-value="modelValue"
12
- @update:modelValue="$emit('update:modelValue', $event)"
12
+ :arrow-nav-items="suggestions"
13
+ @update:modelValue="emitModelValue($event)"
14
+ @show="onShow"
15
+ @hide="onHide"
16
+ @highlightedIndex="setHighlightedIndex"
17
+ @handleSelectedItem="handleSelectedItem"
13
18
  >
14
19
  <dl-list>
15
20
  <dl-list-item
16
- v-for="item in suggestions"
21
+ v-for="(item, suggestionIndex) in suggestions"
17
22
  :key="item"
18
23
  :clickable="true"
19
- @click="$emit('set-input-value', item)"
24
+ :is-highlighted="suggestionIndex === highlightedIndex"
25
+ @click="handleOption(item)"
20
26
  >
21
27
  {{ item }}
22
28
  </dl-list-item>
@@ -25,7 +31,7 @@
25
31
  </div>
26
32
  </template>
27
33
  <script lang="ts">
28
- import { defineComponent, PropType } from 'vue-demi'
34
+ import { defineComponent, PropType, ref } from 'vue-demi'
29
35
  import { DlMenu, DlList } from '../../../../essential'
30
36
  import { DlListItem } from '../../../../basic'
31
37
 
@@ -62,6 +68,39 @@ export default defineComponent({
62
68
  }
63
69
  },
64
70
  emits: ['set-input-value', 'update:modelValue'],
71
+ setup(props, { emit }) {
72
+ const isMenuOpen = ref(false)
73
+ const highlightedIndex = ref(-1)
74
+ const onShow = (value: any) => {
75
+ isMenuOpen.value = !!value
76
+ }
77
+ const onHide = (value: any) => {
78
+ isMenuOpen.value = !value
79
+ }
80
+
81
+ const setHighlightedIndex = (value: any) => {
82
+ highlightedIndex.value = value
83
+ }
84
+ const handleSelectedItem = (value: any) => {
85
+ handleOption(value)
86
+ }
87
+ const emitModelValue = (event: any) => {
88
+ emit('update:modelValue', event)
89
+ }
90
+ const handleOption = (item: any) => {
91
+ emit('set-input-value', item)
92
+ }
93
+
94
+ return {
95
+ setHighlightedIndex,
96
+ handleSelectedItem,
97
+ highlightedIndex,
98
+ onShow,
99
+ onHide,
100
+ emitModelValue,
101
+ handleOption
102
+ }
103
+ },
65
104
  computed: {
66
105
  defaultTarget() {
67
106
  return '.dl-smart-search-input__textarea'
@@ -1,5 +1,4 @@
1
- import { operators, Alias } from '../../../../../hooks/use-suggestions'
2
- import { ColorSchema, SyntaxColorSchema } from '../types'
1
+ import { SyntaxColorSchema } from '../types'
3
2
 
4
3
  let editor = document.getElementById('editor')
5
4
  let styleModel: SyntaxColorSchema
@@ -112,56 +111,3 @@ export function setCaret(target: HTMLElement) {
112
111
  sel.addRange(range)
113
112
  target.focus()
114
113
  }
115
-
116
- export const isEligibleToChange = (target: HTMLElement, expanded: boolean) => {
117
- let childOffsetRight = 0
118
- let childOffsetBottom = 20
119
-
120
- if (target?.lastChild) {
121
- const range = document.createRange()
122
- range.selectNode(target?.lastChild)
123
- childOffsetRight =
124
- range.getBoundingClientRect().right -
125
- target.getBoundingClientRect().left
126
- childOffsetBottom =
127
- range.getBoundingClientRect().bottom -
128
- target.getBoundingClientRect().top +
129
- 5
130
- }
131
-
132
- if (childOffsetRight <= target.clientWidth) {
133
- return [-childOffsetRight, 5]
134
- } else {
135
- return [-target.clientWidth, 5]
136
- }
137
- }
138
-
139
- export function createColorSchema(
140
- colorSchema: ColorSchema,
141
- aliases: Alias[]
142
- ): SyntaxColorSchema {
143
- const thisFields = []
144
- for (const key in aliases) {
145
- thisFields.push(aliases[key].alias)
146
- }
147
-
148
- const thisOperators = []
149
- for (const key in operators) {
150
- thisOperators.push(operators[key])
151
- }
152
-
153
- return {
154
- fields: {
155
- values: thisFields,
156
- color: colorSchema.fields
157
- },
158
- operators: {
159
- values: thisOperators,
160
- color: colorSchema.operators
161
- },
162
- keywords: {
163
- values: ['OR', 'AND'],
164
- color: colorSchema.keywords
165
- }
166
- }
167
- }
@@ -1,8 +1,21 @@
1
1
  export * from './highlightSyntax'
2
+ export * from './utils'
2
3
 
3
- import { dateIntervalPattern } from '../../../../../hooks/use-suggestions'
4
4
  import { DateInterval } from '../../../DlDateTime/types'
5
5
 
6
+ const startDatePattern = new RegExp(
7
+ /\(from\s?\d{2}\/\d{2}\/\d{4}\s?\)|\(from\s?dd\/mm\/yyyy\s?\)/,
8
+ 'gi'
9
+ )
10
+ const endDatePattern = new RegExp(
11
+ /\(to\s?\d{2}\/\d{2}\/\d{4}\s?\)|\(to\s?dd\/mm\/yyyy\s?\)/,
12
+ 'gi'
13
+ )
14
+ const dateIntervalPattern = new RegExp(
15
+ /\((from\s?\(\d{2}\/\d{2}\/\d{4}\)\s?to\s?\(\d{2}\/\d{2}\/\d{4}\))\)|\((from\s?\(dd\/mm\/yyyy\)\s?to\s?\(dd\/mm\/yyyy\))\)/,
16
+ 'gi'
17
+ )
18
+
6
19
  export const isEndOfString = (str: string, pattern: RegExp): boolean => {
7
20
  const trimmed = str.trim()
8
21
  const matches = trimmed.match(pattern)
@@ -13,8 +26,13 @@ export const isEndOfString = (str: string, pattern: RegExp): boolean => {
13
26
  return trimmed.lastIndexOf(lastMatch) + lastMatch.length === trimmed.length
14
27
  }
15
28
 
16
- export const isEndingWithDateIntervalPattern = (str: string) =>
17
- isEndOfString(str, dateIntervalPattern)
29
+ export const isEndingWithDateIntervalPattern = (str: string) => {
30
+ return (
31
+ isEndOfString(str, dateIntervalPattern) ||
32
+ isEndOfString(str, startDatePattern) ||
33
+ isEndOfString(str, endDatePattern)
34
+ )
35
+ }
18
36
 
19
37
  export const replaceDateInterval = (
20
38
  str: string,
@@ -22,24 +40,38 @@ export const replaceDateInterval = (
22
40
  ) => {
23
41
  const dateFrom = new Date(dateInterval.from)
24
42
  const dateTo = new Date(dateInterval.to)
43
+ const values = str.match(/\((.*?)\)/g)
44
+ let newStr = ''
45
+ if (!values) return str
25
46
 
26
- const newStr = `(From ${formatDate(dateFrom)} To ${formatDate(dateTo)})`
27
-
28
- return replaceLastOccurrence(str, newStr)
47
+ if (values.length > 1) {
48
+ newStr = `(From (${formatDate(dateFrom)}) To (${formatDate(dateTo)}))`
49
+ return replaceLastOccurrence(str, newStr, dateIntervalPattern)
50
+ } else if (values[0].includes('From')) {
51
+ newStr = `(From ${formatDate(dateFrom)})`
52
+ return replaceLastOccurrence(str, newStr, startDatePattern)
53
+ } else if (values[0].includes('To')) {
54
+ newStr = `(To ${formatDate(dateTo)})`
55
+ return replaceLastOccurrence(str, newStr, endDatePattern)
56
+ }
29
57
  }
30
58
 
31
59
  const formatDate = (date: Date): string => {
32
- return `(${addZero(date.getDate())}/${addZero(
60
+ return `${addZero(date.getDate())}/${addZero(
33
61
  date.getMonth() + 1
34
- )}/${date.getFullYear()})`
62
+ )}/${date.getFullYear()}`
35
63
  }
36
64
 
37
65
  const addZero = (value: number): string => {
38
66
  return value < 10 ? `0${value}` : value.toString()
39
67
  }
40
68
 
41
- const replaceLastOccurrence = (string: string, replaceValue: string) => {
42
- const matches = string.match(dateIntervalPattern)
69
+ const replaceLastOccurrence = (
70
+ string: string,
71
+ replaceValue: string,
72
+ pattern: RegExp
73
+ ) => {
74
+ const matches = string.match(pattern)
43
75
 
44
76
  return matches && matches.length
45
77
  ? string.replace(matches[matches.length - 1], replaceValue)
@@ -0,0 +1,107 @@
1
+ import { ColorSchema, SyntaxColorSchema } from '../types'
2
+ import {
3
+ operators,
4
+ Alias,
5
+ startDatePattern,
6
+ endDatePattern,
7
+ dateIntervalPattern
8
+ } from '../../../../../hooks/use-suggestions'
9
+
10
+ export function replaceWithJsDates(str: string) {
11
+ const intervals = str.match(dateIntervalPattern)
12
+ const starts = str.match(startDatePattern)
13
+ const ends = str.match(endDatePattern)
14
+
15
+ intervals?.forEach((interval) => {
16
+ str = str.replaceAll(interval, formatToDateObj(interval))
17
+ })
18
+ starts?.forEach((start) => {
19
+ str = str.replaceAll(start, formatToDateObj(start))
20
+ })
21
+ ends?.forEach((end) => {
22
+ str = str.replaceAll(end, formatToDateObj(end))
23
+ })
24
+ return str
25
+ }
26
+
27
+ function formatToDateObj(str: string) {
28
+ const [day, month, year] = str.split(' ')[1].split('/')
29
+ const date = new Date(parseInt(year), parseInt(month), parseInt(day))
30
+ if (!isValidDate(date)) return str
31
+ const [toDay, toMonth, toYear] = str.split(' ')[3]?.split('/') || []
32
+ const toDate = new Date(
33
+ parseInt(toYear),
34
+ parseInt(toMonth),
35
+ parseInt(toDay)
36
+ )
37
+ if (!isValidDate(toDate)) return date.toISOString()
38
+ return JSON.stringify({
39
+ from: date.toISOString(),
40
+ to: toDate.toISOString()
41
+ })
42
+ }
43
+
44
+ function isValidDate(d: Date) {
45
+ return d instanceof Date && !isNaN(d as any)
46
+ }
47
+
48
+ export function replaceAliases(json: string, aliases: Alias[]) {
49
+ let newJson = json
50
+ aliases.forEach((alias) => {
51
+ newJson = newJson.replaceAll(alias.alias, alias.key)
52
+ })
53
+ return newJson
54
+ }
55
+
56
+ export function createColorSchema(
57
+ colorSchema: ColorSchema,
58
+ aliases: Alias[]
59
+ ): SyntaxColorSchema {
60
+ const thisFields = []
61
+ for (const key in aliases) {
62
+ thisFields.push(aliases[key].alias)
63
+ }
64
+
65
+ const thisOperators = []
66
+ for (const key in operators) {
67
+ thisOperators.push(operators[key])
68
+ }
69
+
70
+ return {
71
+ fields: {
72
+ values: thisFields,
73
+ color: colorSchema.fields
74
+ },
75
+ operators: {
76
+ values: thisOperators,
77
+ color: colorSchema.operators
78
+ },
79
+ keywords: {
80
+ values: ['OR', 'AND'],
81
+ color: colorSchema.keywords
82
+ }
83
+ }
84
+ }
85
+
86
+ export const isEligibleToChange = (target: HTMLElement, expanded: boolean) => {
87
+ let childOffsetRight = 0
88
+ let childOffsetBottom = 20
89
+
90
+ if (target?.lastChild) {
91
+ const range = document.createRange()
92
+ range.selectNode(target?.lastChild)
93
+ childOffsetRight =
94
+ range.getBoundingClientRect().right -
95
+ target.getBoundingClientRect().left
96
+ childOffsetBottom =
97
+ range.getBoundingClientRect().bottom -
98
+ target.getBoundingClientRect().top +
99
+ 5
100
+ }
101
+
102
+ if (childOffsetRight <= target.clientWidth) {
103
+ return [-childOffsetRight, 5]
104
+ } else {
105
+ return [-target.clientWidth, 5]
106
+ }
107
+ }
@@ -46,6 +46,7 @@
46
46
  </div>
47
47
  <div
48
48
  class="select-wrapper"
49
+ tabindex="0"
49
50
  :style="placeholderStyles"
50
51
  >
51
52
  <div
@@ -142,8 +143,11 @@
142
143
  :offset="[0, 3]"
143
144
  style="border-radius: 0"
144
145
  :disabled="disabled || readonly"
146
+ :arrow-nav-items="options"
145
147
  @show="onMenuOpen"
146
148
  @hide="closeMenu"
149
+ @highlightedIndex="setHighlightedIndex"
150
+ @handleSelectedItem="handleSelectedItem"
147
151
  >
148
152
  <dl-list
149
153
  class="select-list"
@@ -183,7 +187,7 @@
183
187
  </template>
184
188
  </dl-select-option>
185
189
  <dl-select-option
186
- v-for="option in options"
190
+ v-for="(option, optionIndex) in options"
187
191
  :key="getKeyForOption(option)"
188
192
  clickable
189
193
  :multiselect="multiselect"
@@ -191,6 +195,11 @@
191
195
  selected:
192
196
  option === selectedOption && highlightSelected
193
197
  }"
198
+ :style="
199
+ optionIndex === highlightedIndex
200
+ ? 'background-color: var(--dl-color-fill)'
201
+ : ''
202
+ "
194
203
  :with-wave="withWave"
195
204
  :model-value="modelValue"
196
205
  :value="getOptionValue(option)"
@@ -251,7 +260,7 @@ import { InputSizes, TInputSizes } from '../../../utils/input-sizes'
251
260
  import { DlListItem } from '../../basic'
252
261
  import { DlTooltip, DlList, DlIcon, DlMenu } from '../../essential'
253
262
  import { DlInfoErrorMessage, DlItemSection } from '../../shared'
254
- import { defineComponent, isVue2, PropType } from 'vue-demi'
263
+ import { defineComponent, isVue2, PropType, ref } from 'vue-demi'
255
264
  import {
256
265
  getLabel,
257
266
  getIconSize,
@@ -337,11 +346,39 @@ export default defineComponent({
337
346
  'selected',
338
347
  'deselected'
339
348
  ],
349
+ setup(props, { emit }) {
350
+ const isExpanded = ref(false)
351
+ const selectedIndex = ref(-1)
352
+ const highlightedIndex = ref(-1)
353
+
354
+ const setHighlightedIndex = (value: any) => {
355
+ highlightedIndex.value = value
356
+ }
357
+ const handleModelValueUpdate = (val: any) => {
358
+ emit('update:model-value', val)
359
+ emit('change', val)
360
+ }
361
+ const handleSelectedItem = (value: any) => {
362
+ selectedIndex.value = props.options.findIndex(
363
+ (option: string | Record<string, string | number> | number) =>
364
+ isEqual(option as any, value)
365
+ )
366
+
367
+ handleModelValueUpdate(value)
368
+ }
369
+
370
+ return {
371
+ isExpanded,
372
+ highlightedIndex,
373
+ selectedIndex,
374
+ setHighlightedIndex,
375
+ handleSelectedItem,
376
+ handleModelValueUpdate
377
+ }
378
+ },
340
379
  data() {
341
380
  return {
342
381
  uuid: `dl-select-${v4()}`,
343
- isExpanded: false,
344
- selectedIndex: -1,
345
382
  isEmpty: true
346
383
  }
347
384
  },
@@ -666,10 +703,6 @@ export default defineComponent({
666
703
  this.selectedIndex = -1
667
704
  this.closeMenu()
668
705
  },
669
- handleModelValueUpdate(val: any) {
670
- this.$emit('update:model-value', val)
671
- this.$emit('change', val)
672
- },
673
706
  selectOption(selected: any) {
674
707
  if (this.multiselect) {
675
708
  return