@svadmin/lite 0.25.7 → 0.27.0
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/README.md +11 -5
- package/dist/components/LiteAnnouncementBanner.svelte +88 -0
- package/dist/components/LiteAnnouncementBanner.svelte.d.ts +12 -0
- package/dist/components/LiteAsyncExportModal.svelte +113 -0
- package/dist/components/LiteAsyncExportModal.svelte.d.ts +14 -0
- package/dist/components/LiteAuditLog.svelte +102 -36
- package/dist/components/LiteAuditLog.svelte.d.ts +6 -3
- package/dist/components/LiteConcurrentConflictModal.svelte +110 -0
- package/dist/components/LiteConcurrentConflictModal.svelte.d.ts +21 -0
- package/dist/components/LiteContextMenu.svelte +114 -0
- package/dist/components/LiteContextMenu.svelte.d.ts +18 -0
- package/dist/components/LiteCronExpressionBuilder.svelte +78 -0
- package/dist/components/LiteCronExpressionBuilder.svelte.d.ts +17 -0
- package/dist/components/LiteDualApprovalGate.svelte +58 -0
- package/dist/components/LiteDualApprovalGate.svelte.d.ts +11 -0
- package/dist/components/LiteJsonViewer.svelte +88 -0
- package/dist/components/LiteJsonViewer.svelte.d.ts +9 -0
- package/dist/components/LiteKeyboardShortcutsModal.svelte +56 -0
- package/dist/components/LiteKeyboardShortcutsModal.svelte.d.ts +13 -0
- package/dist/components/LiteKpiCard.svelte +169 -0
- package/dist/components/LiteKpiCard.svelte.d.ts +25 -0
- package/dist/components/LiteMetricGrid.svelte +143 -0
- package/dist/components/LiteMetricGrid.svelte.d.ts +31 -0
- package/dist/components/LiteMicroAppFrame.svelte +57 -0
- package/dist/components/LiteMicroAppFrame.svelte.d.ts +15 -0
- package/dist/components/LiteOrgChart.svelte +78 -0
- package/dist/components/LiteOrgChart.svelte.d.ts +17 -0
- package/dist/components/LitePresenceAvatarGroup.svelte +118 -15
- package/dist/components/LitePresenceAvatarGroup.svelte.d.ts +8 -3
- package/dist/components/LiteResultPage.svelte +135 -0
- package/dist/components/LiteResultPage.svelte.d.ts +17 -0
- package/dist/components/LiteSafeDeleteConfirm.svelte +86 -0
- package/dist/components/LiteSafeDeleteConfirm.svelte.d.ts +21 -0
- package/dist/components/LiteSensitiveDataMask.svelte +34 -2
- package/dist/components/LiteSensitiveDataMask.svelte.d.ts +1 -2
- package/dist/components/LiteSignaturePad.svelte +3 -1
- package/dist/components/LiteSignaturePad.svelte.d.ts +1 -0
- package/dist/components/LiteStepWizard.svelte +98 -0
- package/dist/components/LiteStepWizard.svelte.d.ts +16 -0
- package/dist/components/LiteTaskCenter.svelte +133 -0
- package/dist/components/LiteTaskCenter.svelte.d.ts +24 -0
- package/dist/components/LiteTextDiffViewer.svelte +111 -0
- package/dist/components/LiteTextDiffViewer.svelte.d.ts +10 -0
- package/dist/components/LiteTour.svelte +4 -0
- package/dist/components/LiteTour.svelte.d.ts +4 -0
- package/dist/components/LiteTrendIndicator.svelte +119 -0
- package/dist/components/LiteTrendIndicator.svelte.d.ts +19 -0
- package/dist/components/LiteUnsavedChangesGuard.svelte +53 -0
- package/dist/components/LiteUnsavedChangesGuard.svelte.d.ts +10 -0
- package/dist/components/LiteVirtualTreeSelect.svelte +92 -0
- package/dist/components/LiteVirtualTreeSelect.svelte.d.ts +20 -0
- package/dist/components/LiteWatermarkContainer.svelte +58 -0
- package/dist/components/LiteWatermarkContainer.svelte.d.ts +9 -0
- package/dist/components/LiteWorkflowStepper.svelte +56 -0
- package/dist/components/LiteWorkflowStepper.svelte.d.ts +14 -0
- package/dist/components/widgets/LiteGaugeChart.svelte +50 -3
- package/dist/components/widgets/LiteGaugeChart.svelte.d.ts +12 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +24 -0
- package/dist/rich-content.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
type TrendDirection = 'up' | 'down' | 'neutral';
|
|
3
|
+
type TrendVariant = 'text' | 'badge' | 'solid';
|
|
4
|
+
type TrendSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
value?: number | string;
|
|
8
|
+
prevValue?: number;
|
|
9
|
+
direction?: TrendDirection;
|
|
10
|
+
prefix?: string;
|
|
11
|
+
suffix?: string;
|
|
12
|
+
precision?: number;
|
|
13
|
+
reverseColor?: boolean;
|
|
14
|
+
variant?: TrendVariant;
|
|
15
|
+
size?: TrendSize;
|
|
16
|
+
showIcon?: boolean;
|
|
17
|
+
class?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
value,
|
|
22
|
+
prevValue,
|
|
23
|
+
direction,
|
|
24
|
+
prefix,
|
|
25
|
+
suffix = '%',
|
|
26
|
+
precision = 1,
|
|
27
|
+
reverseColor = false,
|
|
28
|
+
variant = 'text',
|
|
29
|
+
size = 'md',
|
|
30
|
+
showIcon = true,
|
|
31
|
+
class: className = '',
|
|
32
|
+
}: Props = $props();
|
|
33
|
+
|
|
34
|
+
const computed = $derived.by(() => {
|
|
35
|
+
if (typeof value === 'number' && typeof prevValue === 'number' && prevValue !== 0) {
|
|
36
|
+
const diff = value - prevValue;
|
|
37
|
+
return {
|
|
38
|
+
direction: direction ?? (diff > 0 ? 'up' : diff < 0 ? 'down' : 'neutral'),
|
|
39
|
+
text: `${Math.abs((diff / Math.abs(prevValue)) * 100).toFixed(precision)}${suffix}`,
|
|
40
|
+
} satisfies { direction: TrendDirection; text: string };
|
|
41
|
+
}
|
|
42
|
+
if (typeof value === 'number') {
|
|
43
|
+
return {
|
|
44
|
+
direction: direction ?? (value > 0 ? 'up' : value < 0 ? 'down' : 'neutral'),
|
|
45
|
+
text: `${Math.abs(value).toFixed(precision)}${suffix}`,
|
|
46
|
+
} satisfies { direction: TrendDirection; text: string };
|
|
47
|
+
}
|
|
48
|
+
if (typeof value === 'string') {
|
|
49
|
+
const text = value.trim();
|
|
50
|
+
const parsed = Number.parseFloat(text);
|
|
51
|
+
const resolved = direction ?? (text.startsWith('-') || parsed < 0
|
|
52
|
+
? 'down'
|
|
53
|
+
: text.startsWith('+') || parsed > 0
|
|
54
|
+
? 'up'
|
|
55
|
+
: 'neutral');
|
|
56
|
+
return { direction: resolved, text } satisfies { direction: TrendDirection; text: string };
|
|
57
|
+
}
|
|
58
|
+
return { direction: direction ?? 'neutral', text: '--' } satisfies {
|
|
59
|
+
direction: TrendDirection;
|
|
60
|
+
text: string;
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const tone = $derived.by(() => {
|
|
65
|
+
if (computed.direction === 'neutral') return 'neutral';
|
|
66
|
+
const improving = reverseColor ? computed.direction === 'down' : computed.direction === 'up';
|
|
67
|
+
return improving ? 'positive' : 'negative';
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<span
|
|
72
|
+
class="lite-trend lite-trend-{variant} lite-trend-{size} {className}"
|
|
73
|
+
data-tone={tone}
|
|
74
|
+
data-direction={computed.direction}
|
|
75
|
+
>
|
|
76
|
+
{#if prefix}<span class="lite-trend-prefix">{prefix}</span>{/if}
|
|
77
|
+
{#if showIcon}<span class="lite-trend-icon" aria-hidden="true">{computed.direction === 'up' ? '↑' : computed.direction === 'down' ? '↓' : '→'}</span>{/if}
|
|
78
|
+
<span class="lite-trend-value">{computed.text}</span>
|
|
79
|
+
<span class="lite-sr-only">{tone === 'positive' ? 'Improving' : tone === 'negative' ? 'Declining' : 'Unchanged'}</span>
|
|
80
|
+
</span>
|
|
81
|
+
|
|
82
|
+
<style>
|
|
83
|
+
.lite-trend {
|
|
84
|
+
display: inline-flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
color: #4e5969;
|
|
87
|
+
font-size: 12px;
|
|
88
|
+
font-weight: 600;
|
|
89
|
+
line-height: 1.4;
|
|
90
|
+
white-space: nowrap;
|
|
91
|
+
}
|
|
92
|
+
.lite-trend-sm { font-size: 11px; }
|
|
93
|
+
.lite-trend-lg { font-size: 14px; }
|
|
94
|
+
.lite-trend-badge,
|
|
95
|
+
.lite-trend-solid {
|
|
96
|
+
padding: 2px 6px;
|
|
97
|
+
border-radius: 999px;
|
|
98
|
+
border: 1px solid #e5e6eb;
|
|
99
|
+
background: #f7f8fa;
|
|
100
|
+
}
|
|
101
|
+
.lite-trend-solid[data-tone='positive'] { color: #fff; background: #00b42a; border-color: #00b42a; }
|
|
102
|
+
.lite-trend-solid[data-tone='negative'] { color: #fff; background: #f53f3f; border-color: #f53f3f; }
|
|
103
|
+
.lite-trend[data-tone='positive'] { color: #00b42a; }
|
|
104
|
+
.lite-trend[data-tone='negative'] { color: #f53f3f; }
|
|
105
|
+
.lite-trend[data-tone='neutral'] { color: #86909c; }
|
|
106
|
+
.lite-trend-prefix, .lite-trend-icon { margin-right: 4px; }
|
|
107
|
+
.lite-trend-prefix { color: #86909c; font-weight: 500; }
|
|
108
|
+
.lite-sr-only {
|
|
109
|
+
position: absolute;
|
|
110
|
+
width: 1px;
|
|
111
|
+
height: 1px;
|
|
112
|
+
padding: 0;
|
|
113
|
+
margin: -1px;
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
clip: rect(0, 0, 0, 0);
|
|
116
|
+
white-space: nowrap;
|
|
117
|
+
border: 0;
|
|
118
|
+
}
|
|
119
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type TrendDirection = 'up' | 'down' | 'neutral';
|
|
2
|
+
type TrendVariant = 'text' | 'badge' | 'solid';
|
|
3
|
+
type TrendSize = 'sm' | 'md' | 'lg';
|
|
4
|
+
interface Props {
|
|
5
|
+
value?: number | string;
|
|
6
|
+
prevValue?: number;
|
|
7
|
+
direction?: TrendDirection;
|
|
8
|
+
prefix?: string;
|
|
9
|
+
suffix?: string;
|
|
10
|
+
precision?: number;
|
|
11
|
+
reverseColor?: boolean;
|
|
12
|
+
variant?: TrendVariant;
|
|
13
|
+
size?: TrendSize;
|
|
14
|
+
showIcon?: boolean;
|
|
15
|
+
class?: string;
|
|
16
|
+
}
|
|
17
|
+
declare const LiteTrendIndicator: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type LiteTrendIndicator = ReturnType<typeof LiteTrendIndicator>;
|
|
19
|
+
export default LiteTrendIndicator;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
hasChanges?: boolean;
|
|
6
|
+
message?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
hasChanges = false,
|
|
13
|
+
message = 'You have unsaved changes that may be lost.',
|
|
14
|
+
class: className = '',
|
|
15
|
+
children,
|
|
16
|
+
}: Props = $props();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<div
|
|
20
|
+
class="lite-unsaved-guard {className}"
|
|
21
|
+
data-svadmin-component="LiteUnsavedChangesGuard"
|
|
22
|
+
data-dirty={hasChanges ? 'true' : 'false'}
|
|
23
|
+
>
|
|
24
|
+
{#if hasChanges}
|
|
25
|
+
<aside class="lite-unsaved-banner" role="status">
|
|
26
|
+
<span class="lite-unsaved-icon">⚠️</span>
|
|
27
|
+
<span class="lite-unsaved-text">{message}</span>
|
|
28
|
+
</aside>
|
|
29
|
+
{/if}
|
|
30
|
+
|
|
31
|
+
<div class="lite-unsaved-content">
|
|
32
|
+
{#if children}{@render children()}{/if}
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<style>
|
|
37
|
+
.lite-unsaved-guard { display: block; }
|
|
38
|
+
.lite-unsaved-banner {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
padding: 8px 12px;
|
|
42
|
+
background: #fff7e8;
|
|
43
|
+
border: 1px solid #ffd591;
|
|
44
|
+
border-radius: 6px;
|
|
45
|
+
margin-bottom: 12px;
|
|
46
|
+
font-size: 13px;
|
|
47
|
+
color: #d46b08;
|
|
48
|
+
}
|
|
49
|
+
.lite-unsaved-banner > * + * { margin-left: 8px; }
|
|
50
|
+
.lite-unsaved-icon { font-size: 14px; }
|
|
51
|
+
.lite-unsaved-text { font-weight: 500; }
|
|
52
|
+
.lite-unsaved-content { position: relative; }
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
hasChanges?: boolean;
|
|
4
|
+
message?: string;
|
|
5
|
+
class?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const LiteUnsavedChangesGuard: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type LiteUnsavedChangesGuard = ReturnType<typeof LiteUnsavedChangesGuard>;
|
|
10
|
+
export default LiteUnsavedChangesGuard;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export interface LiteVirtualTreeNode {
|
|
3
|
+
value: string | number;
|
|
4
|
+
label: string;
|
|
5
|
+
children?: LiteVirtualTreeNode[];
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
nodes?: LiteVirtualTreeNode[];
|
|
11
|
+
value?: string | number | Array<string | number>;
|
|
12
|
+
name?: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
multiple?: boolean;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
class?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let {
|
|
22
|
+
nodes = [],
|
|
23
|
+
value = '',
|
|
24
|
+
name = 'value',
|
|
25
|
+
label = 'Tree selection',
|
|
26
|
+
placeholder = 'Select an option',
|
|
27
|
+
multiple = false,
|
|
28
|
+
disabled = false,
|
|
29
|
+
required = false,
|
|
30
|
+
class: className = '',
|
|
31
|
+
}: Props = $props();
|
|
32
|
+
|
|
33
|
+
interface FlatNode {
|
|
34
|
+
node: LiteVirtualTreeNode;
|
|
35
|
+
depth: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function flatten(items: LiteVirtualTreeNode[], depth = 0, out: FlatNode[] = []): FlatNode[] {
|
|
39
|
+
for (const node of items) {
|
|
40
|
+
out.push({ node, depth });
|
|
41
|
+
if (node.children?.length) flatten(node.children, depth + 1, out);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const options = $derived(flatten(nodes));
|
|
47
|
+
let current = $state(value);
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
{#snippet treeOptions()}
|
|
51
|
+
{#each options as option (option.node.value)}
|
|
52
|
+
<option value={option.node.value} disabled={option.node.disabled}>
|
|
53
|
+
{'\u00a0'.repeat(option.depth * 3)}{option.depth > 0 ? '└ ' : ''}{option.node.label}
|
|
54
|
+
</option>
|
|
55
|
+
{/each}
|
|
56
|
+
{/snippet}
|
|
57
|
+
|
|
58
|
+
<div class="lite-virtual-tree-select {className}">
|
|
59
|
+
<label for="lite-tree-select">{label}</label>
|
|
60
|
+
{#if multiple}
|
|
61
|
+
<select
|
|
62
|
+
id="lite-tree-select"
|
|
63
|
+
{name}
|
|
64
|
+
multiple
|
|
65
|
+
{disabled}
|
|
66
|
+
{required}
|
|
67
|
+
bind:value={current}
|
|
68
|
+
aria-label={label}
|
|
69
|
+
>
|
|
70
|
+
{@render treeOptions()}
|
|
71
|
+
</select>
|
|
72
|
+
{:else}
|
|
73
|
+
<select
|
|
74
|
+
id="lite-tree-select"
|
|
75
|
+
{name}
|
|
76
|
+
{disabled}
|
|
77
|
+
{required}
|
|
78
|
+
bind:value={current}
|
|
79
|
+
aria-label={label}
|
|
80
|
+
>
|
|
81
|
+
<option value="" disabled={required}>{placeholder}</option>
|
|
82
|
+
{@render treeOptions()}
|
|
83
|
+
</select>
|
|
84
|
+
{/if}
|
|
85
|
+
<p class="lite-virtual-tree-help">Large-tree search and virtual scrolling are client-side enhancements.</p>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<style>
|
|
89
|
+
.lite-virtual-tree-select label { display: block; margin-bottom: 4px; color: #4e5969; font-size: 12px; font-weight: 600; }
|
|
90
|
+
.lite-virtual-tree-select select { width: 100%; box-sizing: border-box; min-height: 34px; padding: 6px 8px; border: 1px solid #e5e6eb; border-radius: 4px; background: #fff; color: #1d2129; font: inherit; font-size: 13px; }
|
|
91
|
+
.lite-virtual-tree-help { margin: 4px 0 0; color: #86909c; font-size: 11px; }
|
|
92
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface LiteVirtualTreeNode {
|
|
2
|
+
value: string | number;
|
|
3
|
+
label: string;
|
|
4
|
+
children?: LiteVirtualTreeNode[];
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface Props {
|
|
8
|
+
nodes?: LiteVirtualTreeNode[];
|
|
9
|
+
value?: string | number | Array<string | number>;
|
|
10
|
+
name?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
multiple?: boolean;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
required?: boolean;
|
|
16
|
+
class?: string;
|
|
17
|
+
}
|
|
18
|
+
declare const LiteVirtualTreeSelect: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type LiteVirtualTreeSelect = ReturnType<typeof LiteVirtualTreeSelect>;
|
|
20
|
+
export default LiteVirtualTreeSelect;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
content?: string | string[];
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
content = 'SVAdmin Lite',
|
|
12
|
+
class: className = '',
|
|
13
|
+
children,
|
|
14
|
+
}: Props = $props();
|
|
15
|
+
|
|
16
|
+
const watermarkText = $derived(
|
|
17
|
+
Array.isArray(content) ? content.join(' ') : String(content)
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const encodedSvg = $derived.by(() => {
|
|
21
|
+
const escaped = watermarkText
|
|
22
|
+
.replace(/&/g, '&')
|
|
23
|
+
.replace(/</g, '<')
|
|
24
|
+
.replace(/>/g, '>')
|
|
25
|
+
.replace(/"/g, '"');
|
|
26
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120" viewBox="0 0 220 120"><text x="20" y="60" fill="rgba(0,0,0,0.07)" font-family="sans-serif" font-size="12" transform="rotate(-18 110 60)">${escaped}</text></svg>`;
|
|
27
|
+
return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div
|
|
32
|
+
class="lite-watermark-container {className}"
|
|
33
|
+
data-svadmin-component="LiteWatermarkContainer"
|
|
34
|
+
style="--lite-watermark-pattern: url('{encodedSvg}');"
|
|
35
|
+
>
|
|
36
|
+
<div class="lite-watermark-overlay" aria-hidden="true" style="background-image: url('{encodedSvg}');"></div>
|
|
37
|
+
<div class="lite-watermark-content">
|
|
38
|
+
{#if children}{@render children()}{/if}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<style>
|
|
43
|
+
.lite-watermark-container {
|
|
44
|
+
position: relative;
|
|
45
|
+
overflow: hidden;
|
|
46
|
+
}
|
|
47
|
+
.lite-watermark-overlay {
|
|
48
|
+
position: absolute;
|
|
49
|
+
inset: 0;
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
z-index: 9;
|
|
52
|
+
background-repeat: repeat;
|
|
53
|
+
}
|
|
54
|
+
.lite-watermark-content {
|
|
55
|
+
position: relative;
|
|
56
|
+
z-index: 1;
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
content?: string | string[];
|
|
4
|
+
class?: string;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
}
|
|
7
|
+
declare const LiteWatermarkContainer: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type LiteWatermarkContainer = ReturnType<typeof LiteWatermarkContainer>;
|
|
9
|
+
export default LiteWatermarkContainer;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export interface LiteWorkflowNode {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
status: 'completed' | 'running' | 'failed' | 'pending';
|
|
6
|
+
durationText?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
nodes: LiteWorkflowNode[];
|
|
11
|
+
title?: string;
|
|
12
|
+
class?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
nodes = [],
|
|
17
|
+
title = 'Workflow Execution',
|
|
18
|
+
class: className = '',
|
|
19
|
+
}: Props = $props();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div
|
|
23
|
+
class="lite-workflow-stepper {className}"
|
|
24
|
+
data-svadmin-component="LiteWorkflowStepper"
|
|
25
|
+
>
|
|
26
|
+
<h4 class="lite-workflow-title">{title}</h4>
|
|
27
|
+
<ol class="lite-workflow-list">
|
|
28
|
+
{#each nodes as node (node.id)}
|
|
29
|
+
<li class="lite-workflow-node lite-status-{node.status}">
|
|
30
|
+
<span class="lite-node-icon">
|
|
31
|
+
{#if node.status === 'completed'}✓{:else if node.status === 'running'}⏳{:else if node.status === 'failed'}✕{:else}○{/if}
|
|
32
|
+
</span>
|
|
33
|
+
<span class="lite-node-label">{node.label}</span>
|
|
34
|
+
{#if node.durationText}
|
|
35
|
+
<span class="lite-node-duration">{node.durationText}</span>
|
|
36
|
+
{/if}
|
|
37
|
+
</li>
|
|
38
|
+
{/each}
|
|
39
|
+
</ol>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<style>
|
|
43
|
+
.lite-workflow-stepper { border: 1px solid #e5e6eb; border-radius: 8px; background: #ffffff; padding: 16px; }
|
|
44
|
+
.lite-workflow-title { font-size: 14px; font-weight: 600; margin: 0 0 12px 0; color: #1d2129; }
|
|
45
|
+
.lite-workflow-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
|
|
46
|
+
.lite-workflow-list > * + * { margin-top: 8px; }
|
|
47
|
+
.lite-workflow-node { display: flex; align-items: center; padding: 8px 12px; border-radius: 6px; border: 1px solid #f2f3f5; font-size: 12px; }
|
|
48
|
+
.lite-workflow-node > * + * { margin-left: 10px; }
|
|
49
|
+
.lite-node-icon { font-weight: 700; width: 18px; text-align: center; }
|
|
50
|
+
.lite-status-completed { background: #e8ffea; color: #00b42a; border-color: #aff0b5; }
|
|
51
|
+
.lite-status-running { background: #e8f3ff; color: #165dff; border-color: #b3d6ff; }
|
|
52
|
+
.lite-status-failed { background: #ffece8; color: #f53f3f; border-color: #fbbbb0; }
|
|
53
|
+
.lite-status-pending { background: #f7f8fa; color: #86909c; }
|
|
54
|
+
.lite-node-label { font-weight: 500; flex: 1; }
|
|
55
|
+
.lite-node-duration { font-family: monospace; font-size: 11px; color: #86909c; }
|
|
56
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface LiteWorkflowNode {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
status: 'completed' | 'running' | 'failed' | 'pending';
|
|
5
|
+
durationText?: string;
|
|
6
|
+
}
|
|
7
|
+
interface Props {
|
|
8
|
+
nodes: LiteWorkflowNode[];
|
|
9
|
+
title?: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const LiteWorkflowStepper: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type LiteWorkflowStepper = ReturnType<typeof LiteWorkflowStepper>;
|
|
14
|
+
export default LiteWorkflowStepper;
|
|
@@ -2,19 +2,66 @@
|
|
|
2
2
|
import LiteChartSvg from './LiteChartSvg.svelte';
|
|
3
3
|
import LiteChartTable from './LiteChartTable.svelte';
|
|
4
4
|
|
|
5
|
+
interface GaugeThreshold {
|
|
6
|
+
value: number;
|
|
7
|
+
label?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
interface Props {
|
|
6
11
|
title?: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
value?: number;
|
|
14
|
+
min?: number;
|
|
15
|
+
max?: number;
|
|
16
|
+
unit?: string;
|
|
17
|
+
target?: number;
|
|
18
|
+
targetLabel?: string;
|
|
19
|
+
thresholds?: GaugeThreshold[];
|
|
7
20
|
data?: Array<Record<string, unknown>>;
|
|
8
21
|
rows?: Array<Array<string | number>>;
|
|
9
22
|
columns?: string[];
|
|
10
23
|
emptyText?: string;
|
|
11
24
|
}
|
|
12
25
|
|
|
13
|
-
let {
|
|
14
|
-
|
|
26
|
+
let {
|
|
27
|
+
title,
|
|
28
|
+
label,
|
|
29
|
+
value,
|
|
30
|
+
min = 0,
|
|
31
|
+
max = 100,
|
|
32
|
+
unit = '',
|
|
33
|
+
target,
|
|
34
|
+
targetLabel = 'Target',
|
|
35
|
+
thresholds = [],
|
|
36
|
+
data = [],
|
|
37
|
+
rows,
|
|
38
|
+
columns,
|
|
39
|
+
emptyText,
|
|
40
|
+
}: Props = $props();
|
|
41
|
+
|
|
42
|
+
const heading = $derived(title ?? label ?? 'Gauge');
|
|
43
|
+
|
|
44
|
+
const normalized = $derived.by(() => {
|
|
45
|
+
if (rows) return rows;
|
|
46
|
+
if (data.length > 0) {
|
|
47
|
+
return data.map((item) => Object.values(item).map((entry) =>
|
|
48
|
+
typeof entry === 'number' ? entry : String(entry ?? '')
|
|
49
|
+
));
|
|
50
|
+
}
|
|
51
|
+
if (typeof value !== 'number') return [];
|
|
52
|
+
const metricRows: Array<Array<string | number>> = [
|
|
53
|
+
['Value', `${value}${unit}`],
|
|
54
|
+
['Range', `${min} – ${max}${unit}`],
|
|
55
|
+
];
|
|
56
|
+
if (typeof target === 'number') metricRows.push([targetLabel, `${target}${unit}`]);
|
|
57
|
+
for (const threshold of thresholds) {
|
|
58
|
+
metricRows.push([threshold.label ?? 'Threshold', `${threshold.value}${unit}`]);
|
|
59
|
+
}
|
|
60
|
+
return metricRows;
|
|
61
|
+
});
|
|
15
62
|
</script>
|
|
16
63
|
|
|
17
64
|
<div class="lite-chart-widget">
|
|
18
|
-
<LiteChartSvg kind="gauge" rows={normalized} {
|
|
65
|
+
<LiteChartSvg kind="gauge" rows={normalized} title={heading} />
|
|
19
66
|
<LiteChartTable {title} kind="gauge" columns={columns ?? ['Label', 'Value']} rows={normalized} {emptyText} />
|
|
20
67
|
</div>
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
interface GaugeThreshold {
|
|
2
|
+
value: number;
|
|
3
|
+
label?: string;
|
|
4
|
+
}
|
|
1
5
|
interface Props {
|
|
2
6
|
title?: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
value?: number;
|
|
9
|
+
min?: number;
|
|
10
|
+
max?: number;
|
|
11
|
+
unit?: string;
|
|
12
|
+
target?: number;
|
|
13
|
+
targetLabel?: string;
|
|
14
|
+
thresholds?: GaugeThreshold[];
|
|
3
15
|
data?: Array<Record<string, unknown>>;
|
|
4
16
|
rows?: Array<Array<string | number>>;
|
|
5
17
|
columns?: string[];
|
package/dist/index.d.ts
CHANGED
|
@@ -111,6 +111,37 @@ export { default as LiteSkeleton } from './components/LiteSkeleton.svelte';
|
|
|
111
111
|
export { default as LiteSpin } from './components/LiteSpin.svelte';
|
|
112
112
|
export { default as LiteProgress } from './components/LiteProgress.svelte';
|
|
113
113
|
export { default as LiteTree } from './components/LiteTree.svelte';
|
|
114
|
+
export { default as LiteTrendIndicator } from './components/LiteTrendIndicator.svelte';
|
|
115
|
+
export { default as LiteMetricGrid } from './components/LiteMetricGrid.svelte';
|
|
116
|
+
export { default as LiteOrgChart } from './components/LiteOrgChart.svelte';
|
|
117
|
+
export { default as LiteCronExpressionBuilder } from './components/LiteCronExpressionBuilder.svelte';
|
|
118
|
+
export { default as LiteVirtualTreeSelect } from './components/LiteVirtualTreeSelect.svelte';
|
|
119
|
+
export { default as LiteConcurrentConflictModal } from './components/LiteConcurrentConflictModal.svelte';
|
|
120
|
+
export { default as LiteTaskCenter } from './components/LiteTaskCenter.svelte';
|
|
121
|
+
export { default as LiteMicroAppFrame } from './components/LiteMicroAppFrame.svelte';
|
|
122
|
+
export { default as LiteSafeDeleteConfirm } from './components/LiteSafeDeleteConfirm.svelte';
|
|
123
|
+
export type { LiteOrgNode } from './components/LiteOrgChart.svelte';
|
|
124
|
+
export type { LiteVirtualTreeNode } from './components/LiteVirtualTreeSelect.svelte';
|
|
125
|
+
export type { LiteConflictField } from './components/LiteConcurrentConflictModal.svelte';
|
|
126
|
+
export type { LiteTaskStatus, LiteBackgroundTask } from './components/LiteTaskCenter.svelte';
|
|
127
|
+
export type { LiteDeleteImpact } from './components/LiteSafeDeleteConfirm.svelte';
|
|
128
|
+
export { default as LiteKpiCard } from './components/LiteKpiCard.svelte';
|
|
129
|
+
export { default as LiteJsonViewer } from './components/LiteJsonViewer.svelte';
|
|
130
|
+
export { default as LiteResultPage } from './components/LiteResultPage.svelte';
|
|
131
|
+
export { default as LiteWatermarkContainer } from './components/LiteWatermarkContainer.svelte';
|
|
132
|
+
export { default as LiteContextMenu } from './components/LiteContextMenu.svelte';
|
|
133
|
+
export { default as LiteUnsavedChangesGuard } from './components/LiteUnsavedChangesGuard.svelte';
|
|
134
|
+
export { default as LiteAnnouncementBanner } from './components/LiteAnnouncementBanner.svelte';
|
|
135
|
+
export { default as LiteTextDiffViewer } from './components/LiteTextDiffViewer.svelte';
|
|
136
|
+
export { default as LiteAsyncExportModal } from './components/LiteAsyncExportModal.svelte';
|
|
137
|
+
export type { LiteContextMenuItem } from './components/LiteContextMenu.svelte';
|
|
138
|
+
export { default as LiteStepWizard } from './components/LiteStepWizard.svelte';
|
|
139
|
+
export { default as LiteWorkflowStepper } from './components/LiteWorkflowStepper.svelte';
|
|
140
|
+
export { default as LiteDualApprovalGate } from './components/LiteDualApprovalGate.svelte';
|
|
141
|
+
export { default as LiteKeyboardShortcutsModal } from './components/LiteKeyboardShortcutsModal.svelte';
|
|
142
|
+
export type { LiteStepItem } from './components/LiteStepWizard.svelte';
|
|
143
|
+
export type { LiteWorkflowNode } from './components/LiteWorkflowStepper.svelte';
|
|
144
|
+
export type { LiteShortcutItem } from './components/LiteKeyboardShortcutsModal.svelte';
|
|
114
145
|
export { configureMarkdownRenderer, escapeHtml, renderInlineMarkdown, renderMarkdown, renderRichContent, sanitizeRichTextHtml, } from './rich-content';
|
|
115
146
|
export type { MarkdownRenderOptions } from './rich-content';
|
|
116
147
|
export * from './components/compatibility/index';
|
package/dist/index.js
CHANGED
|
@@ -115,6 +115,30 @@ export { default as LiteSkeleton } from './components/LiteSkeleton.svelte';
|
|
|
115
115
|
export { default as LiteSpin } from './components/LiteSpin.svelte';
|
|
116
116
|
export { default as LiteProgress } from './components/LiteProgress.svelte';
|
|
117
117
|
export { default as LiteTree } from './components/LiteTree.svelte';
|
|
118
|
+
// Recent enterprise UI parity fallbacks
|
|
119
|
+
export { default as LiteTrendIndicator } from './components/LiteTrendIndicator.svelte';
|
|
120
|
+
export { default as LiteMetricGrid } from './components/LiteMetricGrid.svelte';
|
|
121
|
+
export { default as LiteOrgChart } from './components/LiteOrgChart.svelte';
|
|
122
|
+
export { default as LiteCronExpressionBuilder } from './components/LiteCronExpressionBuilder.svelte';
|
|
123
|
+
export { default as LiteVirtualTreeSelect } from './components/LiteVirtualTreeSelect.svelte';
|
|
124
|
+
export { default as LiteConcurrentConflictModal } from './components/LiteConcurrentConflictModal.svelte';
|
|
125
|
+
export { default as LiteTaskCenter } from './components/LiteTaskCenter.svelte';
|
|
126
|
+
export { default as LiteMicroAppFrame } from './components/LiteMicroAppFrame.svelte';
|
|
127
|
+
export { default as LiteSafeDeleteConfirm } from './components/LiteSafeDeleteConfirm.svelte';
|
|
128
|
+
// Enterprise suites SSR parity fallbacks
|
|
129
|
+
export { default as LiteKpiCard } from './components/LiteKpiCard.svelte';
|
|
130
|
+
export { default as LiteJsonViewer } from './components/LiteJsonViewer.svelte';
|
|
131
|
+
export { default as LiteResultPage } from './components/LiteResultPage.svelte';
|
|
132
|
+
export { default as LiteWatermarkContainer } from './components/LiteWatermarkContainer.svelte';
|
|
133
|
+
export { default as LiteContextMenu } from './components/LiteContextMenu.svelte';
|
|
134
|
+
export { default as LiteUnsavedChangesGuard } from './components/LiteUnsavedChangesGuard.svelte';
|
|
135
|
+
export { default as LiteAnnouncementBanner } from './components/LiteAnnouncementBanner.svelte';
|
|
136
|
+
export { default as LiteTextDiffViewer } from './components/LiteTextDiffViewer.svelte';
|
|
137
|
+
export { default as LiteAsyncExportModal } from './components/LiteAsyncExportModal.svelte';
|
|
138
|
+
export { default as LiteStepWizard } from './components/LiteStepWizard.svelte';
|
|
139
|
+
export { default as LiteWorkflowStepper } from './components/LiteWorkflowStepper.svelte';
|
|
140
|
+
export { default as LiteDualApprovalGate } from './components/LiteDualApprovalGate.svelte';
|
|
141
|
+
export { default as LiteKeyboardShortcutsModal } from './components/LiteKeyboardShortcutsModal.svelte';
|
|
118
142
|
// Rich content rendering (SSR-safe Markdown + rich HTML allowlist)
|
|
119
143
|
export { configureMarkdownRenderer, escapeHtml, renderInlineMarkdown, renderMarkdown, renderRichContent, sanitizeRichTextHtml, } from './rich-content';
|
|
120
144
|
// Compatibility fallbacks for browser-only and third-party UI capabilities.
|
package/dist/rich-content.js
CHANGED
|
@@ -458,7 +458,7 @@ export function sanitizeRichTextHtml(value) {
|
|
|
458
458
|
}
|
|
459
459
|
const attributes = [];
|
|
460
460
|
const isCheckbox = tag === 'input' && /type\s*=\s*["']?checkbox/iu.test(match[2] ?? '');
|
|
461
|
-
if (
|
|
461
|
+
if (tag === 'input' && !isCheckbox)
|
|
462
462
|
continue;
|
|
463
463
|
for (const attribute of (match[2] ?? '').matchAll(ATTRIBUTE)) {
|
|
464
464
|
const name = (attribute[1] ?? '').toLowerCase();
|