@dataloop-ai/components 0.18.70 → 0.18.72
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 +1 -1
- package/src/StateManager.ts +3 -0
- package/src/components/basic/DlButton/DlButton.vue +1 -1
- package/src/components/basic/DlButton/utils.ts +22 -11
- package/src/components/basic/DlPopup/DlPopup.vue +4 -2
- package/src/components/compound/DlDialogBox/DlDialogBox.vue +4 -1
- package/src/components/compound/DlJsonEditor/DlJsonEditor.vue +11 -3
- package/src/components/compound/DlSearches/DlSmartSearch/DlSmartSearch.vue +114 -559
- package/src/components/compound/DlSearches/DlSmartSearch/components/{DlSmartSearchFilters.vue → DlSmartSearchFilter/DlSmartSearchFilters.vue} +7 -6
- package/src/components/compound/DlSearches/DlSmartSearch/components/{FiltersQuery.vue → DlSmartSearchFilter/components/FiltersQuery.vue} +2 -2
- package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchInput.vue +492 -406
- package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchJsonEditorDialog.vue +322 -0
- package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchQueryFilters.vue +124 -0
- package/src/components/compound/DlSearches/DlSmartSearch/components/{DlSuggestionsDropdown.vue → SuggestionsDropdown.vue} +0 -1
- package/src/components/compound/DlSearches/DlSmartSearch/components/index.ts +4 -0
- package/src/components/compound/DlSearches/DlSmartSearch/index.ts +2 -1
- package/src/components/compound/DlSearches/DlSmartSearch/types.ts +1 -0
- package/src/components/compound/DlSearches/DlSmartSearch/utils/highlightSyntax.ts +16 -16
- package/src/components/compound/DlSearches/DlSmartSearch/utils/index.ts +12 -7
- package/src/components/compound/DlSelect/types.ts +4 -0
- package/src/components/compound/DlTreeTable/components/DlTrTree.vue +2 -3
- package/src/components/compound/types.ts +1 -0
- package/src/components/essential/DlLabel/DlLabel.vue +5 -5
- package/src/components/shared/DlTooltip/DlTooltip.vue +1 -6
- package/src/components/shared/DlVirtualScroll/DlVirtualScroll.vue +36 -27
- package/src/demos/DlButtonDemo.vue +3 -1
- package/src/demos/DlDialogBoxDemo.vue +163 -53
- package/src/demos/DlLabelDemo.vue +8 -8
- package/src/demos/DlPopupDemo.vue +13 -0
- package/src/demos/SmartSearchDemo/DlSmartSearchDemo.vue +16 -6
- package/src/hooks/use-portal.ts +1 -7
- package/src/hooks/use-suggestions.ts +5 -1
- package/src/utils/events.ts +3 -1
- package/src/utils/index.ts +59 -0
- package/src/utils/parse-smart-query.ts +7 -3
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
:class="identifierClass"
|
|
4
3
|
class="dl-smart-search"
|
|
5
4
|
:style="cssVars"
|
|
6
5
|
>
|
|
@@ -10,21 +9,15 @@
|
|
|
10
9
|
>
|
|
11
10
|
<dl-smart-search-input
|
|
12
11
|
ref="smartSearchInput"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
:
|
|
16
|
-
:
|
|
17
|
-
:
|
|
18
|
-
:
|
|
19
|
-
:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
:search-bar-width="searchBarWidth"
|
|
23
|
-
:default-width="width"
|
|
24
|
-
@save="saveQueryDialogBoxModel = true"
|
|
25
|
-
@focus="setFocused"
|
|
26
|
-
@update:model-value="debouncedInputModel"
|
|
27
|
-
@dql-edit="jsonEditorModel = !jsonEditorModel"
|
|
12
|
+
v-model="queryObject"
|
|
13
|
+
style="margin-bottom: 0px"
|
|
14
|
+
:status="status"
|
|
15
|
+
:aliases="aliases"
|
|
16
|
+
:schema="schema"
|
|
17
|
+
:color-schema="colorSchema"
|
|
18
|
+
:strict="strict"
|
|
19
|
+
@focus="isFocused = true"
|
|
20
|
+
@blur="isFocused = false"
|
|
28
21
|
/>
|
|
29
22
|
</div>
|
|
30
23
|
<div class="dl-smart-search__buttons">
|
|
@@ -35,7 +28,7 @@
|
|
|
35
28
|
class="dl-smart-search__search-btn-wrapper"
|
|
36
29
|
>
|
|
37
30
|
<dl-button
|
|
38
|
-
|
|
31
|
+
label="Search"
|
|
39
32
|
:styles="{
|
|
40
33
|
height: '28px'
|
|
41
34
|
}"
|
|
@@ -43,222 +36,51 @@
|
|
|
43
36
|
@click="emitSearchQuery"
|
|
44
37
|
/>
|
|
45
38
|
</div>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<dl-button
|
|
50
|
-
class="dl-smart-search__buttons--filters"
|
|
51
|
-
shaded
|
|
52
|
-
outlined
|
|
53
|
-
size="s"
|
|
39
|
+
<div
|
|
40
|
+
style="height: 28px"
|
|
41
|
+
class="dl-smart-search__search-btn-wrapper"
|
|
54
42
|
>
|
|
55
|
-
Saved Filters
|
|
56
|
-
<dl-menu
|
|
57
|
-
v-model="filtersModel"
|
|
58
|
-
:offset="[0, 5]"
|
|
59
|
-
anchor="bottom middle"
|
|
60
|
-
self="top middle"
|
|
61
|
-
>
|
|
62
|
-
<dl-smart-search-filters
|
|
63
|
-
:filters="filters"
|
|
64
|
-
@filters-select="handleFiltersSelect"
|
|
65
|
-
@filters-delete="handleFiltersDelete"
|
|
66
|
-
/>
|
|
67
|
-
</dl-menu>
|
|
68
|
-
</dl-button>
|
|
69
|
-
</div>
|
|
70
|
-
</slot>
|
|
71
|
-
</div>
|
|
72
|
-
<dl-dialog-box
|
|
73
|
-
v-model="jsonEditorModel"
|
|
74
|
-
:height="500"
|
|
75
|
-
:width="800"
|
|
76
|
-
style="--dl-dialog-box-footer-padding: 10px 16px"
|
|
77
|
-
>
|
|
78
|
-
<template #header>
|
|
79
|
-
<dl-dialog-box-header
|
|
80
|
-
title="DQL Search"
|
|
81
|
-
:close-button="true"
|
|
82
|
-
style="font-weight: 200"
|
|
83
|
-
@onClose="handleJsonEditorClose"
|
|
84
|
-
/>
|
|
85
|
-
</template>
|
|
86
|
-
<template #body>
|
|
87
|
-
<div class="json-editor-layout">
|
|
88
|
-
<div class="json-query">
|
|
89
|
-
<div class="json-query-menu">
|
|
90
|
-
<dl-select
|
|
91
|
-
:model-value="selectedOption"
|
|
92
|
-
width="200px"
|
|
93
|
-
:options="selectOptions"
|
|
94
|
-
placeholder="New Query"
|
|
95
|
-
@update:model-value="updateActiveQuery"
|
|
96
|
-
/>
|
|
97
|
-
<dl-button
|
|
98
|
-
icon="icon-dl-align-left"
|
|
99
|
-
label="Align Left"
|
|
100
|
-
flat
|
|
101
|
-
color="secondary"
|
|
102
|
-
padding="0px 3px"
|
|
103
|
-
@click="alignJsonText"
|
|
104
|
-
/>
|
|
105
|
-
</div>
|
|
106
|
-
<dl-json-editor
|
|
107
|
-
v-model="jsonEditorQuery"
|
|
108
|
-
:prevent-update="preventUpdate"
|
|
109
|
-
@update-prevent="(val) => (preventUpdate = val)"
|
|
110
|
-
@align-text="alignJsonText"
|
|
111
|
-
/>
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
</template>
|
|
115
|
-
<template #footer>
|
|
116
|
-
<div class="json-editor__footer-menu">
|
|
117
|
-
<div class="json-editor__footer-delete">
|
|
118
43
|
<dl-button
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
44
|
+
label="DQL Editor"
|
|
45
|
+
:styles="{
|
|
46
|
+
height: '28px',
|
|
47
|
+
'min-width': 'max-content'
|
|
48
|
+
}"
|
|
49
|
+
:disabled="disabled"
|
|
122
50
|
flat
|
|
123
|
-
color="
|
|
124
|
-
|
|
125
|
-
@click="
|
|
126
|
-
/>
|
|
127
|
-
</div>
|
|
128
|
-
<div class="json-editor__footer-save">
|
|
129
|
-
<dl-button
|
|
130
|
-
style="margin-right: 14px"
|
|
131
|
-
outlined
|
|
132
|
-
label="Save As"
|
|
133
|
-
@click="saveQueryDialogBoxModel = true"
|
|
134
|
-
/>
|
|
135
|
-
<dl-button
|
|
136
|
-
label="Search"
|
|
137
|
-
@click="handleJsonSearchButton"
|
|
51
|
+
text-color="var(--dl-color-darker)"
|
|
52
|
+
color="var(--dl-color-darker)"
|
|
53
|
+
@click="showJSONEditor = true"
|
|
138
54
|
/>
|
|
139
55
|
</div>
|
|
140
|
-
</div>
|
|
141
|
-
</template>
|
|
142
|
-
</dl-dialog-box>
|
|
143
56
|
|
|
144
|
-
|
|
145
|
-
<template #header>
|
|
146
|
-
<dl-dialog-box-header
|
|
147
|
-
title="Delete Query"
|
|
148
|
-
@onClose="removeQueryDialogBoxModel = false"
|
|
149
|
-
/>
|
|
150
|
-
</template>
|
|
151
|
-
<template #body>
|
|
152
|
-
<dl-typography
|
|
153
|
-
size="h3"
|
|
154
|
-
style="display: flex; justify-content: center"
|
|
155
|
-
>
|
|
156
|
-
Are you sure you want to delete {{ activeQuery.name }}?
|
|
157
|
-
</dl-typography>
|
|
158
|
-
</template>
|
|
159
|
-
<template #footer>
|
|
160
|
-
<div class="full-width flex justify-end">
|
|
161
|
-
<dl-button @click="emitRemoveQuery">
|
|
162
|
-
Delete
|
|
163
|
-
</dl-button>
|
|
164
|
-
</div>
|
|
165
|
-
</template>
|
|
166
|
-
</dl-dialog-box>
|
|
167
|
-
<dl-dialog-box
|
|
168
|
-
v-model="saveQueryDialogBoxModel"
|
|
169
|
-
style="--dl-dialog-box-footer-padding: 14px 17px"
|
|
170
|
-
>
|
|
171
|
-
<template #header>
|
|
172
|
-
<dl-dialog-box-header
|
|
173
|
-
title="Save Query"
|
|
174
|
-
@onClose="saveQueryDialogBoxModel = false"
|
|
175
|
-
/>
|
|
176
|
-
</template>
|
|
177
|
-
<template #body>
|
|
178
|
-
<dl-input
|
|
179
|
-
v-model="newQueryName"
|
|
180
|
-
title="Query name"
|
|
181
|
-
style="text-align: center"
|
|
182
|
-
placeholder="Type query name"
|
|
183
|
-
/>
|
|
184
|
-
</template>
|
|
185
|
-
<template #footer>
|
|
186
|
-
<div class="dl-smart-search__buttons--save">
|
|
187
|
-
<dl-button
|
|
188
|
-
:disabled="!newQueryName"
|
|
189
|
-
outlined
|
|
190
|
-
@click="handleSaveQuery"
|
|
191
|
-
>
|
|
192
|
-
Save
|
|
193
|
-
</dl-button>
|
|
194
|
-
<dl-button
|
|
195
|
-
:disabled="!newQueryName"
|
|
196
|
-
@click="handleSaveQuery(true)"
|
|
197
|
-
>
|
|
198
|
-
Save and Search
|
|
199
|
-
</dl-button>
|
|
57
|
+
<slot name="extra-actions" />
|
|
200
58
|
</div>
|
|
201
|
-
</
|
|
202
|
-
</
|
|
59
|
+
</slot>
|
|
60
|
+
</div>
|
|
61
|
+
<dl-smart-search-json-editor-dialog
|
|
62
|
+
v-model="showJSONEditor"
|
|
63
|
+
:json="stringifiedJSON"
|
|
64
|
+
@search="emitSearchQuery"
|
|
65
|
+
@change="handleJSONChange"
|
|
66
|
+
/>
|
|
67
|
+
<!-- todo: Add support for saved queries-->
|
|
203
68
|
</div>
|
|
204
69
|
</template>
|
|
205
70
|
<script lang="ts">
|
|
206
|
-
import {
|
|
207
|
-
defineComponent,
|
|
208
|
-
PropType,
|
|
209
|
-
ref,
|
|
210
|
-
nextTick,
|
|
211
|
-
toRef,
|
|
212
|
-
onMounted,
|
|
213
|
-
watch,
|
|
214
|
-
computed
|
|
215
|
-
} from 'vue-demi'
|
|
216
|
-
import { DlTypography, DlMenu } from '../../../essential'
|
|
71
|
+
import { defineComponent, PropType, ref, computed, toRefs } from 'vue-demi'
|
|
217
72
|
import { DlButton } from '../../../basic'
|
|
218
|
-
import {
|
|
219
|
-
import {
|
|
220
|
-
import {
|
|
221
|
-
import { DlJsonEditor } from '../../DlJsonEditor'
|
|
222
|
-
|
|
223
|
-
import DlSmartSearchInput from './components/DlSmartSearchInput.vue'
|
|
224
|
-
import DlSmartSearchFilters from './components/DlSmartSearchFilters.vue'
|
|
225
|
-
|
|
226
|
-
import {
|
|
227
|
-
useSuggestions,
|
|
228
|
-
Schema,
|
|
229
|
-
Alias,
|
|
230
|
-
removeBrackets
|
|
231
|
-
} from '../../../../hooks/use-suggestions'
|
|
232
|
-
import {
|
|
233
|
-
Filters,
|
|
234
|
-
Query,
|
|
235
|
-
ColorSchema,
|
|
236
|
-
SearchStatus,
|
|
237
|
-
SyntaxColorSchema
|
|
238
|
-
} from './types'
|
|
239
|
-
import {
|
|
240
|
-
revertAliases,
|
|
241
|
-
setAliases,
|
|
242
|
-
replaceStringifiedDatesWithJSDates,
|
|
243
|
-
createColorSchema,
|
|
244
|
-
replaceJSDatesWithStringifiedDates
|
|
245
|
-
} from './utils'
|
|
73
|
+
import { DlSmartSearchInput, DlSmartSearchJsonEditorDialog } from './components'
|
|
74
|
+
import { Schema, Alias } from '../../../../hooks/use-suggestions'
|
|
75
|
+
import { Filters, ColorSchema, SearchStatus } from './types'
|
|
246
76
|
import { v4 } from 'uuid'
|
|
247
|
-
import {
|
|
248
|
-
import { debounce, isEqual } from 'lodash'
|
|
77
|
+
import { stateManager } from '../../../../StateManager'
|
|
249
78
|
|
|
250
79
|
export default defineComponent({
|
|
251
80
|
components: {
|
|
252
81
|
DlSmartSearchInput,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
DlJsonEditor,
|
|
256
|
-
DlButton,
|
|
257
|
-
DlTypography,
|
|
258
|
-
DlInput,
|
|
259
|
-
DlSmartSearchFilters,
|
|
260
|
-
DlMenu,
|
|
261
|
-
DlSelect
|
|
82
|
+
DlSmartSearchJsonEditorDialog,
|
|
83
|
+
DlButton
|
|
262
84
|
},
|
|
263
85
|
model: {
|
|
264
86
|
prop: 'modelValue',
|
|
@@ -289,18 +111,6 @@ export default defineComponent({
|
|
|
289
111
|
keywords: 'var(--dl-color-medium)'
|
|
290
112
|
})
|
|
291
113
|
},
|
|
292
|
-
isLoading: {
|
|
293
|
-
type: Boolean,
|
|
294
|
-
default: false
|
|
295
|
-
},
|
|
296
|
-
expandedInputHeight: {
|
|
297
|
-
type: String,
|
|
298
|
-
default: '327px'
|
|
299
|
-
},
|
|
300
|
-
savedFilterKey: {
|
|
301
|
-
type: String,
|
|
302
|
-
default: 'saved'
|
|
303
|
-
},
|
|
304
114
|
filters: {
|
|
305
115
|
type: Object as PropType<Filters>,
|
|
306
116
|
default: () => ({} as Filters)
|
|
@@ -311,7 +121,7 @@ export default defineComponent({
|
|
|
311
121
|
},
|
|
312
122
|
width: {
|
|
313
123
|
type: String,
|
|
314
|
-
default: '
|
|
124
|
+
default: '250px'
|
|
315
125
|
},
|
|
316
126
|
/**
|
|
317
127
|
* If true, the validation will be a closed set based on the schema provided
|
|
@@ -323,8 +133,14 @@ export default defineComponent({
|
|
|
323
133
|
},
|
|
324
134
|
emits: ['save-query', 'remove-query', 'search-query', 'update:model-value'],
|
|
325
135
|
setup(props, { emit }) {
|
|
136
|
+
//#region props
|
|
137
|
+
const { modelValue, filters, width } = toRefs(props)
|
|
138
|
+
//#endregion
|
|
139
|
+
|
|
140
|
+
//#region data
|
|
326
141
|
const inputModel = ref('')
|
|
327
142
|
const jsonEditorModel = ref(false)
|
|
143
|
+
const showJSONEditor = ref(false)
|
|
328
144
|
const searchBarWidth = ref('100%')
|
|
329
145
|
|
|
330
146
|
const activeQuery = ref({
|
|
@@ -346,127 +162,86 @@ export default defineComponent({
|
|
|
346
162
|
label: 'New Query',
|
|
347
163
|
value: ''
|
|
348
164
|
})
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
emit('update:model-value',
|
|
165
|
+
//#endregion
|
|
166
|
+
|
|
167
|
+
//#region computed
|
|
168
|
+
const stringifiedJSON = computed(() => JSON.stringify(modelValue.value))
|
|
169
|
+
|
|
170
|
+
const cssVars = computed(() => ({
|
|
171
|
+
'--dl-smart-search-max-width': isFocused.value
|
|
172
|
+
? '100%'
|
|
173
|
+
: width.value
|
|
174
|
+
}))
|
|
175
|
+
|
|
176
|
+
const queryObject = computed({
|
|
177
|
+
get() {
|
|
178
|
+
return modelValue.value
|
|
179
|
+
},
|
|
180
|
+
set(val) {
|
|
181
|
+
emit('update:model-value', val)
|
|
366
182
|
}
|
|
367
|
-
|
|
368
|
-
activeQuery.value.query = stringified
|
|
369
|
-
nextTick(() => {
|
|
370
|
-
findSuggestions(aliased)
|
|
371
|
-
})
|
|
372
|
-
isQuerying.value = false
|
|
373
|
-
oldInputQuery.value = aliased
|
|
374
|
-
}
|
|
183
|
+
})
|
|
375
184
|
|
|
376
|
-
const
|
|
185
|
+
const selectedOptions = computed(() => {
|
|
186
|
+
const options: Record<string, string>[] = [
|
|
187
|
+
{
|
|
188
|
+
label: 'New Query',
|
|
189
|
+
value: '{}'
|
|
190
|
+
}
|
|
191
|
+
]
|
|
377
192
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
193
|
+
const queryFilters = filters.value?.saved ?? []
|
|
194
|
+
for (const filter of queryFilters) {
|
|
195
|
+
options.push({
|
|
196
|
+
label: filter.name,
|
|
197
|
+
value: filter.query
|
|
198
|
+
})
|
|
384
199
|
}
|
|
385
200
|
|
|
386
|
-
return
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const toJSON = (value: string) => {
|
|
390
|
-
const json = parseSmartQuery(
|
|
391
|
-
replaceStringifiedDatesWithJSDates(value) ?? inputModel.value
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
return isValidJSON(json) ? json : inputModel.value
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
const schemaRef = toRef(props, 'schema')
|
|
398
|
-
const dateKeys = computed(() => {
|
|
399
|
-
return Object.keys(schemaRef.value).filter(
|
|
400
|
-
(key) => schemaRef.value[key] === 'date'
|
|
401
|
-
)
|
|
201
|
+
return options
|
|
402
202
|
})
|
|
203
|
+
//#endregion
|
|
403
204
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
)
|
|
409
|
-
|
|
410
|
-
const stringQuery = stringifySmartQuery(replacedDate)
|
|
411
|
-
const aliased = setAliases(stringQuery, props.aliases)
|
|
412
|
-
return aliased
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
const setFocused = (value: boolean) => {
|
|
416
|
-
isFocused.value = value
|
|
417
|
-
findSuggestions(inputModel.value)
|
|
418
|
-
|
|
419
|
-
if (value) {
|
|
420
|
-
inputModel.value = oldInputQuery.value
|
|
421
|
-
isQuerying.value = false
|
|
205
|
+
//#region methods
|
|
206
|
+
const toObject = (query: string) => {
|
|
207
|
+
if (typeof query !== 'string') {
|
|
208
|
+
return query
|
|
422
209
|
}
|
|
423
|
-
if (!value && !error) {
|
|
424
|
-
toJSON(inputModel.value)
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
210
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
211
|
+
try {
|
|
212
|
+
return JSON.parse(query)
|
|
213
|
+
} catch (e) {
|
|
214
|
+
stateManager.logger.warn(
|
|
215
|
+
'DlSmartSearch - Invalid JSON in DQL Editor',
|
|
216
|
+
e
|
|
434
217
|
)
|
|
435
|
-
|
|
436
|
-
if (isEqual(val, currModel)) {
|
|
437
|
-
return
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
const aliased = fromJSON(val)
|
|
441
|
-
|
|
442
|
-
if (aliased !== inputModel.value.trim()) {
|
|
443
|
-
debouncedInputModel(aliased)
|
|
444
|
-
}
|
|
218
|
+
return null
|
|
445
219
|
}
|
|
446
220
|
}
|
|
447
221
|
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
222
|
+
const emitSearchQuery = (query: string) => {
|
|
223
|
+
const json = toObject(query)
|
|
224
|
+
if (!json) return
|
|
225
|
+
queryObject.value = json
|
|
226
|
+
emit('search-query', json)
|
|
227
|
+
}
|
|
453
228
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}
|
|
229
|
+
const handleJSONChange = (val: string) => {
|
|
230
|
+
const json = toObject(val)
|
|
231
|
+
if (!json) return
|
|
232
|
+
queryObject.value = json
|
|
233
|
+
}
|
|
234
|
+
//#endregion
|
|
459
235
|
|
|
460
236
|
return {
|
|
461
237
|
uuid: `dl-smart-search-${v4()}`,
|
|
238
|
+
queryObject,
|
|
462
239
|
inputModel,
|
|
463
240
|
jsonEditorModel,
|
|
464
241
|
activeQuery,
|
|
465
242
|
filtersModel,
|
|
466
243
|
removeQueryDialogBoxModel,
|
|
467
244
|
saveQueryDialogBoxModel,
|
|
468
|
-
suggestions,
|
|
469
|
-
error,
|
|
470
245
|
newQueryName,
|
|
471
246
|
isFocused,
|
|
472
247
|
isQuerying,
|
|
@@ -477,211 +252,12 @@ export default defineComponent({
|
|
|
477
252
|
newQuery,
|
|
478
253
|
preventUpdate,
|
|
479
254
|
selectedOption,
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
},
|
|
488
|
-
computed: {
|
|
489
|
-
identifierClass(): string {
|
|
490
|
-
return `dl-smart-search`
|
|
491
|
-
},
|
|
492
|
-
cssVars(): Record<string, string> {
|
|
493
|
-
return {
|
|
494
|
-
'--dl-search-max-width': this.isFocused ? '100%' : this.width
|
|
495
|
-
}
|
|
496
|
-
},
|
|
497
|
-
defineStyleModel(): SyntaxColorSchema {
|
|
498
|
-
return createColorSchema(this.colorSchema, this.aliases)
|
|
499
|
-
},
|
|
500
|
-
computedStatus(): SearchStatus {
|
|
501
|
-
if (this.isQuerying) return
|
|
502
|
-
if (!this.error && this.inputModel !== '') {
|
|
503
|
-
return {
|
|
504
|
-
type: 'success',
|
|
505
|
-
message: ''
|
|
506
|
-
}
|
|
507
|
-
} else if (this.error === 'warning') {
|
|
508
|
-
return {
|
|
509
|
-
type: 'warning',
|
|
510
|
-
message: 'The query is not supported technically.'
|
|
511
|
-
}
|
|
512
|
-
} else if (this.inputModel === '') {
|
|
513
|
-
return this.status
|
|
514
|
-
}
|
|
515
|
-
return {
|
|
516
|
-
type: 'error',
|
|
517
|
-
message: this.error
|
|
518
|
-
}
|
|
519
|
-
},
|
|
520
|
-
stringQuery(): string {
|
|
521
|
-
return this.isQuerying || this.inputModel === ''
|
|
522
|
-
? this.activeQuery.name
|
|
523
|
-
: this.inputModel
|
|
524
|
-
},
|
|
525
|
-
deleteButtonState(): boolean {
|
|
526
|
-
return !this.filters?.saved?.filter(
|
|
527
|
-
(q: Query) => q.name === this.activeQuery?.name
|
|
528
|
-
).length
|
|
529
|
-
},
|
|
530
|
-
selectOptions(): Record<string, string>[] {
|
|
531
|
-
const options: Record<string, string>[] = [
|
|
532
|
-
{
|
|
533
|
-
label: 'New Query',
|
|
534
|
-
value: '{}'
|
|
535
|
-
}
|
|
536
|
-
]
|
|
537
|
-
|
|
538
|
-
const filters = this.filters?.saved ?? []
|
|
539
|
-
for (const filter of filters) {
|
|
540
|
-
options.push({
|
|
541
|
-
label: filter.name,
|
|
542
|
-
value: filter.query
|
|
543
|
-
})
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
return options
|
|
547
|
-
}
|
|
548
|
-
},
|
|
549
|
-
watch: {
|
|
550
|
-
jsonEditorModel() {
|
|
551
|
-
const json = JSON.stringify(
|
|
552
|
-
this.toJSON(removeBrackets(this.inputModel))
|
|
553
|
-
)
|
|
554
|
-
const newQuery = revertAliases(json, this.aliases)
|
|
555
|
-
if (newQuery && newQuery !== '{}') {
|
|
556
|
-
this.jsonEditorQuery = newQuery
|
|
557
|
-
}
|
|
558
|
-
this.alignJsonText()
|
|
559
|
-
},
|
|
560
|
-
jsonEditorQuery(val) {
|
|
561
|
-
if (
|
|
562
|
-
this.activeQuery.name === 'New Query' ||
|
|
563
|
-
this.activeQuery.name === ''
|
|
564
|
-
) {
|
|
565
|
-
this.newQuery = this.fromJSON(JSON.parse(val))
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
},
|
|
569
|
-
mounted() {
|
|
570
|
-
const observer = new ResizeObserver((entries) => {
|
|
571
|
-
this.searchBarWidth = `${entries[0].contentRect.width}px`
|
|
572
|
-
})
|
|
573
|
-
observer.observe(this.$refs.inputWrapper as HTMLElement)
|
|
574
|
-
},
|
|
575
|
-
methods: {
|
|
576
|
-
handleQueryRemove() {
|
|
577
|
-
this.filtersModel = false
|
|
578
|
-
this.removeQueryDialogBoxModel = true
|
|
579
|
-
},
|
|
580
|
-
handleSaveQuery(performSearch: boolean) {
|
|
581
|
-
this.activeQuery = {
|
|
582
|
-
name: this.newQueryName || this.activeQuery.name,
|
|
583
|
-
query: this.jsonEditorQuery
|
|
584
|
-
}
|
|
585
|
-
if (performSearch === true) {
|
|
586
|
-
this.emitSaveQuery()
|
|
587
|
-
this.emitSearchQuery()
|
|
588
|
-
const newQuery = setAliases(
|
|
589
|
-
stringifySmartQuery(JSON.parse(this.activeQuery.query)),
|
|
590
|
-
this.aliases
|
|
591
|
-
)
|
|
592
|
-
this.inputModel = newQuery
|
|
593
|
-
this.oldInputQuery = newQuery
|
|
594
|
-
this.jsonEditorModel = false
|
|
595
|
-
} else {
|
|
596
|
-
this.emitSaveQuery()
|
|
597
|
-
}
|
|
598
|
-
},
|
|
599
|
-
handleJsonSearchButton() {
|
|
600
|
-
this.jsonEditorModel = false
|
|
601
|
-
this.activeQuery.query = this.jsonEditorQuery
|
|
602
|
-
nextTick(() => {
|
|
603
|
-
this.setQueryInput()
|
|
604
|
-
this.$emit('search-query', this.activeQuery, this.stringQuery)
|
|
605
|
-
})
|
|
606
|
-
},
|
|
607
|
-
handleFiltersDelete(currentTab: string, query: Query) {
|
|
608
|
-
this.activeQuery = query
|
|
609
|
-
this.currentTab = currentTab
|
|
610
|
-
this.removeQueryDialogBoxModel = true
|
|
611
|
-
this.filtersModel = false
|
|
612
|
-
},
|
|
613
|
-
handleFiltersSelect(currentTab: string, query: Query) {
|
|
614
|
-
this.activeQuery = { ...query }
|
|
615
|
-
const stringQuery = setAliases(
|
|
616
|
-
stringifySmartQuery(JSON.parse(query.query)),
|
|
617
|
-
this.aliases
|
|
618
|
-
)
|
|
619
|
-
this.oldInputQuery = stringQuery
|
|
620
|
-
this.inputModel = stringQuery
|
|
621
|
-
this.currentTab = currentTab
|
|
622
|
-
this.filtersModel = false
|
|
623
|
-
},
|
|
624
|
-
handleJsonEditorClose() {
|
|
625
|
-
this.jsonEditorModel = false
|
|
626
|
-
this.newQuery = ''
|
|
627
|
-
},
|
|
628
|
-
emitSearchQuery() {
|
|
629
|
-
this.$emit('search-query', this.activeQuery, this.stringQuery)
|
|
630
|
-
},
|
|
631
|
-
emitRemoveQuery() {
|
|
632
|
-
if (!this.activeQuery) return
|
|
633
|
-
this.$emit(
|
|
634
|
-
'remove-query',
|
|
635
|
-
this.activeQuery,
|
|
636
|
-
this.currentTab,
|
|
637
|
-
this.inputModel
|
|
638
|
-
)
|
|
639
|
-
this.selectedOption = {
|
|
640
|
-
label: 'New Query',
|
|
641
|
-
value: '{}'
|
|
642
|
-
}
|
|
643
|
-
this.activeQuery.query = this.newQuery
|
|
644
|
-
this.jsonEditorQuery = this.newQuery || '{}'
|
|
645
|
-
this.removeQueryDialogBoxModel = false
|
|
646
|
-
},
|
|
647
|
-
emitSaveQuery() {
|
|
648
|
-
if (!this.activeQuery) return
|
|
649
|
-
if (this.newQueryName !== '')
|
|
650
|
-
this.activeQuery.name = this.newQueryName
|
|
651
|
-
this.$emit('save-query', { ...this.activeQuery }, this.currentTab)
|
|
652
|
-
this.saveQueryDialogBoxModel = false
|
|
653
|
-
this.newQueryName = ''
|
|
654
|
-
},
|
|
655
|
-
setQueryInput(query?: string) {
|
|
656
|
-
const stringQuery = this.fromJSON(
|
|
657
|
-
JSON.parse(query || this.activeQuery.query)
|
|
658
|
-
)
|
|
659
|
-
this.inputModel = stringQuery
|
|
660
|
-
this.oldInputQuery = stringQuery
|
|
661
|
-
},
|
|
662
|
-
updateActiveQuery(option: Record<string, string>) {
|
|
663
|
-
this.preventUpdate = true
|
|
664
|
-
const isNewQuery =
|
|
665
|
-
option.label === 'New Query' || option.label === ''
|
|
666
|
-
this.activeQuery = {
|
|
667
|
-
name: option.label,
|
|
668
|
-
query: isNewQuery ? this.newQuery : this.activeQuery.query
|
|
669
|
-
}
|
|
670
|
-
this.preventUpdate = false
|
|
671
|
-
this.jsonEditorQuery = isNewQuery
|
|
672
|
-
? this.newQuery || '{}'
|
|
673
|
-
: option.value
|
|
674
|
-
this.alignJsonText()
|
|
675
|
-
},
|
|
676
|
-
alignJsonText() {
|
|
677
|
-
try {
|
|
678
|
-
this.preventUpdate = false
|
|
679
|
-
this.jsonEditorQuery = JSON.stringify(
|
|
680
|
-
JSON.parse(this.jsonEditorQuery),
|
|
681
|
-
null,
|
|
682
|
-
2
|
|
683
|
-
)
|
|
684
|
-
} catch (err) {}
|
|
255
|
+
cssVars,
|
|
256
|
+
selectedOptions,
|
|
257
|
+
emitSearchQuery,
|
|
258
|
+
showJSONEditor,
|
|
259
|
+
stringifiedJSON,
|
|
260
|
+
handleJSONChange
|
|
685
261
|
}
|
|
686
262
|
}
|
|
687
263
|
})
|
|
@@ -690,6 +266,9 @@ export default defineComponent({
|
|
|
690
266
|
.dl-smart-search {
|
|
691
267
|
display: flex;
|
|
692
268
|
width: 100%;
|
|
269
|
+
align-items: center;
|
|
270
|
+
/* Margin for the absolute text */
|
|
271
|
+
margin-bottom: 15px;
|
|
693
272
|
|
|
694
273
|
&__inner {
|
|
695
274
|
display: flex;
|
|
@@ -699,15 +278,15 @@ export default defineComponent({
|
|
|
699
278
|
&__input-wrapper {
|
|
700
279
|
flex-grow: 1;
|
|
701
280
|
width: 100%;
|
|
702
|
-
max-width: var(--dl-search-max-width);
|
|
281
|
+
max-width: var(--dl-smart-search-max-width);
|
|
703
282
|
transition: max-width 0.3s ease-out;
|
|
704
283
|
}
|
|
705
284
|
|
|
706
285
|
&__buttons {
|
|
707
286
|
display: flex;
|
|
708
287
|
align-items: center;
|
|
288
|
+
height: 100%;
|
|
709
289
|
margin-left: 8px;
|
|
710
|
-
margin-top: 1px;
|
|
711
290
|
&--filters {
|
|
712
291
|
min-width: fit-content;
|
|
713
292
|
border-radius: 3px;
|
|
@@ -729,30 +308,6 @@ export default defineComponent({
|
|
|
729
308
|
&__search-btn-wrapper {
|
|
730
309
|
display: flex;
|
|
731
310
|
align-items: center;
|
|
732
|
-
|
|
733
|
-
::v-deep .dl-button {
|
|
734
|
-
padding: 4px;
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
&__filters-btn-wrapper {
|
|
739
|
-
display: flex;
|
|
740
|
-
align-items: center;
|
|
741
|
-
|
|
742
|
-
::v-deep .dl-button {
|
|
743
|
-
padding: 0;
|
|
744
|
-
font-size: 12px;
|
|
745
|
-
width: 110px;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
&__search-label {
|
|
750
|
-
font-size: 10px;
|
|
751
|
-
margin-left: 4px;
|
|
752
|
-
margin-top: 4px;
|
|
753
|
-
color: gray;
|
|
754
|
-
position: relative;
|
|
755
|
-
word-break: break-all;
|
|
756
311
|
}
|
|
757
312
|
}
|
|
758
313
|
.json-editor__footer {
|