@design.estate/dees-catalog 3.36.0 → 3.37.1

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/npmextra.json CHANGED
@@ -59,5 +59,8 @@
59
59
  "bundler": "esbuild"
60
60
  }
61
61
  ]
62
+ },
63
+ "@git.zone/tswatch": {
64
+ "preset": "element"
62
65
  }
63
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design.estate/dees-catalog",
3
- "version": "3.36.0",
3
+ "version": "3.37.1",
4
4
  "private": false,
5
5
  "description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
6
6
  "main": "dist_ts_web/index.js",
@@ -9,7 +9,7 @@
9
9
  "scripts": {
10
10
  "test": "tstest test/ --web --verbose --timeout 30 --logfile",
11
11
  "build": "tsbuild tsfolders --allowimplicitany && tsbundle",
12
- "watch": "tswatch element",
12
+ "watch": "tswatch",
13
13
  "buildDocs": "tsdoc",
14
14
  "postinstall": "node scripts/update-monaco-version.cjs"
15
15
  },
@@ -37,19 +37,19 @@
37
37
  "apexcharts": "^5.3.6",
38
38
  "highlight.js": "11.11.1",
39
39
  "ibantools": "^4.5.1",
40
- "lucide": "^0.562.0",
40
+ "lucide": "^0.563.0",
41
41
  "monaco-editor": "0.55.1",
42
42
  "pdfjs-dist": "^4.10.38",
43
43
  "xterm": "^5.3.0",
44
44
  "xterm-addon-fit": "^0.8.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@git.zone/tsbuild": "^4.1.0",
48
- "@git.zone/tsbundle": "^2.8.1",
49
- "@git.zone/tstest": "^3.1.4",
50
- "@git.zone/tswatch": "^2.3.13",
47
+ "@git.zone/tsbuild": "^4.1.2",
48
+ "@git.zone/tsbundle": "^2.8.3",
49
+ "@git.zone/tstest": "^3.1.7",
50
+ "@git.zone/tswatch": "^3.0.1",
51
51
  "@push.rocks/projectinfo": "^5.0.2",
52
- "@types/node": "^25.0.6"
52
+ "@types/node": "^25.0.10"
53
53
  },
54
54
  "files": [
55
55
  "ts/**/*",
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-catalog',
6
- version: '3.36.0',
6
+ version: '3.37.1',
7
7
  description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
8
8
  }
@@ -142,54 +142,95 @@ export const demoFunc = () => html`
142
142
  <dees-panel .title=${'3. Buttons with Icons'} .subtitle=${'Combining icons with text for enhanced visual communication'}>
143
143
  <div class="icon-row">
144
144
  <dees-button>
145
- <dees-icon iconFA="faPlus"></dees-icon>
145
+ <dees-icon icon="fa:plus"></dees-icon>
146
146
  Add Item
147
147
  </dees-button>
148
148
  <dees-button type="destructive">
149
- <dees-icon iconFA="faTrash"></dees-icon>
149
+ <dees-icon icon="fa:trash"></dees-icon>
150
150
  Delete
151
151
  </dees-button>
152
152
  <dees-button type="outline">
153
- <dees-icon iconFA="faDownload"></dees-icon>
153
+ <dees-icon icon="lucide:Download"></dees-icon>
154
154
  Download
155
155
  </dees-button>
156
156
  </div>
157
-
157
+
158
158
  <div class="icon-row">
159
159
  <dees-button type="secondary" size="sm">
160
- <dees-icon iconFA="faCog"></dees-icon>
160
+ <dees-icon icon="fa:gear"></dees-icon>
161
161
  Settings
162
162
  </dees-button>
163
163
  <dees-button type="ghost">
164
- <dees-icon iconFA="faChevronLeft"></dees-icon>
164
+ <dees-icon icon="fa:caretLeft"></dees-icon>
165
165
  Back
166
166
  </dees-button>
167
167
  <dees-button type="ghost">
168
168
  Next
169
- <dees-icon iconFA="faChevronRight"></dees-icon>
169
+ <dees-icon icon="fa:caretRight"></dees-icon>
170
170
  </dees-button>
171
171
  </div>
172
-
172
+
173
173
  <div class="icon-row">
174
174
  <dees-button size="icon" type="default">
175
- <dees-icon iconFA="faPlus"></dees-icon>
175
+ <dees-icon icon="fa:plus"></dees-icon>
176
176
  </dees-button>
177
177
  <dees-button size="icon" type="secondary">
178
- <dees-icon iconFA="faCog"></dees-icon>
178
+ <dees-icon icon="fa:gear"></dees-icon>
179
179
  </dees-button>
180
180
  <dees-button size="icon" type="outline">
181
- <dees-icon iconFA="faSearch"></dees-icon>
181
+ <dees-icon icon="lucide:Search"></dees-icon>
182
182
  </dees-button>
183
183
  <dees-button size="icon" type="ghost">
184
- <dees-icon iconFA="faEllipsisV"></dees-icon>
184
+ <dees-icon icon="lucide:MoreVertical"></dees-icon>
185
185
  </dees-button>
186
186
  <dees-button size="icon" type="destructive">
187
- <dees-icon iconFA="faTrash"></dees-icon>
187
+ <dees-icon icon="fa:trash"></dees-icon>
188
188
  </dees-button>
189
189
  </div>
190
190
  </dees-panel>
191
191
  </dees-demowrapper>
192
-
192
+
193
+ <dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
194
+ // Track icon property button clicks
195
+ const buttons = elementArg.querySelectorAll('dees-button');
196
+ buttons.forEach((button) => {
197
+ button.addEventListener('clicked', () => {
198
+ const icon = button.getAttribute('icon') || 'none';
199
+ const position = button.getAttribute('iconPosition') || 'left';
200
+ console.log(`Icon property button: icon=${icon}, position=${position}`);
201
+ });
202
+ });
203
+ }}>
204
+ <dees-panel .title=${'4. Icons via Property'} .subtitle=${'Simplified icon syntax using the icon property'}>
205
+ <div class="icon-row">
206
+ <dees-button icon="fa:plus">Add Item</dees-button>
207
+ <dees-button type="destructive" icon="fa:trash">Delete</dees-button>
208
+ <dees-button type="outline" icon="lucide:Download">Download</dees-button>
209
+ </div>
210
+
211
+ <div class="icon-row">
212
+ <dees-button type="secondary" size="sm" icon="fa:gear">Settings</dees-button>
213
+ <dees-button type="ghost" icon="fa:caretLeft">Back</dees-button>
214
+ <dees-button type="ghost" icon="fa:caretRight" iconPosition="right">Next</dees-button>
215
+ </div>
216
+
217
+ <div class="icon-row">
218
+ <dees-button size="icon" type="default" icon="fa:plus"></dees-button>
219
+ <dees-button size="icon" type="secondary" icon="lucide:Settings"></dees-button>
220
+ <dees-button size="icon" type="outline" icon="lucide:Search"></dees-button>
221
+ <dees-button size="icon" type="ghost" icon="lucide:MoreVertical"></dees-button>
222
+ <dees-button size="icon" type="destructive" icon="fa:trash"></dees-button>
223
+ </div>
224
+
225
+ <div style="margin-top: 16px;">
226
+ <div class="code-snippet">
227
+ &lt;dees-button icon="fa:plus"&gt;Add Item&lt;/dees-button&gt;<br>
228
+ &lt;dees-button icon="fa:caretRight" iconPosition="right"&gt;Next&lt;/dees-button&gt;
229
+ </div>
230
+ </div>
231
+ </dees-panel>
232
+ </dees-demowrapper>
233
+
193
234
  <dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
194
235
  // Demonstrate status changes
195
236
  const pendingButton = elementArg.querySelector('dees-button[status="pending"]');
@@ -215,7 +256,7 @@ export const demoFunc = () => html`
215
256
  });
216
257
  }
217
258
  }}>
218
- <dees-panel .title=${'4. Button States'} .subtitle=${'Different states to indicate button status and loading conditions'}>
259
+ <dees-panel .title=${'5. Button States'} .subtitle=${'Different states to indicate button status and loading conditions'}>
219
260
  <div class="button-group">
220
261
  <dees-button status="normal">Normal</dees-button>
221
262
  <dees-button status="pending">Processing...</dees-button>
@@ -260,7 +301,7 @@ export const demoFunc = () => html`
260
301
  });
261
302
  }
262
303
  }}>
263
- <dees-panel .title=${'5. Event Handling'} .subtitle=${'Interactive examples with click event handling'}>
304
+ <dees-panel .title=${'6. Event Handling'} .subtitle=${'Interactive examples with click event handling'}>
264
305
  <div class="button-group">
265
306
  <dees-button>Click Me</dees-button>
266
307
  <dees-button type="secondary" .eventDetailData=${'custom-data-123'}>
@@ -303,7 +344,7 @@ export const demoFunc = () => html`
303
344
  });
304
345
  }
305
346
  }}>
306
- <dees-panel .title=${'6. Form Integration'} .subtitle=${'Buttons working within forms with automatic spacing'}>
347
+ <dees-panel .title=${'7. Form Integration'} .subtitle=${'Buttons working within forms with automatic spacing'}>
307
348
  <dees-form>
308
349
  <dees-input-text label="Name" key="name" required></dees-input-text>
309
350
  <dees-input-text label="Email" key="email" type="email" required></dees-input-text>
@@ -330,7 +371,7 @@ export const demoFunc = () => html`
330
371
  }
331
372
  });
332
373
  }}>
333
- <dees-panel .title=${'7. Backward Compatibility'} .subtitle=${'Old button types are automatically mapped to new variants'}>
374
+ <dees-panel .title=${'8. Backward Compatibility'} .subtitle=${'Old button types are automatically mapped to new variants'}>
334
375
  <div class="button-group">
335
376
  <dees-button type="normal">Normal → Default</dees-button>
336
377
  <dees-button type="highlighted">Highlighted → Destructive</dees-button>
@@ -371,36 +412,36 @@ export const demoFunc = () => html`
371
412
  });
372
413
  }
373
414
  }}>
374
- <dees-panel .title=${'8. Advanced Examples'} .subtitle=${'Complex button configurations and real-world use cases'}>
415
+ <dees-panel .title=${'9. Advanced Examples'} .subtitle=${'Complex button configurations and real-world use cases'}>
375
416
  <div class="horizontal-group">
376
417
  <div class="vertical-group">
377
418
  <h4 style="margin: 0 0 8px 0; font-size: 14px; font-weight: 500;">Action Group</h4>
378
419
  <dees-button type="default" size="sm">
379
- <dees-icon iconFA="faSave"></dees-icon>
420
+ <dees-icon icon="lucide:Save"></dees-icon>
380
421
  Save Changes
381
422
  </dees-button>
382
423
  <dees-button type="secondary" size="sm">
383
- <dees-icon iconFA="faUndo"></dees-icon>
424
+ <dees-icon icon="lucide:Undo2"></dees-icon>
384
425
  Discard
385
426
  </dees-button>
386
427
  <dees-button type="ghost" size="sm">
387
- <dees-icon iconFA="faQuestionCircle"></dees-icon>
428
+ <dees-icon icon="lucide:HelpCircle"></dees-icon>
388
429
  Help
389
430
  </dees-button>
390
431
  </div>
391
-
432
+
392
433
  <div class="vertical-group">
393
434
  <h4 style="margin: 0 0 8px 0; font-size: 14px; font-weight: 500;">Danger Zone</h4>
394
435
  <dees-button type="destructive" size="sm">
395
- <dees-icon iconFA="faTrash"></dees-icon>
436
+ <dees-icon icon="fa:trash"></dees-icon>
396
437
  Delete Account
397
438
  </dees-button>
398
439
  <dees-button type="outline" size="sm">
399
- <dees-icon iconFA="faArchive"></dees-icon>
440
+ <dees-icon icon="lucide:Archive"></dees-icon>
400
441
  Archive Data
401
442
  </dees-button>
402
443
  <dees-button type="ghost" size="sm" disabled>
403
- <dees-icon iconFA="faBan"></dees-icon>
444
+ <dees-icon icon="lucide:Ban"></dees-icon>
404
445
  Not Available
405
446
  </dees-button>
406
447
  </div>
@@ -409,8 +450,7 @@ export const demoFunc = () => html`
409
450
  <div style="margin-top: 24px;">
410
451
  <h4 style="margin: 0 0 8px 0; font-size: 14px; font-weight: 500;">Code Example:</h4>
411
452
  <div class="code-snippet">
412
- &lt;dees-button type="default" size="sm" @clicked="\${handleClick}"&gt;<br>
413
- &nbsp;&nbsp;&lt;dees-icon iconFA="faSave"&gt;&lt;/dees-icon&gt;<br>
453
+ &lt;dees-button type="default" size="sm" icon="lucide:Save" @clicked="\${handleClick}"&gt;<br>
414
454
  &nbsp;&nbsp;Save Changes<br>
415
455
  &lt;/dees-button&gt;
416
456
  </div>
@@ -68,6 +68,12 @@ export class DeesButton extends DeesElement {
68
68
  })
69
69
  accessor insideForm: boolean = false;
70
70
 
71
+ @property({ type: String, reflect: true })
72
+ accessor icon: string;
73
+
74
+ @property({ type: String, reflect: true })
75
+ accessor iconPosition: 'left' | 'right' = 'left';
76
+
71
77
  constructor() {
72
78
  super();
73
79
  }
@@ -340,9 +346,62 @@ export class DeesButton extends DeesElement {
340
346
  height: 18px;
341
347
  }
342
348
 
349
+ /* Text alignment */
350
+ .textbox {
351
+ display: flex;
352
+ align-items: center;
353
+ }
354
+
343
355
  `,
344
356
  ];
345
357
 
358
+ /**
359
+ * Extracts icon and text from light DOM and sets properties
360
+ */
361
+ private extractLightDom(): void {
362
+ const iconElement = this.querySelector('dees-icon') as any;
363
+
364
+ // Get all text content from light DOM
365
+ const textContent = Array.from(this.childNodes)
366
+ .filter(node => node.nodeType === Node.TEXT_NODE)
367
+ .map(node => node.textContent?.trim())
368
+ .filter(Boolean)
369
+ .join(' ');
370
+
371
+ if (textContent && !this.text) {
372
+ this.text = textContent;
373
+ }
374
+
375
+ if (iconElement) {
376
+ // Get icon value
377
+ const iconValue = iconElement.icon || iconElement.getAttribute('icon') ||
378
+ (iconElement.iconFA ? `fa:${iconElement.iconFA}` : null);
379
+
380
+ if (iconValue) {
381
+ // Determine position based on DOM order
382
+ const children = Array.from(this.childNodes);
383
+ const iconIndex = children.indexOf(iconElement);
384
+ const textNodes = children.filter(node =>
385
+ node.nodeType === Node.TEXT_NODE && node.textContent?.trim()
386
+ );
387
+
388
+ if (textNodes.length > 0) {
389
+ const firstTextIndex = children.indexOf(textNodes[0]);
390
+ this.iconPosition = iconIndex < firstTextIndex ? 'left' : 'right';
391
+ }
392
+
393
+ // Set the icon property
394
+ this.icon = iconValue;
395
+ }
396
+
397
+ // Remove the light DOM icon element
398
+ iconElement.remove();
399
+ }
400
+
401
+ // Clear all remaining light DOM
402
+ this.innerHTML = '';
403
+ }
404
+
346
405
  public render(): TemplateResult {
347
406
  // Map old types to new types for backward compatibility
348
407
  const typeMap: {[key: string]: string} = {
@@ -351,10 +410,20 @@ export class DeesButton extends DeesElement {
351
410
  'discreet': 'outline',
352
411
  'big': 'default' // Will use size instead
353
412
  };
354
-
413
+
355
414
  const actualType = typeMap[this.type] || this.type;
356
415
  const actualSize = this.type === 'big' ? 'lg' : this.size;
357
-
416
+
417
+ const leftIcon = this.iconPosition === 'left' && this.icon
418
+ ? html`<dees-icon .icon=${this.icon}></dees-icon>`
419
+ : '';
420
+ const rightIcon = this.iconPosition === 'right' && this.icon
421
+ ? html`<dees-icon .icon=${this.icon}></dees-icon>`
422
+ : '';
423
+
424
+ // For icon-only buttons, hide the textbox
425
+ const isIconOnly = actualSize === 'icon' && this.icon;
426
+
358
427
  return html`
359
428
  <div
360
429
  class="button ${this.isHidden ? 'hidden' : ''} ${actualType} size-${actualSize} ${this.status} ${this.disabled
@@ -363,13 +432,15 @@ export class DeesButton extends DeesElement {
363
432
  @click="${this.dispatchClick}"
364
433
  >
365
434
  ${this.status === 'normal' ? html``: html`
366
- <dees-spinner
367
- .bnw=${true}
435
+ <dees-spinner
436
+ .bnw=${true}
368
437
  status="${this.status}"
369
438
  size="${actualSize === 'sm' ? 14 : actualSize === 'lg' ? 18 : 16}"
370
439
  ></dees-spinner>
371
440
  `}
372
- <div class="textbox">${this.text || html`<slot>Button</slot>`}</div>
441
+ ${leftIcon}
442
+ ${isIconOnly ? '' : html`<div class="textbox">${this.text || 'Button'}</div>`}
443
+ ${rightIcon}
373
444
  </div>
374
445
  `;
375
446
  }
@@ -390,6 +461,7 @@ export class DeesButton extends DeesElement {
390
461
  }
391
462
 
392
463
  public async firstUpdated() {
393
- // Don't set default text here as it interferes with slotted content
464
+ // Extract light DOM content (icon + text) and set as properties
465
+ this.extractLightDom();
394
466
  }
395
467
  }
@@ -90,10 +90,26 @@ export class DeesInputCode extends DeesInputBase<string> {
90
90
  }
91
91
 
92
92
  :host {
93
- display: block;
93
+ display: flex;
94
+ flex-direction: column;
95
+ min-height: 0;
96
+ }
97
+
98
+ .input-wrapper,
99
+ :host([label-position="top"]) .input-wrapper,
100
+ :host([label-position="left"]) .input-wrapper,
101
+ :host([label-position="right"]) .input-wrapper {
102
+ display: flex;
103
+ flex-direction: column;
104
+ flex: 1;
105
+ min-height: 0;
94
106
  }
95
107
 
96
108
  .code-container {
109
+ display: flex;
110
+ flex-direction: column;
111
+ flex: 1;
112
+ min-height: 0;
97
113
  border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
98
114
  border-radius: 6px;
99
115
  overflow: hidden;
@@ -206,10 +222,13 @@ export class DeesInputCode extends DeesInputBase<string> {
206
222
 
207
223
  .editor-wrapper {
208
224
  position: relative;
225
+ flex: 1;
226
+ min-height: 0;
209
227
  }
210
228
 
211
229
  dees-workspace-monaco {
212
230
  display: block;
231
+ height: 100%;
213
232
  }
214
233
 
215
234
  .toolbar-divider {
@@ -231,7 +250,7 @@ export class DeesInputCode extends DeesInputBase<string> {
231
250
 
232
251
  return html`
233
252
  <style>
234
- .editor-wrapper {
253
+ :host {
235
254
  height: ${this.height};
236
255
  }
237
256
  </style>
@@ -70,12 +70,22 @@ export class DeesWorkspaceMonaco extends DeesElement {
70
70
  css`
71
71
  /* TODO: Migrate hardcoded values to --dees-* CSS variables */
72
72
  :host {
73
+ display: block;
74
+ position: relative;
75
+ height: 100%;
76
+ width: 100%;
73
77
  }
74
78
 
75
79
  * {
76
80
  box-sizing: border-box;
77
81
  }
78
82
 
83
+ .mainbox {
84
+ position: relative;
85
+ height: 100%;
86
+ width: 100%;
87
+ }
88
+
79
89
  #container {
80
90
  position: absolute;
81
91
  height: 100%;
@@ -1,7 +1,7 @@
1
1
  import { html, css, cssManager } from '@design.estate/dees-element';
2
2
  import '@design.estate/dees-wcctools/demotools';
3
3
  import '../dees-panel/dees-panel.js';
4
- import type { IStatsTile, ICpuCore } from '../dees-statsgrid/dees-statsgrid.js';
4
+ import type { IStatsTile, ICpuCore, IPartitionData, IDiskData } from '../dees-statsgrid/dees-statsgrid.js';
5
5
 
6
6
  // Helper function to generate random CPU core data
7
7
  const generateCpuCores = (count: number): ICpuCore[] => {
@@ -601,8 +601,136 @@ html\`
601
601
  ></dees-statsgrid>
602
602
  \`;`}</div>
603
603
  </dees-panel>
604
+
605
+ <dees-panel .title=${'7. Disk & Storage Tiles'} .subtitle=${'Partition and physical disk visualization tiles'}>
606
+ <dees-statsgrid
607
+ .tiles=${[
608
+ {
609
+ id: 'root-partition',
610
+ title: 'Root Partition',
611
+ value: 0,
612
+ type: 'partition',
613
+ icon: 'lucide:folder-root',
614
+ partitionData: {
615
+ used: 698_341_425_152, // ~650 GB
616
+ total: 1_073_741_824_000, // ~1 TB
617
+ filesystem: 'ext4',
618
+ mountPoint: '/'
619
+ }
620
+ },
621
+ {
622
+ id: 'home-partition',
623
+ title: 'Home Partition',
624
+ value: 0,
625
+ type: 'partition',
626
+ icon: 'lucide:home',
627
+ partitionData: {
628
+ used: 214_748_364_800, // ~200 GB
629
+ total: 536_870_912_000, // ~500 GB
630
+ filesystem: 'ext4',
631
+ mountPoint: '/home'
632
+ }
633
+ },
634
+ {
635
+ id: 'data-partition',
636
+ title: 'Data Partition',
637
+ value: 0,
638
+ type: 'partition',
639
+ icon: 'lucide:database',
640
+ partitionData: {
641
+ used: 1_932_735_283_200, // ~1.8 TB (90% - critical)
642
+ total: 2_147_483_648_000, // ~2 TB
643
+ filesystem: 'xfs',
644
+ mountPoint: '/data'
645
+ }
646
+ },
647
+ {
648
+ id: 'nvme-ssd',
649
+ title: 'Primary NVMe',
650
+ value: 0,
651
+ type: 'disk',
652
+ icon: 'lucide:hard-drive',
653
+ columnSpan: 2,
654
+ diskData: {
655
+ capacity: 2_000_000_000_000, // 2 TB
656
+ model: 'Samsung 990 Pro',
657
+ type: 'nvme',
658
+ iops: {
659
+ read: 7450,
660
+ write: 6900
661
+ },
662
+ health: 98
663
+ }
664
+ },
665
+ {
666
+ id: 'sata-ssd',
667
+ title: 'Secondary SSD',
668
+ value: 0,
669
+ type: 'disk',
670
+ icon: 'lucide:hard-drive',
671
+ diskData: {
672
+ capacity: 1_000_000_000_000, // 1 TB
673
+ model: 'Crucial MX500',
674
+ type: 'ssd',
675
+ iops: {
676
+ read: 560,
677
+ write: 510
678
+ },
679
+ health: 85
680
+ }
681
+ },
682
+ {
683
+ id: 'hdd-storage',
684
+ title: 'Backup HDD',
685
+ value: 0,
686
+ type: 'disk',
687
+ icon: 'lucide:archive',
688
+ diskData: {
689
+ capacity: 8_000_000_000_000, // 8 TB
690
+ model: 'Seagate IronWolf',
691
+ type: 'hdd',
692
+ iops: {
693
+ read: 210,
694
+ write: 195
695
+ },
696
+ health: 42
697
+ }
698
+ }
699
+ ]}
700
+ .minTileWidth=${280}
701
+ .gap=${16}
702
+ ></dees-statsgrid>
703
+
704
+ <div class="tile-config">
705
+ <div class="config-section">
706
+ <div class="config-title">Partition Tile Properties</div>
707
+ <div class="config-description">
708
+ <ul style="margin: 8px 0; padding-left: 20px;">
709
+ <li><strong>partitionData.used:</strong> Used space in bytes (auto-formatted)</li>
710
+ <li><strong>partitionData.total:</strong> Total capacity in bytes</li>
711
+ <li><strong>partitionData.filesystem:</strong> Filesystem type (ext4, xfs, ntfs)</li>
712
+ <li><strong>partitionData.mountPoint:</strong> Mount point path (optional)</li>
713
+ </ul>
714
+ Color thresholds: Normal (&lt;75%), Warning (75-90%), Critical (&gt;90%)
715
+ </div>
716
+ </div>
717
+ <div class="config-section">
718
+ <div class="config-title">Disk Tile Properties</div>
719
+ <div class="config-description">
720
+ <ul style="margin: 8px 0; padding-left: 20px;">
721
+ <li><strong>diskData.capacity:</strong> Total capacity in bytes</li>
722
+ <li><strong>diskData.model:</strong> Disk model name (optional)</li>
723
+ <li><strong>diskData.type:</strong> Disk type: 'ssd', 'hdd', or 'nvme'</li>
724
+ <li><strong>diskData.iops:</strong> Read/write IOPS (optional)</li>
725
+ <li><strong>diskData.health:</strong> Health percentage 0-100 (optional)</li>
726
+ </ul>
727
+ Health thresholds: Good (70-100%), Warning (30-70%), Critical (&lt;30%)
728
+ </div>
729
+ </div>
730
+ </div>
731
+ </dees-panel>
604
732
  </div>
605
-
733
+
606
734
  <script>
607
735
  // Cleanup live updates on page unload
608
736
  window.addEventListener('beforeunload', () => {