@svadmin/lite 0.26.0 → 0.30.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.
Files changed (109) hide show
  1. package/dist/components/LiteAbacPolicyMatrix.svelte +128 -0
  2. package/dist/components/LiteAbacPolicyMatrix.svelte.d.ts +16 -0
  3. package/dist/components/LiteAnnouncementBanner.svelte +88 -0
  4. package/dist/components/LiteAnnouncementBanner.svelte.d.ts +12 -0
  5. package/dist/components/LiteApiPlayground.svelte +103 -0
  6. package/dist/components/LiteApiPlayground.svelte.d.ts +10 -0
  7. package/dist/components/LiteApprovalChainBuilder.svelte +120 -0
  8. package/dist/components/LiteApprovalChainBuilder.svelte.d.ts +15 -0
  9. package/dist/components/LiteAsyncExportModal.svelte +113 -0
  10. package/dist/components/LiteAsyncExportModal.svelte.d.ts +14 -0
  11. package/dist/components/LiteAuditTrailInspector.svelte +166 -0
  12. package/dist/components/LiteAuditTrailInspector.svelte.d.ts +23 -0
  13. package/dist/components/LiteBillingInvoiceDrawer.svelte +100 -0
  14. package/dist/components/LiteBillingInvoiceDrawer.svelte.d.ts +16 -0
  15. package/dist/components/LiteChartAnnotationOverlay.svelte +101 -0
  16. package/dist/components/LiteChartAnnotationOverlay.svelte.d.ts +16 -0
  17. package/dist/components/LiteColumnMappingTable.svelte +105 -0
  18. package/dist/components/LiteColumnMappingTable.svelte.d.ts +14 -0
  19. package/dist/components/LiteContextMenu.svelte +114 -0
  20. package/dist/components/LiteContextMenu.svelte.d.ts +18 -0
  21. package/dist/components/LiteDashboardGridLayout.svelte +108 -0
  22. package/dist/components/LiteDashboardGridLayout.svelte.d.ts +16 -0
  23. package/dist/components/LiteDashboardLayoutStorage.svelte +88 -0
  24. package/dist/components/LiteDashboardLayoutStorage.svelte.d.ts +16 -0
  25. package/dist/components/LiteDataImportDropzone.svelte +89 -0
  26. package/dist/components/LiteDataImportDropzone.svelte.d.ts +10 -0
  27. package/dist/components/LiteDataLineageGraph.svelte +100 -0
  28. package/dist/components/LiteDataLineageGraph.svelte.d.ts +15 -0
  29. package/dist/components/LiteDataMaskPolicyEngine.svelte +131 -0
  30. package/dist/components/LiteDataMaskPolicyEngine.svelte.d.ts +16 -0
  31. package/dist/components/LiteDataScreenContainer.svelte +34 -0
  32. package/dist/components/LiteDataScreenContainer.svelte.d.ts +9 -0
  33. package/dist/components/LiteDualApprovalGate.svelte +58 -0
  34. package/dist/components/LiteDualApprovalGate.svelte.d.ts +11 -0
  35. package/dist/components/LiteElectronicSealStamp.svelte +56 -0
  36. package/dist/components/LiteElectronicSealStamp.svelte.d.ts +9 -0
  37. package/dist/components/LiteEnvVariableEditor.svelte +114 -0
  38. package/dist/components/LiteEnvVariableEditor.svelte.d.ts +15 -0
  39. package/dist/components/LiteFormulaField.svelte +44 -0
  40. package/dist/components/LiteFormulaField.svelte.d.ts +11 -0
  41. package/dist/components/LiteGeoScatterMap.svelte +117 -0
  42. package/dist/components/LiteGeoScatterMap.svelte.d.ts +16 -0
  43. package/dist/components/LiteHmacSignatureCalculator.svelte +84 -0
  44. package/dist/components/LiteHmacSignatureCalculator.svelte.d.ts +10 -0
  45. package/dist/components/LiteImportPreviewValidator.svelte +136 -0
  46. package/dist/components/LiteImportPreviewValidator.svelte.d.ts +16 -0
  47. package/dist/components/LiteJsonViewer.svelte +88 -0
  48. package/dist/components/LiteJsonViewer.svelte.d.ts +9 -0
  49. package/dist/components/LiteKeyboardShortcutsModal.svelte +56 -0
  50. package/dist/components/LiteKeyboardShortcutsModal.svelte.d.ts +13 -0
  51. package/dist/components/LiteKpiCard.svelte +169 -0
  52. package/dist/components/LiteKpiCard.svelte.d.ts +25 -0
  53. package/dist/components/LiteLiveStreamLogViewer.svelte +84 -0
  54. package/dist/components/LiteLiveStreamLogViewer.svelte.d.ts +14 -0
  55. package/dist/components/LiteOmnibarCommandPalette.svelte +111 -0
  56. package/dist/components/LiteOmnibarCommandPalette.svelte.d.ts +15 -0
  57. package/dist/components/LitePeriodComparisonCard.svelte +60 -0
  58. package/dist/components/LitePeriodComparisonCard.svelte.d.ts +11 -0
  59. package/dist/components/LitePermissionSimulator.svelte +90 -0
  60. package/dist/components/LitePermissionSimulator.svelte.d.ts +14 -0
  61. package/dist/components/LitePivotMatrix.svelte +138 -0
  62. package/dist/components/LitePivotMatrix.svelte.d.ts +18 -0
  63. package/dist/components/LitePlanUsageQuotaBar.svelte +96 -0
  64. package/dist/components/LitePlanUsageQuotaBar.svelte.d.ts +15 -0
  65. package/dist/components/LiteQueryAiExplainer.svelte +85 -0
  66. package/dist/components/LiteQueryAiExplainer.svelte.d.ts +10 -0
  67. package/dist/components/LiteResultPage.svelte +135 -0
  68. package/dist/components/LiteResultPage.svelte.d.ts +17 -0
  69. package/dist/components/LiteScheduledJobManager.svelte +116 -0
  70. package/dist/components/LiteScheduledJobManager.svelte.d.ts +16 -0
  71. package/dist/components/LiteScreenAntiLeakGuard.svelte +56 -0
  72. package/dist/components/LiteScreenAntiLeakGuard.svelte.d.ts +8 -0
  73. package/dist/components/LiteSecureDataExporter.svelte +101 -0
  74. package/dist/components/LiteSecureDataExporter.svelte.d.ts +12 -0
  75. package/dist/components/LiteSensitiveDataMask.svelte +34 -2
  76. package/dist/components/LiteSensitiveDataMask.svelte.d.ts +1 -2
  77. package/dist/components/LiteSqlConsole.svelte +128 -0
  78. package/dist/components/LiteSqlConsole.svelte.d.ts +16 -0
  79. package/dist/components/LiteStepWizard.svelte +98 -0
  80. package/dist/components/LiteStepWizard.svelte.d.ts +16 -0
  81. package/dist/components/LiteSystemCapacityForecastCard.svelte +88 -0
  82. package/dist/components/LiteSystemCapacityForecastCard.svelte.d.ts +11 -0
  83. package/dist/components/LiteSystemHealthCheckDashboard.svelte +142 -0
  84. package/dist/components/LiteSystemHealthCheckDashboard.svelte.d.ts +18 -0
  85. package/dist/components/LiteTableAggregationFooter.svelte +76 -0
  86. package/dist/components/LiteTableAggregationFooter.svelte.d.ts +14 -0
  87. package/dist/components/LiteTenantContextSwitcher.svelte +173 -0
  88. package/dist/components/LiteTenantContextSwitcher.svelte.d.ts +27 -0
  89. package/dist/components/LiteTenantQuotasMatrix.svelte +117 -0
  90. package/dist/components/LiteTenantQuotasMatrix.svelte.d.ts +17 -0
  91. package/dist/components/LiteTextDiffViewer.svelte +111 -0
  92. package/dist/components/LiteTextDiffViewer.svelte.d.ts +10 -0
  93. package/dist/components/LiteThreadedCommentDrawer.svelte +60 -0
  94. package/dist/components/LiteThreadedCommentDrawer.svelte.d.ts +15 -0
  95. package/dist/components/LiteTierFeatureComparison.svelte +97 -0
  96. package/dist/components/LiteTierFeatureComparison.svelte.d.ts +18 -0
  97. package/dist/components/LiteUnsavedChangesGuard.svelte +53 -0
  98. package/dist/components/LiteUnsavedChangesGuard.svelte.d.ts +10 -0
  99. package/dist/components/LiteWatermarkContainer.svelte +58 -0
  100. package/dist/components/LiteWatermarkContainer.svelte.d.ts +9 -0
  101. package/dist/components/LiteWebhookSimulator.svelte +120 -0
  102. package/dist/components/LiteWebhookSimulator.svelte.d.ts +11 -0
  103. package/dist/components/LiteWorkflowNodeInspector.svelte +79 -0
  104. package/dist/components/LiteWorkflowNodeInspector.svelte.d.ts +11 -0
  105. package/dist/components/LiteWorkflowStepper.svelte +56 -0
  106. package/dist/components/LiteWorkflowStepper.svelte.d.ts +14 -0
  107. package/dist/index.d.ts +57 -0
  108. package/dist/index.js +61 -0
  109. package/package.json +2 -2
@@ -0,0 +1,136 @@
1
+ <script lang="ts">
2
+ interface ValidationError {
3
+ row: number;
4
+ col: string;
5
+ value: string;
6
+ message: string;
7
+ }
8
+
9
+ interface Props {
10
+ title?: string;
11
+ totalRows?: number;
12
+ validRows?: number;
13
+ errors?: ValidationError[];
14
+ class?: string;
15
+ }
16
+
17
+ let {
18
+ title = '导入数据预检与错误定位',
19
+ totalRows = 100,
20
+ validRows = 98,
21
+ errors = [
22
+ { row: 14, col: 'mobile_phone', value: '138000', message: '手机号格式非法,必须为11位国内有效号码' },
23
+ { row: 42, col: 'email', value: 'invalid-email', message: '电子邮箱格式不合规' }
24
+ ],
25
+ class: className = '',
26
+ }: Props = $props();
27
+
28
+ const errorCount = $derived(errors.length);
29
+ </script>
30
+
31
+ <div
32
+ class="lite-preview-validator {className}"
33
+ data-svadmin-component="LiteImportPreviewValidator"
34
+ role="region"
35
+ aria-label="Import Preview Validator"
36
+ >
37
+ <header class="lite-validator-header">
38
+ <h4 class="lite-validator-title">{title}</h4>
39
+ <div class="lite-stats-wrap">
40
+ <span class="lite-stat-total">总记录: {totalRows}</span>
41
+ <span class="lite-stat-valid">合格: {validRows}</span>
42
+ {#if errorCount > 0}
43
+ <span class="lite-stat-err">异常: {errorCount}</span>
44
+ {/if}
45
+ </div>
46
+ </header>
47
+
48
+ <div class="lite-validator-body">
49
+ {#if errorCount === 0}
50
+ <div class="lite-valid-notice">
51
+ ✓ 所有导入记录校验通过,未发现格式或必填项异常。
52
+ </div>
53
+ {:else}
54
+ <div class="lite-errors-list">
55
+ <div class="lite-err-notice">
56
+ 发现 {errorCount} 处数据格式异常,建议修正后重新上传或选择忽略错误行入库。
57
+ </div>
58
+ <table class="lite-errors-table">
59
+ <thead>
60
+ <tr>
61
+ <th>数据行号</th>
62
+ <th>异常列</th>
63
+ <th>当前取值</th>
64
+ <th>失败原因说明</th>
65
+ </tr>
66
+ </thead>
67
+ <tbody>
68
+ {#each errors as err (err.row + err.col)}
69
+ <tr>
70
+ <td class="font-mono">第 {err.row} 行</td>
71
+ <td><code>{err.col}</code></td>
72
+ <td class="lite-err-val">{err.value}</td>
73
+ <td class="lite-err-msg">{err.message}</td>
74
+ </tr>
75
+ {/each}
76
+ </tbody>
77
+ </table>
78
+ </div>
79
+ {/if}
80
+ </div>
81
+ </div>
82
+
83
+ <style>
84
+ .lite-preview-validator {
85
+ border: 1px solid #e5e6eb;
86
+ border-radius: 6px;
87
+ background: #ffffff;
88
+ font-size: 12px;
89
+ overflow: hidden;
90
+ }
91
+ .lite-validator-header {
92
+ display: flex;
93
+ justify-content: space-between;
94
+ align-items: center;
95
+ padding: 10px 14px;
96
+ background: #f7f8fa;
97
+ border-bottom: 1px solid #e5e6eb;
98
+ }
99
+ .lite-validator-title { margin: 0; font-size: 13px; font-weight: 600; color: #1d2129; }
100
+ .lite-stats-wrap { display: flex; font-size: 11px; font-weight: 500; }
101
+ .lite-stats-wrap > * + * { margin-left: 8px; }
102
+ .lite-stat-total { color: #4e5969; }
103
+ .lite-stat-valid { color: #00b42a; }
104
+ .lite-stat-err { color: #f53f3f; }
105
+ .lite-validator-body { padding: 12px 14px; }
106
+ .lite-valid-notice {
107
+ padding: 10px;
108
+ background: #e8ffea;
109
+ color: #00b42a;
110
+ border-radius: 4px;
111
+ font-weight: 500;
112
+ }
113
+ .lite-err-notice {
114
+ padding: 8px 10px;
115
+ background: #ffece8;
116
+ color: #f53f3f;
117
+ border-radius: 4px;
118
+ font-size: 11px;
119
+ margin-bottom: 10px;
120
+ }
121
+ .lite-errors-table { width: 100%; border-collapse: collapse; text-align: left; font-size: 11px; }
122
+ .lite-errors-table th {
123
+ padding: 6px 10px;
124
+ background: #f2f3f5;
125
+ border-bottom: 1px solid #e5e6eb;
126
+ color: #4e5969;
127
+ }
128
+ .lite-errors-table td {
129
+ padding: 6px 10px;
130
+ border-bottom: 1px solid #f2f3f5;
131
+ }
132
+ .font-mono { font-family: monospace; font-weight: 600; }
133
+ code { font-family: monospace; color: #165dff; }
134
+ .lite-err-val { color: #f53f3f; font-family: monospace; }
135
+ .lite-err-msg { color: #4e5969; }
136
+ </style>
@@ -0,0 +1,16 @@
1
+ interface ValidationError {
2
+ row: number;
3
+ col: string;
4
+ value: string;
5
+ message: string;
6
+ }
7
+ interface Props {
8
+ title?: string;
9
+ totalRows?: number;
10
+ validRows?: number;
11
+ errors?: ValidationError[];
12
+ class?: string;
13
+ }
14
+ declare const LiteImportPreviewValidator: import("svelte").Component<Props, {}, "">;
15
+ type LiteImportPreviewValidator = ReturnType<typeof LiteImportPreviewValidator>;
16
+ export default LiteImportPreviewValidator;
@@ -0,0 +1,88 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ data: unknown;
4
+ initialDepth?: number;
5
+ title?: string;
6
+ class?: string;
7
+ }
8
+
9
+ let {
10
+ data,
11
+ initialDepth = 2,
12
+ title,
13
+ class: className = '',
14
+ }: Props = $props();
15
+
16
+ const formattedJson = $derived.by(() => {
17
+ try {
18
+ return JSON.stringify(data, null, 2);
19
+ } catch {
20
+ return String(data);
21
+ }
22
+ });
23
+
24
+ const itemCount = $derived.by(() => {
25
+ if (typeof data === 'object' && data !== null) {
26
+ return Array.isArray(data) ? `${data.length} items` : `${Object.keys(data).length} keys`;
27
+ }
28
+ return typeof data;
29
+ });
30
+ </script>
31
+
32
+ <div
33
+ class="lite-json-viewer {className}"
34
+ data-svadmin-component="LiteJsonViewer"
35
+ data-initial-depth={initialDepth}
36
+ role="region"
37
+ aria-label={title ?? 'JSON Viewer'}
38
+ >
39
+ {#if title}
40
+ <header class="lite-json-header">
41
+ <h4 class="lite-json-title">{title}</h4>
42
+ <span class="lite-json-meta">{itemCount}</span>
43
+ </header>
44
+ {/if}
45
+
46
+ <div class="lite-json-body">
47
+ <div class="lite-json-details">
48
+ <div class="lite-json-summary">
49
+ <span>Payload Tree ({itemCount})</span>
50
+ </div>
51
+ <pre class="lite-json-code"><code>{formattedJson}</code></pre>
52
+ </div>
53
+ </div>
54
+ </div>
55
+
56
+ <style>
57
+ .lite-json-viewer {
58
+ border: 1px solid #e5e6eb;
59
+ border-radius: 6px;
60
+ background: #f7f8fa;
61
+ font-family: monospace;
62
+ font-size: 12px;
63
+ overflow: hidden;
64
+ }
65
+ .lite-json-header {
66
+ display: flex;
67
+ justify-content: space-between;
68
+ align-items: center;
69
+ padding: 8px 12px;
70
+ border-bottom: 1px solid #e5e6eb;
71
+ background: #ffffff;
72
+ }
73
+ .lite-json-title { margin: 0; font-size: 13px; font-weight: 600; color: #1d2129; }
74
+ .lite-json-meta { font-size: 11px; color: #86909c; }
75
+ .lite-json-body { padding: 10px 12px; max-height: 400px; overflow: auto; }
76
+ .lite-json-summary { cursor: pointer; color: #165dff; font-weight: 500; margin-bottom: 6px; outline: none; }
77
+ .lite-json-code {
78
+ margin: 0;
79
+ padding: 8px;
80
+ background: #ffffff;
81
+ border: 1px solid #e5e6eb;
82
+ border-radius: 4px;
83
+ color: #1d2129;
84
+ white-space: pre-wrap;
85
+ word-break: break-all;
86
+ line-height: 1.5;
87
+ }
88
+ </style>
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ data: unknown;
3
+ initialDepth?: number;
4
+ title?: string;
5
+ class?: string;
6
+ }
7
+ declare const LiteJsonViewer: import("svelte").Component<Props, {}, "">;
8
+ type LiteJsonViewer = ReturnType<typeof LiteJsonViewer>;
9
+ export default LiteJsonViewer;
@@ -0,0 +1,56 @@
1
+ <script lang="ts">
2
+ export interface LiteShortcutItem {
3
+ label: string;
4
+ keys: string[];
5
+ category?: string;
6
+ }
7
+
8
+ interface Props {
9
+ shortcuts?: LiteShortcutItem[];
10
+ title?: string;
11
+ class?: string;
12
+ }
13
+
14
+ let {
15
+ shortcuts = [
16
+ { label: '全局搜索 / 命令面板', keys: ['Ctrl', 'K'], category: '导航' },
17
+ { label: '保存当前表单', keys: ['Ctrl', 'S'], category: '编辑' },
18
+ { label: '打开快捷键向导', keys: ['?'], category: '系统' },
19
+ ],
20
+ title = '快捷键总览',
21
+ class: className = '',
22
+ }: Props = $props();
23
+ </script>
24
+
25
+ <div
26
+ class="lite-shortcuts-card {className}"
27
+ data-svadmin-component="LiteKeyboardShortcutsModal"
28
+ role="region"
29
+ aria-label={title}
30
+ >
31
+ <h4 class="lite-shortcuts-title">{title}</h4>
32
+ <table class="lite-shortcuts-table">
33
+ <tbody>
34
+ {#each shortcuts as item, idx (idx)}
35
+ <tr class="lite-shortcut-row">
36
+ <td class="lite-shortcut-label">{item.label}</td>
37
+ <td class="lite-shortcut-keys">
38
+ {#each item.keys as k, kIdx (kIdx)}
39
+ <kbd class="lite-kbd">{k}</kbd>
40
+ {/each}
41
+ </td>
42
+ </tr>
43
+ {/each}
44
+ </tbody>
45
+ </table>
46
+ </div>
47
+
48
+ <style>
49
+ .lite-shortcuts-card { border: 1px solid #e5e6eb; border-radius: 8px; background: #ffffff; padding: 16px; }
50
+ .lite-shortcuts-title { font-size: 14px; font-weight: 600; margin: 0 0 12px 0; color: #1d2129; }
51
+ .lite-shortcuts-table { width: 100%; border-collapse: collapse; font-size: 12px; }
52
+ .lite-shortcut-row td { padding: 6px 8px; border-bottom: 1px solid #f2f3f5; }
53
+ .lite-shortcut-label { color: #1d2129; font-weight: 500; }
54
+ .lite-shortcut-keys { text-align: right; }
55
+ .lite-kbd { font-family: monospace; font-size: 11px; background: #f2f3f5; border: 1px solid #e5e6eb; border-radius: 4px; padding: 2px 6px; color: #4e5969; margin-left: 4px; }
56
+ </style>
@@ -0,0 +1,13 @@
1
+ export interface LiteShortcutItem {
2
+ label: string;
3
+ keys: string[];
4
+ category?: string;
5
+ }
6
+ interface Props {
7
+ shortcuts?: LiteShortcutItem[];
8
+ title?: string;
9
+ class?: string;
10
+ }
11
+ declare const LiteKeyboardShortcutsModal: import("svelte").Component<Props, {}, "">;
12
+ type LiteKeyboardShortcutsModal = ReturnType<typeof LiteKeyboardShortcutsModal>;
13
+ export default LiteKeyboardShortcutsModal;
@@ -0,0 +1,169 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface TargetProgress {
5
+ current: number;
6
+ target: number;
7
+ label?: string;
8
+ }
9
+
10
+ interface Props {
11
+ title: string;
12
+ value: number | string;
13
+ prefix?: string;
14
+ suffix?: string;
15
+ subtitle?: string;
16
+ trendText?: string;
17
+ trendDirection?: 'up' | 'down' | 'neutral';
18
+ targetProgress?: TargetProgress;
19
+ sparklineData?: number[];
20
+ alertStatus?: 'normal' | 'warning' | 'danger';
21
+ alertMessage?: string;
22
+ class?: string;
23
+ actions?: Snippet;
24
+ children?: Snippet;
25
+ }
26
+
27
+ let {
28
+ title,
29
+ value,
30
+ prefix = '',
31
+ suffix = '',
32
+ subtitle,
33
+ trendText,
34
+ trendDirection = 'neutral',
35
+ targetProgress,
36
+ sparklineData,
37
+ alertStatus = 'normal',
38
+ alertMessage,
39
+ class: className = '',
40
+ actions,
41
+ children,
42
+ }: Props = $props();
43
+
44
+ const formattedValue = $derived(
45
+ typeof value === 'number' ? value.toLocaleString('en-US') : String(value)
46
+ );
47
+
48
+ const progressPercent = $derived.by(() => {
49
+ if (!targetProgress || targetProgress.target <= 0) return 0;
50
+ const pct = (targetProgress.current / targetProgress.target) * 100;
51
+ return Math.max(0, Math.min(100, Math.round(pct)));
52
+ });
53
+
54
+ const sparklinePoints = $derived.by(() => {
55
+ if (!sparklineData || sparklineData.length < 2) return '';
56
+ const min = Math.min(...sparklineData);
57
+ const max = Math.max(...sparklineData);
58
+ const range = max - min || 1;
59
+ const width = 100;
60
+ const height = 30;
61
+ const padding = 2;
62
+
63
+ return sparklineData
64
+ .map((val, idx) => {
65
+ const x = padding + (idx / (sparklineData.length - 1)) * (width - padding * 2);
66
+ const y = height - padding - ((val - min) / range) * (height - padding * 2);
67
+ return `${x.toFixed(1)},${y.toFixed(1)}`;
68
+ })
69
+ .join(' ');
70
+ });
71
+ </script>
72
+
73
+ <div
74
+ class="lite-kpi-card lite-kpi-card-{alertStatus} {className}"
75
+ data-svadmin-component="LiteKpiCard"
76
+ role="region"
77
+ aria-label={title}
78
+ >
79
+ <header class="lite-kpi-card-header">
80
+ <div class="lite-kpi-card-title-group">
81
+ <h4 class="lite-kpi-card-title">{title}</h4>
82
+ {#if subtitle}
83
+ <span class="lite-kpi-card-subtitle">{subtitle}</span>
84
+ {/if}
85
+ </div>
86
+ {#if actions}
87
+ <div class="lite-kpi-card-actions">{@render actions()}</div>
88
+ {/if}
89
+ </header>
90
+
91
+ <div class="lite-kpi-card-body">
92
+ <div class="lite-kpi-card-metric">
93
+ {#if prefix}<span class="lite-kpi-card-prefix">{prefix}</span>{/if}
94
+ <span class="lite-kpi-card-value">{formattedValue}</span>
95
+ {#if suffix}<span class="lite-kpi-card-suffix">{suffix}</span>{/if}
96
+ </div>
97
+
98
+ {#if trendText}
99
+ <div class="lite-kpi-card-trend lite-kpi-card-trend-{trendDirection}">
100
+ {#if trendDirection === 'up'}↑{:else if trendDirection === 'down'}↓{/if}
101
+ <span>{trendText}</span>
102
+ </div>
103
+ {/if}
104
+
105
+ {#if sparklinePoints}
106
+ <div class="lite-kpi-card-sparkline">
107
+ <svg viewBox="0 0 100 30" class="lite-kpi-sparkline-svg" aria-hidden="true">
108
+ <polyline points={sparklinePoints} fill="none" stroke="currentColor" stroke-width="2" />
109
+ </svg>
110
+ </div>
111
+ {/if}
112
+ </div>
113
+
114
+ {#if targetProgress}
115
+ <div class="lite-kpi-card-progress">
116
+ <div class="lite-kpi-progress-label">
117
+ <span>{targetProgress.label ?? 'Target progress'}</span>
118
+ <span class="lite-kpi-progress-pct">{progressPercent}%</span>
119
+ </div>
120
+ <div class="lite-kpi-progress-track">
121
+ <div class="lite-kpi-progress-bar" style="width: {progressPercent}%;"></div>
122
+ </div>
123
+ </div>
124
+ {/if}
125
+
126
+ {#if alertMessage && alertStatus !== 'normal'}
127
+ <div class="lite-kpi-card-alert lite-kpi-alert-{alertStatus}" role="alert">
128
+ <span>{alertMessage}</span>
129
+ </div>
130
+ {/if}
131
+
132
+ {#if children}
133
+ <div class="lite-kpi-card-extra">{@render children()}</div>
134
+ {/if}
135
+ </div>
136
+
137
+ <style>
138
+ .lite-kpi-card {
139
+ border: 1px solid #e5e6eb;
140
+ border-radius: 8px;
141
+ padding: 16px;
142
+ background: #ffffff;
143
+ box-sizing: border-box;
144
+ }
145
+ .lite-kpi-card-warning { border-color: #ffc766; background: #fffdf5; }
146
+ .lite-kpi-card-danger { border-color: #ffd8d2; background: #fff7f6; }
147
+ .lite-kpi-card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 8px; }
148
+ .lite-kpi-card-title { margin: 0; font-size: 13px; font-weight: 600; color: #4e5969; }
149
+ .lite-kpi-card-subtitle { font-size: 11px; color: #86909c; display: block; margin-top: 2px; }
150
+ .lite-kpi-card-body { display: flex; align-items: baseline; flex-wrap: wrap; margin-bottom: 8px; }
151
+ .lite-kpi-card-body > * + * { margin-left: 8px; }
152
+ .lite-kpi-card-metric { font-family: monospace; font-size: 24px; font-weight: 700; color: #1d2129; }
153
+ .lite-kpi-card-prefix, .lite-kpi-card-suffix { font-size: 13px; font-weight: 400; color: #86909c; margin: 0 2px; }
154
+ .lite-kpi-card-trend { font-size: 11px; font-weight: 600; padding: 2px 6px; border-radius: 4px; display: inline-flex; align-items: center; }
155
+ .lite-kpi-card-trend > * + * { margin-left: 2px; }
156
+ .lite-kpi-card-trend-up { color: #00b42a; background: #e8ffea; }
157
+ .lite-kpi-card-trend-down { color: #f53f3f; background: #ffece8; }
158
+ .lite-kpi-card-trend-neutral { color: #4e5969; background: #f2f3f5; }
159
+ .lite-kpi-card-sparkline { margin-left: auto; width: 80px; height: 24px; color: #165dff; }
160
+ .lite-kpi-sparkline-svg { width: 100%; height: 100%; display: block; }
161
+ .lite-kpi-card-progress { margin-top: 8px; }
162
+ .lite-kpi-progress-label { display: flex; justify-content: space-between; font-size: 11px; color: #86909c; margin-bottom: 4px; }
163
+ .lite-kpi-progress-track { height: 4px; background: #f2f3f5; border-radius: 2px; overflow: hidden; }
164
+ .lite-kpi-progress-bar { height: 100%; background: #165dff; border-radius: 2px; }
165
+ .lite-kpi-card-alert { margin-top: 10px; padding: 6px 10px; border-radius: 4px; font-size: 12px; }
166
+ .lite-kpi-alert-warning { background: #fff7e8; color: #d46b08; border: 1px solid #ffd591; }
167
+ .lite-kpi-alert-danger { background: #fff1f0; color: #cf1322; border: 1px solid #ffa39e; }
168
+ .lite-kpi-card-extra { margin-top: 10px; border-top: 1px solid #f2f3f5; padding-top: 8px; }
169
+ </style>
@@ -0,0 +1,25 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface TargetProgress {
3
+ current: number;
4
+ target: number;
5
+ label?: string;
6
+ }
7
+ interface Props {
8
+ title: string;
9
+ value: number | string;
10
+ prefix?: string;
11
+ suffix?: string;
12
+ subtitle?: string;
13
+ trendText?: string;
14
+ trendDirection?: 'up' | 'down' | 'neutral';
15
+ targetProgress?: TargetProgress;
16
+ sparklineData?: number[];
17
+ alertStatus?: 'normal' | 'warning' | 'danger';
18
+ alertMessage?: string;
19
+ class?: string;
20
+ actions?: Snippet;
21
+ children?: Snippet;
22
+ }
23
+ declare const LiteKpiCard: import("svelte").Component<Props, {}, "">;
24
+ type LiteKpiCard = ReturnType<typeof LiteKpiCard>;
25
+ export default LiteKpiCard;
@@ -0,0 +1,84 @@
1
+ <script lang="ts">
2
+ interface LogItem {
3
+ id: string;
4
+ timestamp: string;
5
+ level: string;
6
+ message: string;
7
+ }
8
+
9
+ interface Props {
10
+ title?: string;
11
+ logs?: LogItem[];
12
+ class?: string;
13
+ }
14
+
15
+ let {
16
+ title = '实时日志控制台',
17
+ logs = [
18
+ { id: '1', timestamp: '08:45:10', level: 'INFO', message: '[Gateway] Inbound HTTP POST /api/v1/orders/create (200 OK)' },
19
+ { id: '2', timestamp: '08:45:11', level: 'WARN', message: '[Redis] Cache miss on key "session:usr_9901"' },
20
+ { id: '3', timestamp: '08:45:12', level: 'ERROR', message: '[NotificationService] Third-party SMS webhook timed out' }
21
+ ],
22
+ class: className = '',
23
+ }: Props = $props();
24
+
25
+ function getLevelColor(lvl: string): string {
26
+ if (lvl === 'ERROR') return '#f53f3f';
27
+ if (lvl === 'WARN') return '#ff7d00';
28
+ return '#165dff';
29
+ }
30
+ </script>
31
+
32
+ <div
33
+ class="lite-log-viewer {className}"
34
+ data-svadmin-component="LiteLiveStreamLogViewer"
35
+ role="region"
36
+ aria-label="Live Stream Log Viewer"
37
+ >
38
+ <header class="lite-log-header">
39
+ <h4 class="lite-log-title">{title}</h4>
40
+ <span class="lite-log-count">{logs.length} 条日志记录</span>
41
+ </header>
42
+
43
+ <div class="lite-log-console">
44
+ {#each logs as log (log.id)}
45
+ <div class="lite-log-line font-mono">
46
+ <span class="lite-log-time">{log.timestamp}</span>
47
+ <span class="lite-log-badge" style="color: {getLevelColor(log.level)};">[{log.level}]</span>
48
+ <span class="lite-log-msg">{log.message}</span>
49
+ </div>
50
+ {/each}
51
+ </div>
52
+ </div>
53
+
54
+ <style>
55
+ .lite-log-viewer {
56
+ border: 1px solid #e5e6eb;
57
+ border-radius: 6px;
58
+ background: #ffffff;
59
+ font-size: 12px;
60
+ overflow: hidden;
61
+ }
62
+ .lite-log-header {
63
+ display: flex;
64
+ justify-content: space-between;
65
+ align-items: center;
66
+ padding: 10px 14px;
67
+ background: #f7f8fa;
68
+ border-bottom: 1px solid #e5e6eb;
69
+ }
70
+ .lite-log-title { margin: 0; font-size: 13px; font-weight: 600; color: #1d2129; }
71
+ .lite-log-count { font-size: 11px; color: #86909c; }
72
+ .lite-log-console {
73
+ background: #1e293b;
74
+ color: #f8fafc;
75
+ padding: 12px 14px;
76
+ font-size: 11px;
77
+ overflow-x: auto;
78
+ }
79
+ .lite-log-line { line-height: 1.6; }
80
+ .font-mono { font-family: monospace; }
81
+ .lite-log-time { color: #94a3b8; margin-right: 6px; }
82
+ .lite-log-badge { font-weight: 700; margin-right: 6px; }
83
+ .lite-log-msg { color: #f8fafc; }
84
+ </style>
@@ -0,0 +1,14 @@
1
+ interface LogItem {
2
+ id: string;
3
+ timestamp: string;
4
+ level: string;
5
+ message: string;
6
+ }
7
+ interface Props {
8
+ title?: string;
9
+ logs?: LogItem[];
10
+ class?: string;
11
+ }
12
+ declare const LiteLiveStreamLogViewer: import("svelte").Component<Props, {}, "">;
13
+ type LiteLiveStreamLogViewer = ReturnType<typeof LiteLiveStreamLogViewer>;
14
+ export default LiteLiveStreamLogViewer;