@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,6 +1,6 @@
1
1
  {
2
2
  "name": "@necrolab/dashboard",
3
- "version": "0.5.17",
3
+ "version": "0.5.18",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "rm -rf dist && vite build && npx workbox-cli generateSW workbox-config.cjs",
@@ -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 flex-wrap items-center gap-3 w-full">
5
- <div class="unified-search-group flex w-full flex-shrink-0 dropdown-container z-dropdown-high lg:w-auto lg:min-w-64">
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 transition-standard hover:bg-dark-450"
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-1.5 ml-auto">
22
+ <div v-if="isEditorVisible" class="flex gap-2 flex-shrink-0">
22
23
  <button
23
- class="button-default bg-dark-400"
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="button-default bg-dark-400" @click="$emit('save')" title="Save File">
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="button-default bg-dark-400" @click="$emit('close')" title="Close File">
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="pb-4">
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 flex-wrap items-center gap-3 w-full mb-1">
5
- <div class="w-full lg:w-64 flex flex-shrink-0 dropdown-container z-dropdown">
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-1.5 ml-auto">
18
- <button class="button-default bg-dark-400" @click="$emit('save-proxies')" title="Save Proxies">
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="button-default bg-dark-400" @click="$emit('close-proxy')" title="Close File">
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 table-component">
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>