@necrolab/dashboard 0.5.17 → 0.5.18
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,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="admin-editor-section" :class="{ 'landscape-hidden': isHidden }">
|
|
2
|
+
<div class="admin-editor-section" :class="{ 'landscape-hidden': isHidden }" v-if="!isHidden">
|
|
3
3
|
<h5 class="text-white text-xl font-bold flex gap-x-3 mb-3">Admin Editor</h5>
|
|
4
|
-
<div class="flex
|
|
5
|
-
<div class="unified-search-group flex
|
|
4
|
+
<div class="flex items-center gap-2 w-full">
|
|
5
|
+
<div class="unified-search-group flex flex-1 dropdown-container z-dropdown-high lg:flex-initial lg:min-w-64">
|
|
6
6
|
<Dropdown
|
|
7
7
|
class="admin-file-dropdown flex-1"
|
|
8
8
|
default="Select a file"
|
|
@@ -12,15 +12,16 @@
|
|
|
12
12
|
:includeAdjacentButtons="true"
|
|
13
13
|
rightAmount="right-1" />
|
|
14
14
|
<button
|
|
15
|
-
class="refresh-button flex items-center justify-center w-9 h-10 flex-shrink-0 text-white bg-dark-400
|
|
15
|
+
class="refresh-button flex items-center justify-center w-9 h-10 flex-shrink-0 text-white bg-dark-400 hover:bg-dark-450"
|
|
16
|
+
style="transition: all 0.2s ease"
|
|
16
17
|
@click="$emit('refresh-files')"
|
|
17
18
|
title="Refresh file list">
|
|
18
19
|
<ReloadIcon class="refresh-icon icon-md" />
|
|
19
20
|
</button>
|
|
20
21
|
</div>
|
|
21
|
-
<div v-if="isEditorVisible" class="flex gap-
|
|
22
|
+
<div v-if="isEditorVisible" class="flex gap-2 flex-shrink-0">
|
|
22
23
|
<button
|
|
23
|
-
class="
|
|
24
|
+
class="editor-action-btn"
|
|
24
25
|
@click="$emit('format')"
|
|
25
26
|
v-if="isJsonFile"
|
|
26
27
|
title="Format JSON">
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
<path d="M21 18H7" />
|
|
41
42
|
</svg>
|
|
42
43
|
</button>
|
|
43
|
-
<button class="
|
|
44
|
+
<button class="editor-action-btn" @click="$emit('save')" title="Save File">
|
|
44
45
|
<svg
|
|
45
46
|
xmlns="http://www.w3.org/2000/svg"
|
|
46
47
|
width="16"
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
<polyline points="7 3 7 8 15 8" />
|
|
57
58
|
</svg>
|
|
58
59
|
</button>
|
|
59
|
-
<button class="
|
|
60
|
+
<button class="editor-action-btn" @click="$emit('close')" title="Close File">
|
|
60
61
|
<svg
|
|
61
62
|
xmlns="http://www.w3.org/2000/svg"
|
|
62
63
|
width="16"
|
|
@@ -75,9 +76,9 @@
|
|
|
75
76
|
</div>
|
|
76
77
|
|
|
77
78
|
<transition name="fade">
|
|
78
|
-
<div v-if="isEditorVisible" class="my-3 relative">
|
|
79
|
-
<div class="
|
|
80
|
-
<div class="editor-container overflow-hidden rounded-lg shadow-card bg-dark-350" :class="{ 'has-error': errorMessage }">
|
|
79
|
+
<div v-if="isEditorVisible" class="my-3 relative editor-wrapper">
|
|
80
|
+
<div :class="{ 'has-error-padding': errorMessage }">
|
|
81
|
+
<div class="editor-container overflow-hidden rounded-lg shadow-card bg-dark-350" :class="{ 'has-error': errorMessage, 'with-error-msg': errorMessage }">
|
|
81
82
|
<div class="relative w-full h-full">
|
|
82
83
|
<pre ref="codeDisplay" class="code-highlight language-json"></pre>
|
|
83
84
|
<textarea
|
|
@@ -91,7 +92,6 @@
|
|
|
91
92
|
</div>
|
|
92
93
|
</div>
|
|
93
94
|
</div>
|
|
94
|
-
|
|
95
95
|
<div v-if="errorMessage" class="error-container">
|
|
96
96
|
<div class="error-icon">
|
|
97
97
|
<svg
|
|
@@ -177,3 +177,245 @@ onMounted(() => {
|
|
|
177
177
|
}
|
|
178
178
|
});
|
|
179
179
|
</script>
|
|
180
|
+
|
|
181
|
+
<style scoped>
|
|
182
|
+
.editor-action-btn {
|
|
183
|
+
@apply flex items-center justify-center w-9 h-9 rounded border-2 border-dark-550 bg-dark-400 text-white;
|
|
184
|
+
transition: all 0.2s ease;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.editor-action-btn:hover {
|
|
188
|
+
@apply bg-dark-450 border-dark-625;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.editor-action-btn svg {
|
|
192
|
+
@apply w-4 h-4;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.editor-wrapper {
|
|
196
|
+
max-height: calc(100vh - 380px);
|
|
197
|
+
overflow: visible;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.editor-container {
|
|
201
|
+
position: relative;
|
|
202
|
+
height: calc(100vh - 380px);
|
|
203
|
+
min-height: 300px;
|
|
204
|
+
max-height: calc(100vh - 380px);
|
|
205
|
+
border: 2px solid var(--color-border);
|
|
206
|
+
overflow: hidden;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.editor-container.has-error {
|
|
210
|
+
border-color: oklch(0.6 0.19 29);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.editor-container.with-error-msg {
|
|
214
|
+
height: calc(100vh - 520px);
|
|
215
|
+
max-height: calc(100vh - 520px);
|
|
216
|
+
min-height: 200px;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.code-highlight,
|
|
220
|
+
.code-editor {
|
|
221
|
+
position: absolute;
|
|
222
|
+
top: 0;
|
|
223
|
+
left: 0;
|
|
224
|
+
right: 0;
|
|
225
|
+
bottom: 0;
|
|
226
|
+
width: 100%;
|
|
227
|
+
height: 100%;
|
|
228
|
+
margin: 0;
|
|
229
|
+
padding: 1rem;
|
|
230
|
+
font-family: 'Courier New', Courier, monospace;
|
|
231
|
+
font-size: 14px;
|
|
232
|
+
line-height: 1.6;
|
|
233
|
+
white-space: pre;
|
|
234
|
+
word-wrap: normal;
|
|
235
|
+
overflow-wrap: normal;
|
|
236
|
+
tab-size: 4;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.code-highlight {
|
|
240
|
+
overflow: auto;
|
|
241
|
+
pointer-events: none;
|
|
242
|
+
background: transparent;
|
|
243
|
+
caret-color: transparent;
|
|
244
|
+
z-index: 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* Enhanced syntax highlighting - SUPER BRIGHT for dark background */
|
|
248
|
+
.code-highlight :deep(.token.property),
|
|
249
|
+
.code-highlight :deep(.token.tag),
|
|
250
|
+
.code-highlight :deep(.token.boolean),
|
|
251
|
+
.code-highlight :deep(.token.number),
|
|
252
|
+
.code-highlight :deep(.token.constant),
|
|
253
|
+
.code-highlight :deep(.token.symbol),
|
|
254
|
+
.code-highlight :deep(.token.deleted) {
|
|
255
|
+
color: #ff6b9d !important;
|
|
256
|
+
font-weight: 500;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.code-highlight :deep(.token.selector),
|
|
260
|
+
.code-highlight :deep(.token.attr-name),
|
|
261
|
+
.code-highlight :deep(.token.string),
|
|
262
|
+
.code-highlight :deep(.token.char),
|
|
263
|
+
.code-highlight :deep(.token.builtin),
|
|
264
|
+
.code-highlight :deep(.token.inserted) {
|
|
265
|
+
color: #7ee8fa !important;
|
|
266
|
+
font-weight: 500;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.code-highlight :deep(.token.operator),
|
|
270
|
+
.code-highlight :deep(.token.entity),
|
|
271
|
+
.code-highlight :deep(.token.url),
|
|
272
|
+
.code-highlight :deep(.language-css .token.string),
|
|
273
|
+
.code-highlight :deep(.style .token.string) {
|
|
274
|
+
color: #5bc0eb !important;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.code-highlight :deep(.token.atrule),
|
|
278
|
+
.code-highlight :deep(.token.attr-value),
|
|
279
|
+
.code-highlight :deep(.token.keyword) {
|
|
280
|
+
color: #ffa657 !important;
|
|
281
|
+
font-weight: 600;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.code-highlight :deep(.token.function),
|
|
285
|
+
.code-highlight :deep(.token.class-name) {
|
|
286
|
+
color: #d4a5ff !important;
|
|
287
|
+
font-weight: 600;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.code-highlight :deep(.token.regex),
|
|
291
|
+
.code-highlight :deep(.token.important),
|
|
292
|
+
.code-highlight :deep(.token.variable) {
|
|
293
|
+
color: #ffc777 !important;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.code-highlight :deep(.token.punctuation) {
|
|
297
|
+
color: #c8d3f5 !important;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.code-editor {
|
|
301
|
+
background: transparent;
|
|
302
|
+
color: transparent;
|
|
303
|
+
border: none;
|
|
304
|
+
outline: none;
|
|
305
|
+
resize: none;
|
|
306
|
+
overflow: auto;
|
|
307
|
+
z-index: 1;
|
|
308
|
+
caret-color: #ffc777;
|
|
309
|
+
-webkit-text-fill-color: transparent;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.code-editor::selection {
|
|
313
|
+
background: oklch(0.5 0.15 250 / 0.5);
|
|
314
|
+
color: #fff;
|
|
315
|
+
-webkit-text-fill-color: #fff;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.error-container {
|
|
319
|
+
@apply mt-2 p-3 rounded-lg border-2 flex gap-3 items-start;
|
|
320
|
+
background: oklch(0.25 0.02 29);
|
|
321
|
+
border-color: oklch(0.5 0.15 29);
|
|
322
|
+
max-width: 100%;
|
|
323
|
+
word-wrap: break-word;
|
|
324
|
+
overflow-wrap: break-word;
|
|
325
|
+
max-height: 120px;
|
|
326
|
+
overflow-y: auto;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.error-icon {
|
|
330
|
+
@apply flex-shrink-0 text-error-400;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.error-content {
|
|
334
|
+
@apply flex-1;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.error-title {
|
|
338
|
+
@apply text-sm font-semibold text-error-300 mb-1;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.error-text {
|
|
342
|
+
@apply text-xs text-error-300;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* Tablet adjustments */
|
|
346
|
+
@media (max-width: 1024px) {
|
|
347
|
+
.editor-wrapper {
|
|
348
|
+
max-height: calc(100vh - 350px);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.editor-container {
|
|
352
|
+
height: calc(100vh - 350px);
|
|
353
|
+
max-height: calc(100vh - 350px);
|
|
354
|
+
min-height: 280px;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.editor-container.with-error-msg {
|
|
358
|
+
height: calc(100vh - 480px);
|
|
359
|
+
max-height: calc(100vh - 480px);
|
|
360
|
+
min-height: 180px;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/* Mobile adjustments */
|
|
365
|
+
@media (max-width: 768px) {
|
|
366
|
+
.editor-wrapper {
|
|
367
|
+
max-height: calc(100vh - 320px);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.editor-container {
|
|
371
|
+
height: calc(100vh - 320px);
|
|
372
|
+
max-height: calc(100vh - 320px);
|
|
373
|
+
min-height: 250px;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.editor-container.with-error-msg {
|
|
377
|
+
height: calc(100vh - 440px);
|
|
378
|
+
max-height: calc(100vh - 440px);
|
|
379
|
+
min-height: 150px;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.code-highlight,
|
|
383
|
+
.code-editor {
|
|
384
|
+
font-size: 13px;
|
|
385
|
+
padding: 0.75rem;
|
|
386
|
+
line-height: 1.5;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.error-container {
|
|
390
|
+
max-height: 100px;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
@media (max-width: 480px) {
|
|
395
|
+
.editor-wrapper {
|
|
396
|
+
max-height: calc(100vh - 300px);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.editor-container {
|
|
400
|
+
height: calc(100vh - 300px);
|
|
401
|
+
max-height: calc(100vh - 300px);
|
|
402
|
+
min-height: 200px;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.editor-container.with-error-msg {
|
|
406
|
+
height: calc(100vh - 400px);
|
|
407
|
+
max-height: calc(100vh - 400px);
|
|
408
|
+
min-height: 120px;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.code-highlight,
|
|
412
|
+
.code-editor {
|
|
413
|
+
font-size: 12px;
|
|
414
|
+
padding: 0.5rem;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.error-container {
|
|
418
|
+
max-height: 80px;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
</style>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="proxy-editor-section" :class="{ 'landscape-hidden': isHidden }">
|
|
2
|
+
<div class="proxy-editor-section" :class="{ 'landscape-hidden': isHidden }" v-if="!isHidden">
|
|
3
3
|
<h5 class="text-white text-xl font-bold flex gap-x-3 mb-3">Proxy Editor</h5>
|
|
4
|
-
<div class="flex
|
|
5
|
-
<div class="
|
|
4
|
+
<div class="flex items-center gap-2 w-full mb-1">
|
|
5
|
+
<div class="flex-1 lg:flex-initial lg:w-64 flex dropdown-container z-dropdown">
|
|
6
6
|
<div class="relative flex-grow">
|
|
7
7
|
<Dropdown
|
|
8
8
|
class="bg-dark-500 border-2 border-dark-550 proxy-file-dropdown w-full"
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
rightAmount="right-1" />
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
17
|
-
<div v-if="isProxyEditorVisible" class="flex gap-
|
|
18
|
-
<button class="
|
|
17
|
+
<div v-if="isProxyEditorVisible" class="flex gap-2 flex-shrink-0">
|
|
18
|
+
<button class="editor-action-btn" @click="$emit('save-proxies')" title="Save Proxies">
|
|
19
19
|
<svg
|
|
20
20
|
xmlns="http://www.w3.org/2000/svg"
|
|
21
21
|
width="16"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<polyline points="7 3 7 8 15 8" />
|
|
32
32
|
</svg>
|
|
33
33
|
</button>
|
|
34
|
-
<button class="
|
|
34
|
+
<button class="editor-action-btn" @click="$emit('close-proxy')" title="Close File">
|
|
35
35
|
<svg
|
|
36
36
|
xmlns="http://www.w3.org/2000/svg"
|
|
37
37
|
width="16"
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
<transition name="fade">
|
|
52
52
|
<div v-if="isProxyEditorVisible" class="relative my-3">
|
|
53
53
|
<div class="pb-4">
|
|
54
|
-
<div class="proxy-editor-container
|
|
54
|
+
<div class="proxy-editor-container">
|
|
55
55
|
<textarea
|
|
56
56
|
:value="proxyContent"
|
|
57
57
|
@input="$emit('update:proxyContent', $event.target.value)"
|
|
@@ -84,3 +84,95 @@ const loadProxies = (listName) => {
|
|
|
84
84
|
emit('load-proxies', listName);
|
|
85
85
|
};
|
|
86
86
|
</script>
|
|
87
|
+
|
|
88
|
+
<style scoped>
|
|
89
|
+
.editor-action-btn {
|
|
90
|
+
@apply flex items-center justify-center w-9 h-9 rounded border-2 border-dark-550 bg-dark-400 text-white;
|
|
91
|
+
transition: all 0.2s ease;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.editor-action-btn:hover {
|
|
95
|
+
@apply bg-dark-450 border-dark-625;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.editor-action-btn svg {
|
|
99
|
+
@apply w-4 h-4;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.proxy-editor-container {
|
|
103
|
+
position: relative;
|
|
104
|
+
height: calc(100vh - 380px);
|
|
105
|
+
min-height: 300px;
|
|
106
|
+
max-height: calc(100vh - 380px);
|
|
107
|
+
border: 2px solid var(--color-border);
|
|
108
|
+
border-radius: 0.5rem;
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
background: var(--color-bg-dark-350);
|
|
111
|
+
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.proxy-editor {
|
|
115
|
+
width: 100%;
|
|
116
|
+
height: 100%;
|
|
117
|
+
padding: 1rem;
|
|
118
|
+
font-family: 'Courier New', Courier, monospace;
|
|
119
|
+
font-size: 14px;
|
|
120
|
+
line-height: 1.6;
|
|
121
|
+
color: #c8d3f5;
|
|
122
|
+
background: transparent;
|
|
123
|
+
border: none;
|
|
124
|
+
outline: none;
|
|
125
|
+
resize: none;
|
|
126
|
+
overflow: auto;
|
|
127
|
+
white-space: pre;
|
|
128
|
+
word-wrap: normal;
|
|
129
|
+
overflow-wrap: normal;
|
|
130
|
+
tab-size: 4;
|
|
131
|
+
caret-color: #ffc777;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.proxy-editor::selection {
|
|
135
|
+
background: oklch(0.4 0.1 240 / 0.4);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.proxy-editor:focus {
|
|
139
|
+
outline: none;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Tablet adjustments */
|
|
143
|
+
@media (max-width: 1024px) {
|
|
144
|
+
.proxy-editor-container {
|
|
145
|
+
height: calc(100vh - 350px);
|
|
146
|
+
max-height: calc(100vh - 350px);
|
|
147
|
+
min-height: 280px;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Mobile adjustments */
|
|
152
|
+
@media (max-width: 768px) {
|
|
153
|
+
.proxy-editor-container {
|
|
154
|
+
height: calc(100vh - 320px);
|
|
155
|
+
max-height: calc(100vh - 320px);
|
|
156
|
+
min-height: 250px;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.proxy-editor {
|
|
160
|
+
font-size: 13px;
|
|
161
|
+
padding: 0.75rem;
|
|
162
|
+
line-height: 1.5;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@media (max-width: 480px) {
|
|
167
|
+
.proxy-editor-container {
|
|
168
|
+
height: calc(100vh - 300px);
|
|
169
|
+
max-height: calc(100vh - 300px);
|
|
170
|
+
min-height: 200px;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.proxy-editor {
|
|
174
|
+
font-size: 12px;
|
|
175
|
+
padding: 0.5rem;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
</style>
|