@dataloop-ai/components 0.20.26 → 0.20.28

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.26",
3
+ "version": "0.20.28",
4
4
  "exports": {
5
5
  ".": "./index.ts",
6
6
  "./models": "./models.ts",
@@ -445,8 +445,15 @@ export default defineComponent({
445
445
  queryRightSide = queryRightSide.trimStart()
446
446
  } else {
447
447
  // this|situation: replace whatever is there on both sides with the value
448
- if (/^[^']+('[^']?'[^']+)?'[^']+'?$/.test(queryLeftSide)) {
449
- queryLeftSide = queryLeftSide.replace(/'[^']+'?$/, '')
448
+ if (
449
+ /^[^']+((?<!\\)'.*(?<!\\)'[^']+)*(?<!\\)'([^']+\\')*[^']*((?<!\\)')?$/.test(
450
+ queryLeftSide
451
+ )
452
+ ) {
453
+ queryLeftSide = queryLeftSide.replace(
454
+ /(?<!\\)'([^']+\\')*[^']*((?<!\\)')?$/,
455
+ ''
456
+ )
450
457
  } else {
451
458
  queryLeftSide = queryLeftSide.replace(/[^'\s]+$/, '')
452
459
  }
@@ -159,7 +159,7 @@ export default defineComponent({
159
159
  const removeQuotes = (item: any) => {
160
160
  const str = '' + item
161
161
  const match = str.match(/^'(.*)'$/)
162
- return match ? match[1] : str
162
+ return match ? match[1].replace(/\\'/g, "'") : str
163
163
  }
164
164
 
165
165
  const updatePosition = () => {
@@ -82,37 +82,27 @@
82
82
  name="selected"
83
83
  >
84
84
  <span class="root-container--placeholder">
85
- <dl-ellipsis>
86
- {{ filterSelectLabel }}
87
- </dl-ellipsis>
85
+ <dl-ellipsis :text="filterSelectLabel" />
88
86
  </span>
89
87
  </slot>
90
88
  </div>
91
89
  <template v-else>
92
90
  <span
93
- v-show="
94
- (multiselect && !searchable) ||
95
- (multiselect && searchable && !isExpanded)
96
- "
91
+ v-show="multiselect && (!searchable || !isExpanded)"
97
92
  class="root-container--placeholder"
98
93
  >
99
94
  <template v-if="allFiltersModel">
100
- {{ computedAllItemsLabel }}
95
+ <dl-ellipsis :text="computedAllItemsLabel" />
101
96
  </template>
102
97
  <template v-else>
103
- <dl-ellipsis> filterSelectLabel </dl-ellipsis>
98
+ <dl-ellipsis :text="filterSelectLabel" />
104
99
  </template>
105
100
  </span>
106
101
  <span
107
- v-show="
108
- (!multiselect && !searchable) ||
109
- (!multiselect && searchable && !isExpanded)
110
- "
102
+ v-show="!multiselect && (!searchable || !isExpanded)"
111
103
  class="selected-label"
112
104
  >
113
- <dl-ellipsis>
114
- {{ getLabel(selectedOption) }}
115
- </dl-ellipsis>
105
+ <dl-ellipsis :text="getLabel(selectedOption)" />
116
106
  </span>
117
107
  </template>
118
108
  <div
@@ -635,10 +625,10 @@ export default defineComponent({
635
625
  }
636
626
  return this.modelValueLength > 0
637
627
  ? `${this.modelValueLength} ${this.selectedResourceLabel}`
638
- : this.computedPlaceholder
628
+ : String(this.computedPlaceholder)
639
629
  },
640
630
  computedAllItemsLabel(): string {
641
- return this.allItemsOptionLabel || 'All Items'
631
+ return String(this.allItemsOptionLabel ?? 'All Items')
642
632
  },
643
633
  isModelValuePrimitiveType(): boolean {
644
634
  return this.isPrimitiveValue(this.modelValue)
@@ -674,7 +664,7 @@ export default defineComponent({
674
664
  return this.searchable && this.isExpanded
675
665
  },
676
666
  computedPlaceholder(): string {
677
- return this.placeholder || 'Select option'
667
+ return String(this.placeholder ?? 'Select option')
678
668
  },
679
669
  placeholderStyles(): Record<string, string> {
680
670
  if (this.disabled) {
@@ -3,10 +3,10 @@ import { DlSelectOptionType } from './types'
3
3
 
4
4
  export const getLabel = (option: any) => {
5
5
  if (typeof option === 'object' && 'label' in option) {
6
- return option.label
6
+ return String(option.label)
7
7
  }
8
8
 
9
- return option
9
+ return String(option)
10
10
  }
11
11
 
12
12
  const ICON_SIZES = {
@@ -45,12 +45,12 @@ export const getLabelOfSelectedOption = (
45
45
  typeof selected === 'string' &&
46
46
  option === selected
47
47
  ) {
48
- return option
48
+ return String(option)
49
49
  } else if (
50
50
  typeof option === 'object' &&
51
51
  isValueSelected(option, selected)
52
52
  ) {
53
- return option.label
53
+ return String(option.label)
54
54
  }
55
55
  }
56
56
  return '1 Option Selected'
@@ -697,6 +697,19 @@
697
697
  <div>{{ scope.opt.label }}</div>
698
698
  </template>
699
699
  </dl-select>
700
+
701
+ Select numbers as labels
702
+ <dl-select
703
+ v-model="selectedNumbers"
704
+ :options="optionsAsNumbers"
705
+ multiselect
706
+ searchable
707
+ style="margin-bottom: 150px; width: 200px"
708
+ >
709
+ <template #selected="scope">
710
+ <div>{{ scope.opt.label }}</div>
711
+ </template>
712
+ </dl-select>
700
713
  </div>
701
714
  </template>
702
715
 
@@ -712,6 +725,12 @@ const defaultOptions = [
712
725
  { label: 'Contributor 3', value: 'c3' }
713
726
  ]
714
727
 
728
+ const optionsAsNumbers = [
729
+ { label: 1, value: 1 },
730
+ { label: 2, value: 2 },
731
+ { label: 3, value: 3 }
732
+ ]
733
+
715
734
  const defaultOptions1 = [
716
735
  {
717
736
  label: 'Contributor 1 Contributor 1 Contributor 1 Contributor 1 Contributor 1 Contributor 1',
@@ -980,7 +999,9 @@ export default defineComponent({
980
999
  tasksFilter: [],
981
1000
  showAllOption: true,
982
1001
  disabledSelected: 'disabled option',
983
- preSelectedValue: null
1002
+ preSelectedValue: null,
1003
+ optionsAsNumbers,
1004
+ selectedNumbers: []
984
1005
  }
985
1006
  },
986
1007
  computed: {
@@ -136,7 +136,7 @@ export default defineComponent({
136
136
  '*': 'any'
137
137
  },
138
138
  type: ['dir', 'file'],
139
- test0: ['why wont', 'this work', 123],
139
+ test0: ['why wont', 'this work', 123, '1\' = 12"'],
140
140
  test1: [...numbersArr, 'number'],
141
141
  test2: ['true', 'false']
142
142
  }
@@ -333,10 +333,12 @@ export const useSuggestions = (
333
333
  const mappedTypes: string[] = []
334
334
  for (const type of filteredTypes) {
335
335
  if (typeof type === 'string') {
336
- mappedTypes.push(`'${type}'`)
336
+ mappedTypes.push(enquoteString(type))
337
337
  } else if (typeof type === 'object') {
338
338
  mappedTypes.push(
339
- ...Object.keys(type).map((key) => `'${key}'`)
339
+ ...Object.keys(type).map((key) =>
340
+ enquoteString(key)
341
+ )
340
342
  )
341
343
  } else {
342
344
  mappedTypes.push(type)
@@ -614,10 +616,19 @@ const isValidBoolean = (str: string) => {
614
616
  }
615
617
 
616
618
  const isValidString = (str: string) => {
617
- const match = str.match(/(?<=\")(.*?)(?=\")|(?<=\')(.*?)(?=\')/)
618
- if (!match) return false
619
- const trimmed = str.trim()
620
- return match[0] === trimmed.substring(1, trimmed.length - 1)
619
+ const matchSingleQuotes = str.match(/^\s*(?<!\\)'(.*)(?<!\\)'\s*$/)
620
+ if (matchSingleQuotes) {
621
+ return !/(?<!\\)'/.test(matchSingleQuotes[1])
622
+ }
623
+ const matchDoubleQuotes = str.match(/^\s*(?<!\\)"(.*)(?<!\\)"\s*$/)
624
+ if (matchDoubleQuotes) {
625
+ return !/(?<!\\)"/.test(matchDoubleQuotes[1])
626
+ }
627
+ return false
628
+ }
629
+
630
+ const enquoteString = (str: string) => {
631
+ return `'${str.replace(/'/g, "\\'")}'`
621
632
  }
622
633
 
623
634
  const getOperatorByDataType = (dataType: string) => {
@@ -728,7 +739,9 @@ const getValueMatch = (
728
739
  let serach = s
729
740
 
730
741
  if (typeof str === 'string') {
731
- term = insensitive(str.replace(/["']/gi, ''))
742
+ term = insensitive(
743
+ str.replace(/^["'](.*)["']$/, '$1').replace(/\\'/g, "'")
744
+ )
732
745
  }
733
746
  if (typeof s === 'string') {
734
747
  serach = insensitive(s)
@@ -844,7 +857,9 @@ const getValueSuggestions = (
844
857
  !knownDataTypes.includes(type as string) &&
845
858
  typeof type !== 'object'
846
859
  ) {
847
- suggestion.push(typeof type === 'string' ? `'${type}'` : type)
860
+ suggestion.push(
861
+ typeof type === 'string' ? enquoteString(type) : type
862
+ )
848
863
  }
849
864
  }
850
865
  }
@@ -863,7 +878,7 @@ const getValueSuggestions = (
863
878
  default:
864
879
  if (typeof type === 'object') {
865
880
  // value aliases: key is the alias, value is the actual value
866
- for (const key in type) suggestion.push(`'${key}'`)
881
+ for (const key in type) suggestion.push(enquoteString(key))
867
882
  }
868
883
  break
869
884
  }
@@ -29,6 +29,17 @@ const GeneratePureValue = (value: any) => {
29
29
  if (isFinite(num)) {
30
30
  return num
31
31
  }
32
+
33
+ let unquoted = value.replace(/^[^']*'(.*)'[^']*$/, '$1')
34
+ if (unquoted !== value) {
35
+ return unquoted.replace(/\\'/g, "'")
36
+ }
37
+
38
+ unquoted = value.replace(/^[^"]*"(.*)"[^"]*$/, '$1')
39
+ if (unquoted !== value) {
40
+ return unquoted.replace(/\\"/g, '"')
41
+ }
42
+
32
43
  return value.replaceAll('"', '').replaceAll("'", '')
33
44
  } catch (e) {}
34
45
  }
@@ -48,6 +59,14 @@ const Operators: string[] = [
48
59
  'DOESNT-EXIST'
49
60
  ]
50
61
 
62
+ const SplitFirst = (what: string, by: string): string[] => {
63
+ const result = what.split(by)
64
+ if (result.length > 2) {
65
+ return [result.shift(), result.join(by)]
66
+ }
67
+ return result
68
+ }
69
+
51
70
  /**
52
71
  * Method to convert a DlSmartSearch query string to Mongo based JSON query
53
72
  *
@@ -112,66 +131,67 @@ export const parseSmartQuery = (
112
131
  for (const term of andTerms) {
113
132
  pureValue = null
114
133
 
134
+ const termUpToQuote = term.replace(/^([^'"]+)['"].*$/, '$1')
135
+
115
136
  switch (true) {
116
- case term.includes('>='):
117
- ;[key, value] = term.split('>=').map((x) => x.trim())
137
+ case termUpToQuote.includes('>='):
138
+ ;[key, value] = SplitFirst(term, '>=').map((x) => x.trim())
118
139
  pureValue = GeneratePureValue(value)
119
140
  if (pureValue !== null) {
120
141
  andQuery.push({ [key]: { $gte: pureValue } })
121
142
  }
122
143
  break
123
- case term.includes('<='):
124
- ;[key, value] = term.split('<=').map((x) => x.trim())
144
+ case termUpToQuote.includes('<='):
145
+ ;[key, value] = SplitFirst(term, '<=').map((x) => x.trim())
125
146
  pureValue = GeneratePureValue(value)
126
147
  if (pureValue !== null) {
127
148
  andQuery.push({ [key]: { $lte: pureValue } })
128
149
  }
129
150
  break
130
- case term.includes('>'):
131
- ;[key, value] = term.split('>').map((x) => x.trim())
151
+ case termUpToQuote.includes('>'):
152
+ ;[key, value] = SplitFirst(term, '>').map((x) => x.trim())
132
153
  pureValue = GeneratePureValue(value)
133
154
  if (pureValue !== null) {
134
155
  andQuery.push({ [key]: { $gt: pureValue } })
135
156
  }
136
157
  break
137
- case term.includes('<'):
138
- ;[key, value] = term.split('<').map((x) => x.trim())
158
+ case termUpToQuote.includes('<'):
159
+ ;[key, value] = SplitFirst(term, '<').map((x) => x.trim())
139
160
  pureValue = GeneratePureValue(value)
140
161
  if (pureValue !== null) {
141
162
  andQuery.push({ [key]: { $lt: pureValue } })
142
163
  }
143
164
  break
144
- case term.includes('!='):
145
- ;[key, value] = term.split('!=').map((x) => x.trim())
165
+ case termUpToQuote.includes('!='):
166
+ ;[key, value] = SplitFirst(term, '!=').map((x) => x.trim())
146
167
  pureValue = GeneratePureValue(value)
147
168
  if (pureValue !== null) {
148
169
  andQuery.push({ [key]: { $ne: pureValue } })
149
170
  }
150
171
  break
151
- case term.includes('='):
152
- ;[key, value] = term.split('=').map((x) => x.trim())
172
+ case termUpToQuote.includes('='):
173
+ ;[key, value] = SplitFirst(term, '=').map((x) => x.trim())
153
174
  pureValue = GeneratePureValue(value)
154
175
  if (pureValue !== null) {
155
176
  andQuery.push({ [key]: pureValue })
156
177
  }
157
178
  break
158
- case term.includes('EXISTS'):
179
+ case termUpToQuote.includes('EXISTS'):
159
180
  key = term.split('EXISTS')[0].trim()
160
181
  andQuery.push({ [key]: { $exists: true } })
161
182
  break
162
- case term.includes('DOESNT-EXIST'):
183
+ case termUpToQuote.includes('DOESNT-EXIST'):
163
184
  key = term.split('DOESNT-EXIST')[0].trim()
164
185
  andQuery.push({ [key]: { $exists: false } })
165
186
  break
166
- case term.includes('IN'):
167
- ;[key, value] = term.split('IN').map((x) => x.trim())
187
+ case termUpToQuote.includes('IN'):
188
+ ;[key, value] = SplitFirst(term, 'IN').map((x) => x.trim())
168
189
  if (key.includes('NOT-')) {
169
- ;[key, value] = term
170
- .split('NOT-IN')
171
- .map((x) => x.trim())
172
- queryValue = term
173
- .split('NOT-IN')
174
- .map((x) => x.trim())[1]
190
+ ;[key, value] = SplitFirst(term, 'NOT-IN').map((x) =>
191
+ x.trim()
192
+ )
193
+ // TODO make , inside quotes work
194
+ queryValue = value
175
195
  .split(',')
176
196
  .map((x) => GeneratePureValue(x.trim()))
177
197
  .filter((x) => x)
@@ -181,9 +201,8 @@ export const parseSmartQuery = (
181
201
  andQuery.push({ [key]: { $nin: pureValue } })
182
202
  }
183
203
  } else {
184
- queryValue = term
185
- .split('IN')
186
- .map((x) => x.trim())[1]
204
+ // TODO make , inside quotes work
205
+ queryValue = value
187
206
  .split(',')
188
207
  .map((x) => GeneratePureValue(x.trim()))
189
208
  .filter((x) => x)
@@ -344,7 +363,7 @@ export const stringifySmartQuery = (query: { [key: string]: any }): string => {
344
363
  } else if (isDatePattern(value)) {
345
364
  result += `${key} = (${value})`
346
365
  } else {
347
- result += `${key} = '${value}'`
366
+ result += `${key} = '${value.toString().replace(/'/g, "\\'")}'`
348
367
  }
349
368
  }
350
369
 
@@ -3,7 +3,7 @@ export function splitByQuotes(input: string, split: string) {
3
3
  .replace('sp', split)
4
4
  .replace('o', '[\\(\\{\\[]')
5
5
  .replace('c', '[\\)\\}\\]]')
6
- .replace('t', '[\'"]')
6
+ .replace('t', '(?<!\\\\)[\'"]')
7
7
  .replace('e', '[\\\\]')
8
8
  const r = new RegExp(pattern, 'gi')
9
9
  const stack: string[] = []
@@ -13,11 +13,20 @@ export function splitByQuotes(input: string, split: string) {
13
13
  if ($e) {
14
14
  buffer.push($1, $s || $o || $c || $t)
15
15
  return
16
- } else if ($o) stack.push($o)
17
- else if ($c) stack.pop()
18
- else if ($t) {
19
- if (stack[stack.length - 1] !== $t) stack.push($t)
20
- else stack.pop()
16
+ } else if ($o) {
17
+ if (!stack.includes("'") && !stack.includes('"')) {
18
+ stack.push($o)
19
+ }
20
+ } else if ($c) {
21
+ if (!stack.includes("'") && !stack.includes('"')) {
22
+ stack.pop()
23
+ }
24
+ } else if ($t) {
25
+ const otherQuote = $t === '"' ? "'" : '"'
26
+ if (!stack.includes(otherQuote)) {
27
+ if (stack[stack.length - 1] !== $t) stack.push($t)
28
+ else stack.pop()
29
+ }
21
30
  } else {
22
31
  if ($s ? !stack.length : !$1) {
23
32
  buffer.push($1)