@dataloop-ai/components 0.17.23 → 0.17.25
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/components/compound/DlJsonEditor/DlJsonEditor.vue +37 -220
- package/src/components/compound/DlSearches/DlSmartSearch/DlSmartSearch.vue +210 -32
- package/src/components/compound/DlSearches/DlSmartSearch/utils/utils.ts +8 -1
- package/src/components/compound/index.ts +1 -0
- package/src/components/essential/DlTextArea/DlTextArea.vue +204 -6
- package/src/demos/DlJsonEditorDemo.vue +59 -0
- package/src/demos/DlTextAreaDemo.vue +5 -0
- package/src/demos/index.ts +3 -1
package/package.json
CHANGED
|
@@ -1,196 +1,55 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
>
|
|
7
|
-
<template #header>
|
|
8
|
-
<dl-dialog-box-header
|
|
9
|
-
title="DQL Search"
|
|
10
|
-
:close-button="true"
|
|
11
|
-
style="font-weight: 200"
|
|
12
|
-
@onClose="$emit('update:modelValue', false)"
|
|
13
|
-
/>
|
|
14
|
-
</template>
|
|
15
|
-
<template #body>
|
|
16
|
-
<div class="json-query">
|
|
17
|
-
<div class="json-query-menu">
|
|
18
|
-
<dl-select
|
|
19
|
-
:model-value="selectedOption"
|
|
20
|
-
width="200px"
|
|
21
|
-
:options="selectOptions"
|
|
22
|
-
placeholder="New Query"
|
|
23
|
-
@update:model-value="updateActiveQuery"
|
|
24
|
-
/>
|
|
25
|
-
<dl-button
|
|
26
|
-
icon="icon-dl-align-left"
|
|
27
|
-
label="Align Left"
|
|
28
|
-
flat
|
|
29
|
-
color="secondary"
|
|
30
|
-
@click="alignText"
|
|
31
|
-
/>
|
|
32
|
-
</div>
|
|
33
|
-
<div
|
|
34
|
-
ref="jsonEditorRef"
|
|
35
|
-
class="json-editor"
|
|
36
|
-
/>
|
|
37
|
-
</div>
|
|
38
|
-
</template>
|
|
39
|
-
<template #footer>
|
|
40
|
-
<div class="footer-menu">
|
|
41
|
-
<div class="footer-delete">
|
|
42
|
-
<dl-button
|
|
43
|
-
:disabled="deleteButtonState"
|
|
44
|
-
icon="icon-dl-delete"
|
|
45
|
-
label="Delete Query"
|
|
46
|
-
flat
|
|
47
|
-
color="secondary"
|
|
48
|
-
@click="$emit('remove', activeQuery)"
|
|
49
|
-
/>
|
|
50
|
-
</div>
|
|
51
|
-
<div class="footer-save">
|
|
52
|
-
<dl-button
|
|
53
|
-
outlined
|
|
54
|
-
label="Save As"
|
|
55
|
-
@click="handleSaveButton"
|
|
56
|
-
/>
|
|
57
|
-
<dl-button
|
|
58
|
-
label="Search"
|
|
59
|
-
@click="handleSearchButton"
|
|
60
|
-
/>
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
63
|
-
</template>
|
|
64
|
-
</dl-dialog-box>
|
|
65
|
-
</div>
|
|
2
|
+
<div
|
|
3
|
+
ref="jsonEditorRef"
|
|
4
|
+
class="json-editor"
|
|
5
|
+
/>
|
|
66
6
|
</template>
|
|
67
7
|
|
|
68
8
|
<script lang="ts">
|
|
69
|
-
import { defineComponent
|
|
70
|
-
import { JSONEditor,
|
|
9
|
+
import { defineComponent } from 'vue-demi'
|
|
10
|
+
import { JSONEditor, Mode } from 'vanilla-jsoneditor'
|
|
71
11
|
import { debounce } from 'lodash'
|
|
72
|
-
import { Query } from './types'
|
|
73
|
-
import { DlSelect } from '../DlSelect'
|
|
74
|
-
import { DlButton } from '../../basic'
|
|
75
|
-
import { DlDialogBox, DlDialogBoxHeader } from '../DlDialogBox'
|
|
76
|
-
|
|
77
|
-
interface JSONContent {
|
|
78
|
-
json: JSONValue
|
|
79
|
-
text: string
|
|
80
|
-
}
|
|
81
12
|
|
|
82
13
|
export default defineComponent({
|
|
83
|
-
components: {
|
|
84
|
-
DlDialogBox,
|
|
85
|
-
DlDialogBoxHeader,
|
|
86
|
-
DlSelect,
|
|
87
|
-
DlButton
|
|
88
|
-
},
|
|
89
14
|
props: {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
query: null
|
|
97
|
-
} as Query)
|
|
15
|
+
/**
|
|
16
|
+
* The string to display and modify as JSON
|
|
17
|
+
*/
|
|
18
|
+
modelValue: {
|
|
19
|
+
type: String,
|
|
20
|
+
default: '{}'
|
|
98
21
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
22
|
+
/**
|
|
23
|
+
* When this prop is false, the editor will not refresh, paired with the update-prevent event
|
|
24
|
+
* it helps with controlling when the editor refreshes
|
|
25
|
+
*/
|
|
26
|
+
preventUpdate: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: null
|
|
102
29
|
}
|
|
103
30
|
},
|
|
104
|
-
emits: ['update:modelValue', '
|
|
31
|
+
emits: ['update:modelValue', 'update-prevent', 'align-text'],
|
|
105
32
|
data() {
|
|
106
33
|
return {
|
|
107
|
-
preventOnChange: false,
|
|
108
|
-
preventUpdate: false,
|
|
109
34
|
jsonEditor: {} as JSONEditor,
|
|
110
|
-
|
|
111
|
-
selectedOption: {
|
|
112
|
-
label: this.query?.name,
|
|
113
|
-
value: this.query?.query
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
computed: {
|
|
118
|
-
selectOptions(): Record<string, string>[] {
|
|
119
|
-
return [
|
|
120
|
-
{
|
|
121
|
-
label: 'New Query',
|
|
122
|
-
value: ''
|
|
123
|
-
},
|
|
124
|
-
...this.queries.map((q: Query) => ({
|
|
125
|
-
label: q.name,
|
|
126
|
-
value: q.query
|
|
127
|
-
}))
|
|
128
|
-
]
|
|
129
|
-
},
|
|
130
|
-
deleteButtonState(): boolean {
|
|
131
|
-
return !this.queries.filter(
|
|
132
|
-
(q: Query) => q.name === this.activeQuery?.name
|
|
133
|
-
).length
|
|
35
|
+
preventOnChange: false
|
|
134
36
|
}
|
|
135
37
|
},
|
|
136
38
|
watch: {
|
|
137
|
-
modelValue
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
})
|
|
143
|
-
},
|
|
144
|
-
queries() {
|
|
145
|
-
this.resetEditor()
|
|
146
|
-
},
|
|
147
|
-
activeQuery(val) {
|
|
148
|
-
this.$emit('update-query', val)
|
|
149
|
-
this.jsonEditor?.set({
|
|
150
|
-
text: val.query
|
|
151
|
-
})
|
|
152
|
-
this.selectedOption = {
|
|
153
|
-
label: val.name,
|
|
154
|
-
value: val.query
|
|
39
|
+
modelValue: {
|
|
40
|
+
handler(val) {
|
|
41
|
+
if (this.preventUpdate === false) {
|
|
42
|
+
this.setJsonText(val)
|
|
43
|
+
}
|
|
155
44
|
}
|
|
156
45
|
}
|
|
157
46
|
},
|
|
158
47
|
mounted() {
|
|
159
48
|
this.initJsonEditor()
|
|
49
|
+
this.setJsonText(this.modelValue)
|
|
50
|
+
this.$emit('align-text')
|
|
160
51
|
},
|
|
161
52
|
methods: {
|
|
162
|
-
updateActiveQuery(option: Record<string, string>) {
|
|
163
|
-
this.activeQuery = {
|
|
164
|
-
name: option.label,
|
|
165
|
-
query: option.value
|
|
166
|
-
}
|
|
167
|
-
this.jsonEditor?.destroy()
|
|
168
|
-
this.initJsonEditor()
|
|
169
|
-
},
|
|
170
|
-
alignText() {
|
|
171
|
-
if (!(this.jsonEditor.get && this.jsonEditor.get())) return
|
|
172
|
-
try {
|
|
173
|
-
const parsed = JSON.parse(
|
|
174
|
-
(
|
|
175
|
-
this.jsonEditor.get &&
|
|
176
|
-
(this.jsonEditor?.get() as JSONContent)
|
|
177
|
-
)?.text
|
|
178
|
-
)
|
|
179
|
-
const newText = JSON.stringify(parsed, null, 2)
|
|
180
|
-
this.jsonEditor?.set({ text: newText })
|
|
181
|
-
} catch (error) {}
|
|
182
|
-
},
|
|
183
|
-
resetEditor() {
|
|
184
|
-
if (this.jsonEditor.set) {
|
|
185
|
-
this.jsonEditor.set({
|
|
186
|
-
text: '{}'
|
|
187
|
-
})
|
|
188
|
-
}
|
|
189
|
-
this.selectedOption = {
|
|
190
|
-
label: 'New Query',
|
|
191
|
-
value: ''
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
53
|
initJsonEditor() {
|
|
195
54
|
const initialAttrs: any = {
|
|
196
55
|
onChange: debounce(
|
|
@@ -199,27 +58,17 @@ export default defineComponent({
|
|
|
199
58
|
this.preventOnChange = false
|
|
200
59
|
return
|
|
201
60
|
}
|
|
202
|
-
this.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
: 'New Query',
|
|
206
|
-
query: updatedContent.text
|
|
61
|
+
this.$emit('update:modelValue', updatedContent.text)
|
|
62
|
+
if (this.preventUpdate !== null) {
|
|
63
|
+
this.$emit('update-prevent', true)
|
|
207
64
|
}
|
|
208
|
-
this.preventUpdate = true
|
|
209
65
|
},
|
|
210
66
|
100
|
|
211
67
|
),
|
|
212
68
|
mode: Mode.text,
|
|
213
69
|
mainMenuBar: false,
|
|
214
70
|
navigationBar: false,
|
|
215
|
-
statusBar: false
|
|
216
|
-
...(this.activeQuery !== undefined && {
|
|
217
|
-
content: {
|
|
218
|
-
text: this.activeQuery?.query
|
|
219
|
-
? this.activeQuery.query
|
|
220
|
-
: '{}'
|
|
221
|
-
}
|
|
222
|
-
})
|
|
71
|
+
statusBar: false
|
|
223
72
|
}
|
|
224
73
|
|
|
225
74
|
// There is type instantiation issue with JSONEditor,
|
|
@@ -231,22 +80,11 @@ export default defineComponent({
|
|
|
231
80
|
: document.createElement('div'),
|
|
232
81
|
props: initialAttrs
|
|
233
82
|
})
|
|
234
|
-
this.alignText()
|
|
235
83
|
},
|
|
236
|
-
|
|
237
|
-
this
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
? this.activeQuery
|
|
241
|
-
: {
|
|
242
|
-
name: 'New Query',
|
|
243
|
-
query: (this.jsonEditor?.get() as any).text || ''
|
|
244
|
-
}
|
|
245
|
-
)
|
|
246
|
-
},
|
|
247
|
-
handleSearchButton() {
|
|
248
|
-
this.$emit('search', this.activeQuery)
|
|
249
|
-
this.$emit('update:modelValue', false)
|
|
84
|
+
setJsonText(text: string) {
|
|
85
|
+
this.jsonEditor?.set({
|
|
86
|
+
text
|
|
87
|
+
})
|
|
250
88
|
}
|
|
251
89
|
}
|
|
252
90
|
})
|
|
@@ -260,6 +98,7 @@ export default defineComponent({
|
|
|
260
98
|
--jse-background-color: var(--dl-color-tooltip-text);
|
|
261
99
|
--jse-value-color-boolean: #ae6307;
|
|
262
100
|
--jse-value-color-string: #337433;
|
|
101
|
+
height: 100%;
|
|
263
102
|
.jse-error {
|
|
264
103
|
display: none !important;
|
|
265
104
|
}
|
|
@@ -267,26 +106,4 @@ export default defineComponent({
|
|
|
267
106
|
display: none !important;
|
|
268
107
|
}
|
|
269
108
|
}
|
|
270
|
-
|
|
271
|
-
.json-query-menu {
|
|
272
|
-
display: flex;
|
|
273
|
-
justify-content: space-between;
|
|
274
|
-
align-items: center;
|
|
275
|
-
margin-bottom: 10px;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
.footer-save button {
|
|
279
|
-
margin: 0px 10px;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
.footer-menu {
|
|
283
|
-
width: 100%;
|
|
284
|
-
display: flex;
|
|
285
|
-
justify-content: space-between;
|
|
286
|
-
}
|
|
287
|
-
.footer-save {
|
|
288
|
-
width: 25%;
|
|
289
|
-
display: flex;
|
|
290
|
-
justify-content: space-between;
|
|
291
|
-
}
|
|
292
109
|
</style>
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
class="dl-smart-search__input-wrapper"
|
|
10
10
|
>
|
|
11
11
|
<dl-smart-search-input
|
|
12
|
+
v-show="!jsonEditorModel"
|
|
12
13
|
:status="computedStatus"
|
|
13
14
|
:style-model="defineStyleModel"
|
|
14
15
|
:with-save-button="true"
|
|
@@ -61,16 +62,74 @@
|
|
|
61
62
|
</dl-menu>
|
|
62
63
|
</dl-button>
|
|
63
64
|
</div>
|
|
64
|
-
<dl-
|
|
65
|
-
|
|
66
|
-
:
|
|
67
|
-
:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
<dl-dialog-box
|
|
66
|
+
v-model="jsonEditorModel"
|
|
67
|
+
:height="500"
|
|
68
|
+
:width="800"
|
|
69
|
+
>
|
|
70
|
+
<template #header>
|
|
71
|
+
<dl-dialog-box-header
|
|
72
|
+
title="DQL Search"
|
|
73
|
+
:close-button="true"
|
|
74
|
+
style="font-weight: 200"
|
|
75
|
+
@onClose="handleJsonEditorClose"
|
|
76
|
+
/>
|
|
77
|
+
</template>
|
|
78
|
+
<template #body>
|
|
79
|
+
<div class="json-editor-layout">
|
|
80
|
+
<div class="json-query">
|
|
81
|
+
<div class="json-query-menu">
|
|
82
|
+
<dl-select
|
|
83
|
+
:model-value="selectedOption"
|
|
84
|
+
width="200px"
|
|
85
|
+
:options="selectOptions"
|
|
86
|
+
placeholder="New Query"
|
|
87
|
+
@update:model-value="updateActiveQuery"
|
|
88
|
+
/>
|
|
89
|
+
<dl-button
|
|
90
|
+
icon="icon-dl-align-left"
|
|
91
|
+
label="Align Left"
|
|
92
|
+
flat
|
|
93
|
+
color="secondary"
|
|
94
|
+
@click="alignJsonText"
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
<dl-json-editor
|
|
98
|
+
v-model="jsonEditorQuery"
|
|
99
|
+
:prevent-update="preventUpdate"
|
|
100
|
+
@update-prevent="(val) => (preventUpdate = val)"
|
|
101
|
+
@align-text="alignJsonText"
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
|
106
|
+
<template #footer>
|
|
107
|
+
<div class="json-editor__footer-menu">
|
|
108
|
+
<div class="json-editor__footer-delete">
|
|
109
|
+
<dl-button
|
|
110
|
+
:disabled="deleteButtonState"
|
|
111
|
+
icon="icon-dl-delete"
|
|
112
|
+
label="Delete Query"
|
|
113
|
+
flat
|
|
114
|
+
color="secondary"
|
|
115
|
+
@click="handleQueryRemove"
|
|
116
|
+
/>
|
|
117
|
+
</div>
|
|
118
|
+
<div class="json-editor__footer-save">
|
|
119
|
+
<dl-button
|
|
120
|
+
outlined
|
|
121
|
+
label="Save As"
|
|
122
|
+
@click="saveQueryDialogBoxModel = true"
|
|
123
|
+
/>
|
|
124
|
+
<dl-button
|
|
125
|
+
label="Search"
|
|
126
|
+
@click="handleJsonSearchButton"
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</template>
|
|
131
|
+
</dl-dialog-box>
|
|
132
|
+
|
|
74
133
|
<dl-dialog-box v-model="removeQueryDialogBoxModel">
|
|
75
134
|
<template #header>
|
|
76
135
|
<dl-dialog-box-header
|
|
@@ -133,6 +192,7 @@ import { DlDialogBox, DlDialogBoxHeader } from '../../DlDialogBox'
|
|
|
133
192
|
import { DlInput } from '../../DlInput'
|
|
134
193
|
import { DlTypography, DlMenu } from '../../../essential'
|
|
135
194
|
import { DlButton } from '../../../basic'
|
|
195
|
+
import { DlSelect } from '../../../compound'
|
|
136
196
|
import {
|
|
137
197
|
useSuggestions,
|
|
138
198
|
Schema,
|
|
@@ -141,7 +201,8 @@ import {
|
|
|
141
201
|
} from '../../../../hooks/use-suggestions'
|
|
142
202
|
import { Filters, Query, ColorSchema, SearchStatus } from './types'
|
|
143
203
|
import {
|
|
144
|
-
|
|
204
|
+
replaceWithAliases,
|
|
205
|
+
revertAliases,
|
|
145
206
|
replaceWithJsDates,
|
|
146
207
|
createColorSchema
|
|
147
208
|
} from './utils/utils'
|
|
@@ -158,7 +219,8 @@ export default defineComponent({
|
|
|
158
219
|
DlTypography,
|
|
159
220
|
DlInput,
|
|
160
221
|
DlSmartSearchFilters,
|
|
161
|
-
DlMenu
|
|
222
|
+
DlMenu,
|
|
223
|
+
DlSelect
|
|
162
224
|
},
|
|
163
225
|
props: {
|
|
164
226
|
status: {
|
|
@@ -224,6 +286,13 @@ export default defineComponent({
|
|
|
224
286
|
const isQuerying = ref(false)
|
|
225
287
|
const currentTab = ref('saved')
|
|
226
288
|
const oldInputQuery = ref('')
|
|
289
|
+
const jsonEditorQuery = ref('{}')
|
|
290
|
+
const newQuery = ref('')
|
|
291
|
+
const preventUpdate = ref(false)
|
|
292
|
+
const selectedOption = ref({
|
|
293
|
+
label: 'New Query',
|
|
294
|
+
value: ''
|
|
295
|
+
})
|
|
227
296
|
|
|
228
297
|
const { suggestions, error, findSuggestions } = useSuggestions(
|
|
229
298
|
props.schema,
|
|
@@ -233,7 +302,8 @@ export default defineComponent({
|
|
|
233
302
|
const handleInputModel = (value: string) => {
|
|
234
303
|
inputModel.value = value
|
|
235
304
|
const json = JSON.stringify(toJSON(removeBrackets(value)))
|
|
236
|
-
|
|
305
|
+
const newQuery = replaceWithAliases(json, props.aliases)
|
|
306
|
+
activeQuery.value.query = newQuery
|
|
237
307
|
findSuggestions(value)
|
|
238
308
|
isQuerying.value = false
|
|
239
309
|
oldInputQuery.value = value
|
|
@@ -257,7 +327,6 @@ export default defineComponent({
|
|
|
257
327
|
toJSON(inputModel.value)
|
|
258
328
|
}
|
|
259
329
|
}
|
|
260
|
-
|
|
261
330
|
return {
|
|
262
331
|
uuid: `dl-smart-search-${v4()}`,
|
|
263
332
|
inputModel,
|
|
@@ -274,6 +343,10 @@ export default defineComponent({
|
|
|
274
343
|
currentTab,
|
|
275
344
|
searchBarWidth,
|
|
276
345
|
oldInputQuery,
|
|
346
|
+
jsonEditorQuery,
|
|
347
|
+
newQuery,
|
|
348
|
+
preventUpdate,
|
|
349
|
+
selectedOption,
|
|
277
350
|
handleInputModel,
|
|
278
351
|
setFocused,
|
|
279
352
|
findSuggestions,
|
|
@@ -319,6 +392,43 @@ export default defineComponent({
|
|
|
319
392
|
return this.isQuerying || this.inputModel === ''
|
|
320
393
|
? this.activeQuery.name
|
|
321
394
|
: this.inputModel
|
|
395
|
+
},
|
|
396
|
+
deleteButtonState(): boolean {
|
|
397
|
+
return !this.filters.saved.filter(
|
|
398
|
+
(q: Query) => q.name === this.activeQuery?.name
|
|
399
|
+
).length
|
|
400
|
+
},
|
|
401
|
+
selectOptions(): Record<string, string>[] {
|
|
402
|
+
return [
|
|
403
|
+
{
|
|
404
|
+
label: 'New Query',
|
|
405
|
+
value: '{}'
|
|
406
|
+
},
|
|
407
|
+
...this.filters.saved.map((q: Query) => ({
|
|
408
|
+
label: q.name,
|
|
409
|
+
value: q.query
|
|
410
|
+
}))
|
|
411
|
+
]
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
watch: {
|
|
415
|
+
jsonEditorModel() {
|
|
416
|
+
const json = JSON.stringify(
|
|
417
|
+
this.toJSON(removeBrackets(this.inputModel))
|
|
418
|
+
)
|
|
419
|
+
const newQuery = replaceWithAliases(json, this.aliases)
|
|
420
|
+
if (newQuery && newQuery !== '{}') {
|
|
421
|
+
this.jsonEditorQuery = newQuery
|
|
422
|
+
}
|
|
423
|
+
this.alignJsonText()
|
|
424
|
+
},
|
|
425
|
+
jsonEditorQuery(val) {
|
|
426
|
+
if (
|
|
427
|
+
this.activeQuery.name === 'New Query' ||
|
|
428
|
+
this.activeQuery.name === ''
|
|
429
|
+
) {
|
|
430
|
+
this.newQuery = val
|
|
431
|
+
}
|
|
322
432
|
}
|
|
323
433
|
},
|
|
324
434
|
mounted() {
|
|
@@ -328,35 +438,34 @@ export default defineComponent({
|
|
|
328
438
|
observer.observe(this.$refs.inputWrapper as HTMLElement)
|
|
329
439
|
},
|
|
330
440
|
methods: {
|
|
331
|
-
handleQueryRemove(
|
|
441
|
+
handleQueryRemove() {
|
|
332
442
|
this.filtersModel = false
|
|
333
|
-
this.activeQuery = query
|
|
334
443
|
this.removeQueryDialogBoxModel = true
|
|
335
444
|
},
|
|
336
|
-
handleQuerySearchEditor(query: Query) {
|
|
337
|
-
this.filtersModel = false
|
|
338
|
-
this.activeQuery = query
|
|
339
|
-
this.oldInputQuery = query.query
|
|
340
|
-
this.$emit('search-query', this.activeQuery, this.stringQuery)
|
|
341
|
-
},
|
|
342
445
|
handleSaveQuery(performSearch: boolean) {
|
|
446
|
+
this.activeQuery = {
|
|
447
|
+
name: this.newQueryName || this.activeQuery.name,
|
|
448
|
+
query: this.jsonEditorQuery
|
|
449
|
+
}
|
|
343
450
|
if (performSearch === true) {
|
|
344
451
|
this.emitSaveQuery()
|
|
345
452
|
this.emitSearchQuery()
|
|
453
|
+
const newQuery = revertAliases(
|
|
454
|
+
stringifySmartQuery(JSON.parse(this.activeQuery.query)),
|
|
455
|
+
this.aliases
|
|
456
|
+
)
|
|
457
|
+
this.inputModel = newQuery
|
|
458
|
+
this.oldInputQuery = newQuery
|
|
346
459
|
this.jsonEditorModel = false
|
|
347
460
|
} else {
|
|
348
461
|
this.emitSaveQuery()
|
|
349
462
|
}
|
|
350
463
|
},
|
|
351
|
-
|
|
352
|
-
this.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
this.oldInputQuery = stringQuery
|
|
357
|
-
} catch (error) {
|
|
358
|
-
console.log(error)
|
|
359
|
-
}
|
|
464
|
+
handleJsonSearchButton() {
|
|
465
|
+
this.jsonEditorModel = false
|
|
466
|
+
this.activeQuery.query = this.jsonEditorQuery
|
|
467
|
+
this.setQueryInput()
|
|
468
|
+
this.$emit('search-query', this.activeQuery, this.stringQuery)
|
|
360
469
|
},
|
|
361
470
|
handleFiltersDelete(currentTab: string, query: Query) {
|
|
362
471
|
this.activeQuery = query
|
|
@@ -366,12 +475,19 @@ export default defineComponent({
|
|
|
366
475
|
},
|
|
367
476
|
handleFiltersSelect(currentTab: string, query: Query) {
|
|
368
477
|
this.activeQuery = { ...query }
|
|
369
|
-
const stringQuery =
|
|
478
|
+
const stringQuery = revertAliases(
|
|
479
|
+
stringifySmartQuery(JSON.parse(query.query)),
|
|
480
|
+
this.aliases
|
|
481
|
+
)
|
|
370
482
|
this.oldInputQuery = stringQuery
|
|
371
483
|
this.inputModel = stringQuery
|
|
372
484
|
this.currentTab = currentTab
|
|
373
485
|
this.filtersModel = false
|
|
374
486
|
},
|
|
487
|
+
handleJsonEditorClose() {
|
|
488
|
+
this.jsonEditorModel = false
|
|
489
|
+
this.newQuery = ''
|
|
490
|
+
},
|
|
375
491
|
emitSearchQuery() {
|
|
376
492
|
this.$emit('search-query', this.activeQuery, this.stringQuery)
|
|
377
493
|
},
|
|
@@ -383,6 +499,12 @@ export default defineComponent({
|
|
|
383
499
|
this.currentTab,
|
|
384
500
|
this.inputModel
|
|
385
501
|
)
|
|
502
|
+
this.selectedOption = {
|
|
503
|
+
label: 'New Query',
|
|
504
|
+
value: '{}'
|
|
505
|
+
}
|
|
506
|
+
this.activeQuery.query = this.newQuery
|
|
507
|
+
this.jsonEditorQuery = this.newQuery || '{}'
|
|
386
508
|
this.removeQueryDialogBoxModel = false
|
|
387
509
|
},
|
|
388
510
|
emitSaveQuery() {
|
|
@@ -392,6 +514,40 @@ export default defineComponent({
|
|
|
392
514
|
this.$emit('save-query', { ...this.activeQuery }, this.currentTab)
|
|
393
515
|
this.saveQueryDialogBoxModel = false
|
|
394
516
|
this.newQueryName = ''
|
|
517
|
+
},
|
|
518
|
+
setQueryInput(query?: string) {
|
|
519
|
+
const stringQuery = revertAliases(
|
|
520
|
+
stringifySmartQuery(
|
|
521
|
+
JSON.parse(query || this.activeQuery.query)
|
|
522
|
+
),
|
|
523
|
+
this.aliases
|
|
524
|
+
)
|
|
525
|
+
this.inputModel = stringQuery
|
|
526
|
+
this.oldInputQuery = stringQuery
|
|
527
|
+
},
|
|
528
|
+
updateActiveQuery(option: Record<string, string>) {
|
|
529
|
+
this.preventUpdate = true
|
|
530
|
+
const isNewQuery =
|
|
531
|
+
option.label === 'New Query' || option.label === ''
|
|
532
|
+
this.activeQuery = {
|
|
533
|
+
name: option.label,
|
|
534
|
+
query: isNewQuery ? this.newQuery : this.activeQuery.query
|
|
535
|
+
}
|
|
536
|
+
this.preventUpdate = false
|
|
537
|
+
this.jsonEditorQuery = isNewQuery
|
|
538
|
+
? this.newQuery || '{}'
|
|
539
|
+
: option.value
|
|
540
|
+
this.alignJsonText()
|
|
541
|
+
},
|
|
542
|
+
alignJsonText() {
|
|
543
|
+
try {
|
|
544
|
+
this.preventUpdate = false
|
|
545
|
+
this.jsonEditorQuery = JSON.stringify(
|
|
546
|
+
JSON.parse(this.jsonEditorQuery),
|
|
547
|
+
null,
|
|
548
|
+
2
|
|
549
|
+
)
|
|
550
|
+
} catch (err) {}
|
|
395
551
|
}
|
|
396
552
|
}
|
|
397
553
|
})
|
|
@@ -465,4 +621,26 @@ export default defineComponent({
|
|
|
465
621
|
word-break: break-all;
|
|
466
622
|
}
|
|
467
623
|
}
|
|
624
|
+
.json-editor__footer {
|
|
625
|
+
&-menu {
|
|
626
|
+
width: 100%;
|
|
627
|
+
display: flex;
|
|
628
|
+
justify-content: space-between;
|
|
629
|
+
}
|
|
630
|
+
&-save > * {
|
|
631
|
+
margin: 0px 10px;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
.json-query {
|
|
635
|
+
height: 100%;
|
|
636
|
+
}
|
|
637
|
+
.json-editor-layout {
|
|
638
|
+
height: 90%;
|
|
639
|
+
}
|
|
640
|
+
.json-query-menu {
|
|
641
|
+
display: flex;
|
|
642
|
+
justify-content: space-between;
|
|
643
|
+
align-items: center;
|
|
644
|
+
margin-bottom: 10px;
|
|
645
|
+
}
|
|
468
646
|
</style>
|
|
@@ -62,13 +62,20 @@ function isValidDate(d: Date) {
|
|
|
62
62
|
return d instanceof Date && !isNaN(d as any)
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
export function
|
|
65
|
+
export function replaceWithAliases(json: string, aliases: Alias[]) {
|
|
66
66
|
let newJson = json
|
|
67
67
|
aliases.forEach((alias) => {
|
|
68
68
|
newJson = newJson.replaceAll(alias.alias, alias.key)
|
|
69
69
|
})
|
|
70
70
|
return newJson
|
|
71
71
|
}
|
|
72
|
+
export function revertAliases(json: string, aliases: Alias[]) {
|
|
73
|
+
let newJson = json
|
|
74
|
+
aliases.forEach((alias) => {
|
|
75
|
+
newJson = newJson.replaceAll(alias.key, alias.alias)
|
|
76
|
+
})
|
|
77
|
+
return newJson
|
|
78
|
+
}
|
|
72
79
|
|
|
73
80
|
export function createColorSchema(
|
|
74
81
|
colorSchema: ColorSchema,
|
|
@@ -2,8 +2,62 @@
|
|
|
2
2
|
<div
|
|
3
3
|
:id="uuid"
|
|
4
4
|
class="container"
|
|
5
|
+
:class="rootContainerClasses"
|
|
5
6
|
:style="cssVars"
|
|
6
7
|
>
|
|
8
|
+
<div class="dl-textarea__header">
|
|
9
|
+
<div
|
|
10
|
+
v-show="!!title.length || !!tooltip.length"
|
|
11
|
+
class="dl-textarea__title-container"
|
|
12
|
+
>
|
|
13
|
+
<label
|
|
14
|
+
v-show="!!title.length"
|
|
15
|
+
class="dl-textarea__title"
|
|
16
|
+
>
|
|
17
|
+
{{ title }}
|
|
18
|
+
<span
|
|
19
|
+
v-show="required"
|
|
20
|
+
:class="asteriskClasses"
|
|
21
|
+
> *</span>
|
|
22
|
+
{{ !required && optional ? ' (Optional)' : null }}
|
|
23
|
+
</label>
|
|
24
|
+
<span v-show="!!tooltip.length">
|
|
25
|
+
<dl-icon
|
|
26
|
+
class="dl-textarea__tooltip-icon"
|
|
27
|
+
icon="icon-dl-info"
|
|
28
|
+
size="12px"
|
|
29
|
+
/>
|
|
30
|
+
<dl-tooltip>
|
|
31
|
+
{{ tooltip }}
|
|
32
|
+
</dl-tooltip>
|
|
33
|
+
</span>
|
|
34
|
+
</div>
|
|
35
|
+
<div
|
|
36
|
+
v-show="!!topMessage.length"
|
|
37
|
+
class="dl-textarea__top-message-container"
|
|
38
|
+
>
|
|
39
|
+
<dl-info-error-message
|
|
40
|
+
v-show="!!topMessage.length"
|
|
41
|
+
position="above"
|
|
42
|
+
:value="topMessage"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
<span
|
|
46
|
+
v-show="showClearButton"
|
|
47
|
+
class="dl-textarea__clear-button"
|
|
48
|
+
>
|
|
49
|
+
<dl-button
|
|
50
|
+
ref="input-clear-button"
|
|
51
|
+
icon="icon-dl-close"
|
|
52
|
+
size="s"
|
|
53
|
+
text-color="dl-color-darker"
|
|
54
|
+
flat
|
|
55
|
+
fluid
|
|
56
|
+
@click="onClear"
|
|
57
|
+
/>
|
|
58
|
+
<dl-tooltip v-if="clearButtonTooltip"> Remove text </dl-tooltip>
|
|
59
|
+
</span>
|
|
60
|
+
</div>
|
|
7
61
|
<textarea
|
|
8
62
|
ref="textarea"
|
|
9
63
|
:value="modelValue"
|
|
@@ -11,6 +65,7 @@
|
|
|
11
65
|
:placeholder="placeholder"
|
|
12
66
|
:maxlength="maxLength"
|
|
13
67
|
:disabled="disabled"
|
|
68
|
+
:readonly="readonly"
|
|
14
69
|
@input="onChange"
|
|
15
70
|
@keydown="onKeydown"
|
|
16
71
|
@focus="onFocus"
|
|
@@ -42,9 +97,11 @@
|
|
|
42
97
|
warning
|
|
43
98
|
:value="warningMessage"
|
|
44
99
|
/>
|
|
45
|
-
<span
|
|
46
|
-
|
|
47
|
-
|
|
100
|
+
<span
|
|
101
|
+
v-if="showCounter && maxLength && maxLength > 0"
|
|
102
|
+
class="dl-text-input__counter"
|
|
103
|
+
>
|
|
104
|
+
{{ characterCounter }}
|
|
48
105
|
</span>
|
|
49
106
|
</div>
|
|
50
107
|
</div>
|
|
@@ -55,10 +112,15 @@ import { v4 } from 'uuid'
|
|
|
55
112
|
import { DlInfoErrorMessage } from '../../shared'
|
|
56
113
|
import { defineComponent, computed, ref } from 'vue-demi'
|
|
57
114
|
import { useSizeObserver } from '../../../hooks/use-size-observer'
|
|
115
|
+
import { DlIcon, DlTooltip } from '../'
|
|
116
|
+
import DlButton from '../../basic/DlButton/DlButton.vue'
|
|
58
117
|
|
|
59
118
|
export default defineComponent({
|
|
60
119
|
name: 'DlTextArea',
|
|
61
120
|
components: {
|
|
121
|
+
DlButton,
|
|
122
|
+
DlTooltip,
|
|
123
|
+
DlIcon,
|
|
62
124
|
DlInfoErrorMessage
|
|
63
125
|
},
|
|
64
126
|
model: {
|
|
@@ -113,9 +175,50 @@ export default defineComponent({
|
|
|
113
175
|
warning: {
|
|
114
176
|
type: Boolean,
|
|
115
177
|
default: false
|
|
178
|
+
},
|
|
179
|
+
required: {
|
|
180
|
+
type: Boolean,
|
|
181
|
+
default: false
|
|
182
|
+
},
|
|
183
|
+
tooltip: {
|
|
184
|
+
type: String,
|
|
185
|
+
default: ''
|
|
186
|
+
},
|
|
187
|
+
optional: {
|
|
188
|
+
type: Boolean,
|
|
189
|
+
default: false
|
|
190
|
+
},
|
|
191
|
+
title: {
|
|
192
|
+
type: String,
|
|
193
|
+
default: ''
|
|
194
|
+
},
|
|
195
|
+
topMessage: {
|
|
196
|
+
type: String,
|
|
197
|
+
default: ''
|
|
198
|
+
},
|
|
199
|
+
hideClearButton: {
|
|
200
|
+
type: Boolean,
|
|
201
|
+
default: false
|
|
202
|
+
},
|
|
203
|
+
clearButtonTooltip: {
|
|
204
|
+
type: Boolean,
|
|
205
|
+
default: false
|
|
206
|
+
},
|
|
207
|
+
dense: Boolean,
|
|
208
|
+
redAsterisk: {
|
|
209
|
+
type: Boolean,
|
|
210
|
+
default: false
|
|
211
|
+
},
|
|
212
|
+
readonly: {
|
|
213
|
+
type: Boolean,
|
|
214
|
+
default: false
|
|
215
|
+
},
|
|
216
|
+
counterReverse: {
|
|
217
|
+
type: Boolean,
|
|
218
|
+
default: false
|
|
116
219
|
}
|
|
117
220
|
},
|
|
118
|
-
emits: ['input', 'focus', 'blur', 'update:model-value', 'keydown'],
|
|
221
|
+
emits: ['input', 'focus', 'blur', 'clear', 'update:model-value', 'keydown'],
|
|
119
222
|
setup(props) {
|
|
120
223
|
const uuid = ref(`dl-text-area-${v4()}`)
|
|
121
224
|
const textarea = ref(null)
|
|
@@ -161,7 +264,56 @@ export default defineComponent({
|
|
|
161
264
|
textarea
|
|
162
265
|
}
|
|
163
266
|
},
|
|
267
|
+
computed: {
|
|
268
|
+
showClearButton(): boolean {
|
|
269
|
+
return (
|
|
270
|
+
!this.hideClearButton &&
|
|
271
|
+
!this.disabled &&
|
|
272
|
+
!this.readonly &&
|
|
273
|
+
!!this.modelValue
|
|
274
|
+
)
|
|
275
|
+
},
|
|
276
|
+
asteriskClasses(): string[] {
|
|
277
|
+
const classes = ['dl-textarea__asterisk']
|
|
278
|
+
|
|
279
|
+
if (this.redAsterisk) {
|
|
280
|
+
classes.push('dl-textarea__asterisk--red')
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return classes
|
|
284
|
+
},
|
|
285
|
+
rootContainerClasses(): string[] {
|
|
286
|
+
const classes = []
|
|
287
|
+
if (this.dense) {
|
|
288
|
+
classes.push('dl-textarea--dense')
|
|
289
|
+
}
|
|
290
|
+
return classes
|
|
291
|
+
},
|
|
292
|
+
textareaLength(): number {
|
|
293
|
+
return `${this.modelValue}`.length
|
|
294
|
+
},
|
|
295
|
+
characterCounter(): string {
|
|
296
|
+
if (!this.maxLength) {
|
|
297
|
+
return ''
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const chars = this.counterReverse
|
|
301
|
+
? this.maxLength - this.textareaLength
|
|
302
|
+
: this.textareaLength
|
|
303
|
+
|
|
304
|
+
return `${chars}/${this.maxLength}`
|
|
305
|
+
}
|
|
306
|
+
},
|
|
164
307
|
methods: {
|
|
308
|
+
onClear(e: any): void {
|
|
309
|
+
this.$emit('clear', this.modelValue)
|
|
310
|
+
this.$emit('input', '', e)
|
|
311
|
+
this.$emit('update:model-value', '')
|
|
312
|
+
|
|
313
|
+
const inputRef = this.$refs.textarea as HTMLInputElement
|
|
314
|
+
inputRef.value = ''
|
|
315
|
+
inputRef.focus()
|
|
316
|
+
},
|
|
165
317
|
onChange(e: any) {
|
|
166
318
|
this.$emit('input', e.target.value, e)
|
|
167
319
|
this.$emit('update:model-value', e.target.value)
|
|
@@ -211,7 +363,47 @@ export default defineComponent({
|
|
|
211
363
|
outline: none;
|
|
212
364
|
color: var(--dl-color-darker);
|
|
213
365
|
box-sizing: border-box;
|
|
214
|
-
|
|
366
|
+
&--dense {
|
|
367
|
+
padding: 0;
|
|
368
|
+
}
|
|
369
|
+
&__asterisk {
|
|
370
|
+
color: var(--dl-color-medium);
|
|
371
|
+
font-size: var(--dl-font-size-body);
|
|
372
|
+
user-select: none;
|
|
373
|
+
&--red {
|
|
374
|
+
color: var(--dl-color-negative);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
&__clear-button {
|
|
378
|
+
position: absolute;
|
|
379
|
+
bottom: -25px;
|
|
380
|
+
right: 0;
|
|
381
|
+
}
|
|
382
|
+
&__header {
|
|
383
|
+
position: relative;
|
|
384
|
+
width: var(--dl-textarea-width);
|
|
385
|
+
}
|
|
386
|
+
&__title-container {
|
|
387
|
+
margin-bottom: 6px;
|
|
388
|
+
display: flex;
|
|
389
|
+
align-items: center;
|
|
390
|
+
text-align: start;
|
|
391
|
+
}
|
|
392
|
+
&__title {
|
|
393
|
+
color: var(--dl-color-medium);
|
|
394
|
+
font-size: var(--dl-font-size-body);
|
|
395
|
+
text-align: left;
|
|
396
|
+
margin-right: 5px;
|
|
397
|
+
white-space: nowrap;
|
|
398
|
+
}
|
|
399
|
+
&__tooltip-icon {
|
|
400
|
+
color: var(--dl-color-medium);
|
|
401
|
+
}
|
|
402
|
+
&__top-message-container {
|
|
403
|
+
display: flex;
|
|
404
|
+
margin-bottom: 10px;
|
|
405
|
+
text-align: start;
|
|
406
|
+
}
|
|
215
407
|
&:hover {
|
|
216
408
|
border-color: var(--dl-color-hover);
|
|
217
409
|
}
|
|
@@ -226,7 +418,13 @@ export default defineComponent({
|
|
|
226
418
|
cursor: not-allowed;
|
|
227
419
|
user-select: none;
|
|
228
420
|
}
|
|
229
|
-
|
|
421
|
+
&:readonly {
|
|
422
|
+
border-color: var(--dl-color-separator);
|
|
423
|
+
cursor: text;
|
|
424
|
+
&:hover {
|
|
425
|
+
border-color: var(--dl-color-separator) !important;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
230
428
|
&::placeholder {
|
|
231
429
|
color: var(--dl-color-lighter);
|
|
232
430
|
opacity: 1;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
style="
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
"
|
|
8
|
+
>
|
|
9
|
+
<div style="height: 200px; width: 500px">
|
|
10
|
+
<dl-json-editor v-model="jsonModel" />
|
|
11
|
+
</div>
|
|
12
|
+
<span>JSON: {{ jsonModel }}</span>
|
|
13
|
+
|
|
14
|
+
<dl-button @click="dialogState = !dialogState">
|
|
15
|
+
JsonEditor
|
|
16
|
+
</dl-button>
|
|
17
|
+
<dl-dialog-box
|
|
18
|
+
v-model="dialogState"
|
|
19
|
+
volatile
|
|
20
|
+
:width="700"
|
|
21
|
+
>
|
|
22
|
+
<template #header>
|
|
23
|
+
<dl-dialog-box-header
|
|
24
|
+
title="JsonEditor"
|
|
25
|
+
@onClose="dialogState = false"
|
|
26
|
+
/>
|
|
27
|
+
</template>
|
|
28
|
+
<template #body>
|
|
29
|
+
<div style="height: 200px">
|
|
30
|
+
<dl-json-editor v-model="dialogJsonModel" />
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
</dl-dialog-box>
|
|
34
|
+
<span>Dialog JSON: {{ dialogJsonModel }}</span>
|
|
35
|
+
</div>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<script lang="ts">
|
|
39
|
+
import { defineComponent, ref } from 'vue-demi'
|
|
40
|
+
import {
|
|
41
|
+
DlJsonEditor,
|
|
42
|
+
DlDialogBox,
|
|
43
|
+
DlDialogBoxHeader,
|
|
44
|
+
DlButton
|
|
45
|
+
} from '../components'
|
|
46
|
+
export default defineComponent({
|
|
47
|
+
components: { DlJsonEditor, DlDialogBox, DlDialogBoxHeader, DlButton },
|
|
48
|
+
setup() {
|
|
49
|
+
const jsonModel = ref('')
|
|
50
|
+
const dialogJsonModel = ref('')
|
|
51
|
+
const dialogState = ref(false)
|
|
52
|
+
return {
|
|
53
|
+
jsonModel,
|
|
54
|
+
dialogState,
|
|
55
|
+
dialogJsonModel
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
</script>
|
|
@@ -6,8 +6,13 @@
|
|
|
6
6
|
placeholder="Type your text..."
|
|
7
7
|
show-counter
|
|
8
8
|
:max-length="20"
|
|
9
|
+
title="Text area title"
|
|
10
|
+
required
|
|
11
|
+
tooltip="Quis fugiat et non eu proident sit et amet."
|
|
12
|
+
top-message="Pariatur consequat non sit aliqua labore ad reprehenderit deserunt ullamco incididunt non irure laborum deserunt."
|
|
9
13
|
enable-resize
|
|
10
14
|
error
|
|
15
|
+
clear-button-tooltip
|
|
11
16
|
error-message="Something went wrong!"
|
|
12
17
|
@keydown="log"
|
|
13
18
|
@focus="textAreaFocused = true"
|
package/src/demos/index.ts
CHANGED
|
@@ -55,6 +55,7 @@ import DlSeparatorDemo from './DlSeparatorDemo.vue'
|
|
|
55
55
|
import DlCardDemo from './DlCardDemo.vue'
|
|
56
56
|
import DlMarkupTableDemo from './DlMarkupTableDemo.vue'
|
|
57
57
|
import DlVirtualScrollDemo from './DlVirtualScrollDemo.vue'
|
|
58
|
+
import DlJsonEditorDemo from './DlJsonEditorDemo.vue'
|
|
58
59
|
|
|
59
60
|
export default {
|
|
60
61
|
AvatarDemo,
|
|
@@ -113,5 +114,6 @@ export default {
|
|
|
113
114
|
DlKpiDemo,
|
|
114
115
|
DlCardDemo,
|
|
115
116
|
DlMarkupTableDemo,
|
|
116
|
-
DlVirtualScrollDemo
|
|
117
|
+
DlVirtualScrollDemo,
|
|
118
|
+
DlJsonEditorDemo
|
|
117
119
|
}
|