@tellegen/svelte 0.4.3 → 0.4.5

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 (115) hide show
  1. package/README.md +45 -0
  2. package/dist/TellegenMap.svelte +63 -22
  3. package/dist/TellegenProvider.svelte +7 -4
  4. package/dist/TellegenShell.svelte +12 -1
  5. package/dist/TellegenViewer.svelte +2 -0
  6. package/dist/basemap.d.ts +14 -0
  7. package/dist/basemap.js +27 -0
  8. package/dist/colors.d.ts +6 -1
  9. package/dist/colors.js +11 -4
  10. package/dist/components/DiagnosticLogView.svelte +176 -0
  11. package/dist/components/DiagnosticLogView.svelte.d.ts +11 -0
  12. package/dist/components/FormulationSelector.svelte +1 -1
  13. package/dist/components/LocalCaseDetails.svelte +18 -3
  14. package/dist/components/LogEntryView.svelte +188 -0
  15. package/dist/components/LogEntryView.svelte.d.ts +11 -0
  16. package/dist/components/LogPanel.svelte +25 -0
  17. package/dist/components/LogPanel.svelte.d.ts +3 -0
  18. package/dist/components/McResults.svelte +18 -3
  19. package/dist/components/McWorkbench.svelte +688 -0
  20. package/dist/components/McWorkbench.svelte.d.ts +38 -0
  21. package/dist/components/MultiWire.svelte +136 -0
  22. package/dist/components/MultiWire.svelte.d.ts +7 -0
  23. package/dist/components/MulticonductorDetails.svelte +7 -0
  24. package/dist/components/NotificationCenter.svelte +37 -6
  25. package/dist/components/OmniSearch.svelte +163 -0
  26. package/dist/components/OmniSearch.svelte.d.ts +14 -0
  27. package/dist/components/ResultsTable.svelte +259 -0
  28. package/dist/components/ResultsTable.svelte.d.ts +13 -0
  29. package/dist/components/SchematicCanvas.svelte +1896 -0
  30. package/dist/components/SchematicCanvas.svelte.d.ts +13 -0
  31. package/dist/components/SolveCard.svelte +6 -0
  32. package/dist/components/schematic/PickCard.svelte +126 -0
  33. package/dist/components/schematic/PickCard.svelte.d.ts +56 -0
  34. package/dist/components/schematic/export.d.ts +21 -0
  35. package/dist/components/schematic/export.js +110 -0
  36. package/dist/components/schematic/layers.d.ts +161 -0
  37. package/dist/components/schematic/layers.js +756 -0
  38. package/dist/components/schematic/paint.d.ts +28 -0
  39. package/dist/components/schematic/paint.js +69 -0
  40. package/dist/components/schematic/palette.d.ts +34 -0
  41. package/dist/components/schematic/palette.js +54 -0
  42. package/dist/components/schematic/text.d.ts +83 -0
  43. package/dist/components/schematic/text.js +190 -0
  44. package/dist/components/schematic/view-prefs.svelte.d.ts +30 -0
  45. package/dist/components/schematic/view-prefs.svelte.js +77 -0
  46. package/dist/components.d.ts +4 -0
  47. package/dist/components.js +4 -0
  48. package/dist/context.svelte.d.ts +2 -0
  49. package/dist/context.svelte.js +2 -0
  50. package/dist/controller.svelte.d.ts +40 -5
  51. package/dist/controller.svelte.js +230 -25
  52. package/dist/diagram/basemap.d.ts +28 -0
  53. package/dist/diagram/basemap.js +39 -0
  54. package/dist/diagram/bus-stacks.d.ts +19 -0
  55. package/dist/diagram/bus-stacks.js +99 -0
  56. package/dist/diagram/colour-modes.d.ts +18 -0
  57. package/dist/diagram/colour-modes.js +33 -0
  58. package/dist/diagram/connections.d.ts +30 -0
  59. package/dist/diagram/connections.js +129 -0
  60. package/dist/diagram/display-tree.d.ts +21 -0
  61. package/dist/diagram/display-tree.js +65 -0
  62. package/dist/diagram/energisation.d.ts +10 -0
  63. package/dist/diagram/energisation.js +31 -0
  64. package/dist/diagram/feeders.d.ts +30 -0
  65. package/dist/diagram/feeders.js +57 -0
  66. package/dist/diagram/galvanic-zones.d.ts +60 -0
  67. package/dist/diagram/galvanic-zones.js +210 -0
  68. package/dist/diagram/graph-inputs.d.ts +18 -0
  69. package/dist/diagram/graph-inputs.js +103 -0
  70. package/dist/diagram/index.d.ts +28 -0
  71. package/dist/diagram/index.js +28 -0
  72. package/dist/diagram/landmarks.d.ts +50 -0
  73. package/dist/diagram/landmarks.js +153 -0
  74. package/dist/diagram/layout-morph.d.ts +15 -0
  75. package/dist/diagram/layout-morph.js +32 -0
  76. package/dist/diagram/multi-wire.d.ts +44 -0
  77. package/dist/diagram/multi-wire.js +65 -0
  78. package/dist/diagram/phase-bars.d.ts +35 -0
  79. package/dist/diagram/phase-bars.js +44 -0
  80. package/dist/diagram/results-table.d.ts +47 -0
  81. package/dist/diagram/results-table.js +173 -0
  82. package/dist/diagram/schematic-equipment.d.ts +133 -0
  83. package/dist/diagram/schematic-equipment.js +645 -0
  84. package/dist/diagram/schematic-layout.d.ts +51 -0
  85. package/dist/diagram/schematic-layout.js +240 -0
  86. package/dist/diagram/search.d.ts +36 -0
  87. package/dist/diagram/search.js +48 -0
  88. package/dist/diagram/shared-routes.d.ts +21 -0
  89. package/dist/diagram/shared-routes.js +40 -0
  90. package/dist/diagram/short-names.d.ts +11 -0
  91. package/dist/diagram/short-names.js +54 -0
  92. package/dist/diagram/snapshot.d.ts +115 -0
  93. package/dist/diagram/snapshot.js +242 -0
  94. package/dist/diagram/summary.d.ts +65 -0
  95. package/dist/diagram/summary.js +144 -0
  96. package/dist/diagram/svg-export.d.ts +80 -0
  97. package/dist/diagram/svg-export.js +108 -0
  98. package/dist/diagram/tree-walk.d.ts +13 -0
  99. package/dist/diagram/tree-walk.js +83 -0
  100. package/dist/diagram/value-labels.d.ts +24 -0
  101. package/dist/diagram/value-labels.js +69 -0
  102. package/dist/diagram/view-state.d.ts +12 -0
  103. package/dist/diagram/view-state.js +22 -0
  104. package/dist/diagram/voltage-levels.d.ts +14 -0
  105. package/dist/diagram/voltage-levels.js +20 -0
  106. package/dist/index.d.ts +3 -0
  107. package/dist/index.js +2 -0
  108. package/dist/log.svelte.d.ts +77 -0
  109. package/dist/log.svelte.js +149 -0
  110. package/dist/notices.svelte.d.ts +3 -0
  111. package/dist/state.svelte.d.ts +42 -5
  112. package/dist/state.svelte.js +56 -4
  113. package/dist/transformer-icon.d.ts +22 -13
  114. package/dist/transformer-icon.js +23 -13
  115. package/package.json +2 -2
@@ -154,15 +154,22 @@
154
154
  {/if}
155
155
  {@render note?.(lc)}
156
156
  {#if lc.summary && lc.studyInputJson}
157
+ {@const exportUnavailable = ctrl.caseExportUnavailableReason(lc)}
157
158
  <div class="case-actions">
158
- <button class="reset" disabled={busy} onclick={() => saveCase(lc)}>Save case</button>
159
+ <button
160
+ class="reset"
161
+ disabled={busy || !!exportUnavailable}
162
+ title={exportUnavailable ?? undefined}
163
+ onclick={() => saveCase(lc)}>Save case</button
164
+ >
159
165
  {#if lc.formulation === 'dcopf' && lc.solution}
160
166
  <button class="reset" disabled={busy} onclick={() => saveSolution(lc)}>Save solution</button
161
167
  >
162
168
  {/if}
163
169
  <button
164
170
  class="reset"
165
- disabled={busy}
171
+ disabled={busy || !!exportUnavailable}
172
+ title={exportUnavailable ?? undefined}
166
173
  aria-expanded={exportOpen}
167
174
  aria-controls="case-export-formats"
168
175
  onclick={() => (exportOpen = !exportOpen)}
@@ -175,7 +182,9 @@
175
182
  </button>
176
183
  {/if}
177
184
  </div>
178
- {#if exportOpen}
185
+ {#if exportUnavailable}
186
+ <p class="unavailable">{exportUnavailable}</p>
187
+ {:else if exportOpen}
179
188
  <ul class="case-actions" id="case-export-formats" aria-label="Export formats">
180
189
  {#each EXPORT_FORMATS as f (f.token)}
181
190
  <li>
@@ -266,4 +275,10 @@
266
275
  .case-actions .reset {
267
276
  margin-top: 0;
268
277
  }
278
+
279
+ .unavailable {
280
+ margin: 8px 0 0;
281
+ font-size: 12px;
282
+ color: var(--text-secondary);
283
+ }
269
284
  </style>
@@ -0,0 +1,188 @@
1
+ <script lang="ts">
2
+ import type { LogEntry, LogEntryInput } from '../log.svelte.js';
3
+ let {
4
+ entry,
5
+ showSubject = true,
6
+ onbus
7
+ }: {
8
+ entry: LogEntryInput | LogEntry;
9
+ /** Off inside a group that already names the subject. */
10
+ showSubject?: boolean;
11
+ /** Makes each named bus a button, for a host that can select it. */
12
+ onbus?: (bus: number, entry: LogEntryInput) => void;
13
+ } = $props();
14
+ const LABEL = { error: 'Error', warning: 'Warning', note: 'Note' } as const;
15
+ const MAX_BUSES = 12;
16
+ const count = $derived('count' in entry ? entry.count : 1);
17
+ const buses = $derived(entry.buses ?? []);
18
+ const details = $derived(
19
+ Object.entries(entry.details ?? {}).map(
20
+ ([key, value]) => [key, typeof value === 'string' ? value : JSON.stringify(value)] as const
21
+ )
22
+ );
23
+ </script>
24
+
25
+ <div class="entry" data-severity={entry.severity} data-testid="log-entry">
26
+ <span class="severity">{LABEL[entry.severity]}</span>
27
+ <div class="body">
28
+ <p class="message">
29
+ {entry.message}{#if count > 1}<span class="count" aria-label={`reported ${count} times`}
30
+ >{count}×</span
31
+ >{/if}
32
+ </p>
33
+ <dl class="meta">
34
+ <div>
35
+ <dt>From</dt>
36
+ <dd>{entry.source}</dd>
37
+ </div>
38
+ {#if entry.code}<div>
39
+ <dt>Code</dt>
40
+ <dd class="mono">{entry.code}</dd>
41
+ </div>{/if}
42
+ {#if showSubject && entry.subject}<div>
43
+ <dt>In</dt>
44
+ <dd>{entry.subject}</dd>
45
+ </div>{/if}
46
+ {#if entry.target}<div>
47
+ <dt>Element</dt>
48
+ <dd class="mono">{entry.target}</dd>
49
+ </div>{/if}
50
+ </dl>
51
+ {#if buses.length}
52
+ <p class="buses">
53
+ <span class="label">{buses.length === 1 ? 'Bus' : 'Buses'}</span>
54
+ {#each buses.slice(0, MAX_BUSES) as bus (bus)}
55
+ {#if onbus}<button type="button" onclick={() => onbus(bus, entry)}>{bus}</button
56
+ >{:else}<span class="bus">{bus}</span>{/if}
57
+ {/each}
58
+ {#if buses.length > MAX_BUSES}<span class="more">and {buses.length - MAX_BUSES} more</span
59
+ >{/if}
60
+ </p>
61
+ {/if}
62
+ {#if entry.hint}<p class="hint">{entry.hint}</p>{/if}
63
+ {#if details.length}
64
+ <details>
65
+ <summary>Details</summary>
66
+ <dl class="details">
67
+ {#each details as [key, value] (key)}
68
+ <div>
69
+ <dt class="mono">{key}</dt>
70
+ <dd class="mono">{value}</dd>
71
+ </div>
72
+ {/each}
73
+ </dl>
74
+ </details>
75
+ {/if}
76
+ </div>
77
+ </div>
78
+
79
+ <style>
80
+ .entry {
81
+ --log-warning: #8a5300;
82
+ display: grid;
83
+ grid-template-columns: 62px minmax(0, 1fr);
84
+ gap: 8px;
85
+ font: var(--fs-meta, 12px) / 1.45 var(--font-display);
86
+ color: var(--text-primary, var(--ink));
87
+ }
88
+ :global(:root[data-theme='dark']) .entry {
89
+ --log-warning: #f0c36d;
90
+ }
91
+ .severity {
92
+ font: 600 10px/1.9 var(--font-mono);
93
+ text-transform: uppercase;
94
+ letter-spacing: 0.04em;
95
+ color: var(--text-secondary);
96
+ }
97
+ [data-severity='error'] .severity {
98
+ color: var(--text-danger, var(--red));
99
+ }
100
+ [data-severity='warning'] .severity {
101
+ color: var(--log-warning);
102
+ }
103
+ .body {
104
+ min-width: 0;
105
+ }
106
+ p {
107
+ margin: 0;
108
+ }
109
+ .message {
110
+ overflow-wrap: anywhere;
111
+ }
112
+ .count {
113
+ margin-left: 6px;
114
+ font: 10px var(--font-mono);
115
+ color: var(--text-secondary);
116
+ }
117
+ .meta {
118
+ display: flex;
119
+ flex-wrap: wrap;
120
+ gap: 2px 12px;
121
+ margin: 3px 0 0;
122
+ color: var(--text-secondary);
123
+ }
124
+ .meta div,
125
+ .details div {
126
+ display: flex;
127
+ gap: 4px;
128
+ min-width: 0;
129
+ }
130
+ dt {
131
+ color: var(--text-tertiary, var(--text-secondary));
132
+ }
133
+ dd {
134
+ margin: 0;
135
+ overflow-wrap: anywhere;
136
+ }
137
+ .mono {
138
+ font-family: var(--font-mono);
139
+ font-size: 11px;
140
+ }
141
+ .buses {
142
+ display: flex;
143
+ flex-wrap: wrap;
144
+ align-items: center;
145
+ gap: 4px;
146
+ margin-top: 4px;
147
+ }
148
+ .label,
149
+ .more {
150
+ color: var(--text-secondary);
151
+ }
152
+ .bus,
153
+ .buses button {
154
+ font: 11px var(--font-mono);
155
+ padding: 1px 6px;
156
+ border-radius: 3px;
157
+ background: var(--surface-chip, var(--accent-soft));
158
+ color: inherit;
159
+ border: 0;
160
+ }
161
+ .buses button {
162
+ cursor: pointer;
163
+ }
164
+ .buses button:hover {
165
+ background: var(--accent-soft);
166
+ }
167
+ .buses button:focus-visible,
168
+ summary:focus-visible {
169
+ outline: 2px solid var(--focus-ring);
170
+ outline-offset: 2px;
171
+ }
172
+ .hint {
173
+ margin-top: 4px;
174
+ color: var(--text-secondary);
175
+ }
176
+ details {
177
+ margin-top: 4px;
178
+ }
179
+ summary {
180
+ cursor: pointer;
181
+ color: var(--text-secondary);
182
+ }
183
+ .details {
184
+ display: grid;
185
+ gap: 2px;
186
+ margin: 4px 0 0;
187
+ }
188
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { LogEntry, LogEntryInput } from '../log.svelte.js';
2
+ type $$ComponentProps = {
3
+ entry: LogEntryInput | LogEntry;
4
+ /** Off inside a group that already names the subject. */
5
+ showSubject?: boolean;
6
+ /** Makes each named bus a button, for a host that can select it. */
7
+ onbus?: (bus: number, entry: LogEntryInput) => void;
8
+ };
9
+ declare const LogEntryView: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type LogEntryView = ReturnType<typeof LogEntryView>;
11
+ export default LogEntryView;
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import { getAppState, getController } from '../context.svelte.js';
3
+ import DiagnosticLogView from './DiagnosticLogView.svelte';
4
+ import PanelFrame from './PanelFrame.svelte';
5
+ const app = getAppState();
6
+ const ctrl = getController();
7
+ let open = $state(false);
8
+ // A bus named in a finding selects that bus on the case on screen.
9
+ function selectBus(bus: number) {
10
+ if (app.activeLocal) void ctrl.selectLocalBus(app.activeLocal.id, bus);
11
+ else if (app.activeCaseId) ctrl.selectBus(app.activeCaseId, bus);
12
+ }
13
+ </script>
14
+
15
+ <PanelFrame id="log" title="Log" side="right" order={40} width={360} bind:open>
16
+ <div class="log-body">
17
+ <DiagnosticLogView onbus={selectBus} />
18
+ </div>
19
+ </PanelFrame>
20
+
21
+ <style>
22
+ .log-body {
23
+ padding: 12px 14px;
24
+ }
25
+ </style>
@@ -0,0 +1,3 @@
1
+ declare const LogPanel: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type LogPanel = ReturnType<typeof LogPanel>;
3
+ export default LogPanel;
@@ -40,6 +40,17 @@
40
40
  });
41
41
  let busChoice = $state('');
42
42
  let edgeChoice = $state('');
43
+ /** One entry per equipment id. A multi-winding transformer projects to several graph edges
44
+ * that share its id (one per winding pair), so the edges are grouped by id. */
45
+ const equipmentOptions = $derived.by(() => {
46
+ const byId = new Map<string, string[]>();
47
+ for (const edge of graph?.edges ?? []) {
48
+ const ends = byId.get(edge.id) ?? [];
49
+ ends.push(`${edge.from} - ${edge.to}`);
50
+ byId.set(edge.id, ends);
51
+ }
52
+ return [...byId].map(([id, ends]) => ({ id, label: `${ends.join(', ')}, ${id}` }));
53
+ });
43
54
  const busId = $derived(
44
55
  selectedBus ??
45
56
  (graph?.buses.some((b) => b.id === busChoice) ? busChoice : graph?.buses[0]?.id) ??
@@ -127,7 +138,11 @@
127
138
  </div>
128
139
  <div>
129
140
  <dt>Load voltage range</dt>
130
- <dd>{summary.min_voltage_pu == null || summary.max_voltage_pu == null ? 'n/a' : `${fixed(summary.min_voltage_pu)}–${fixed(summary.max_voltage_pu)} pu`}</dd>
141
+ <dd>
142
+ {summary.min_voltage_pu == null || summary.max_voltage_pu == null
143
+ ? 'n/a'
144
+ : `${fixed(summary.min_voltage_pu)}–${fixed(summary.max_voltage_pu)} pu`}
145
+ </dd>
131
146
  </div>
132
147
  <div>
133
148
  <dt>Source P / Q</dt>
@@ -228,8 +243,8 @@
228
243
  selectedEdge = null;
229
244
  portPage = 0;
230
245
  }}
231
- ><option value="">All equipment</option>{#each graph?.edges ?? [] as edge (edge.id)}<option
232
- value={edge.id}>{edge.from} - {edge.to}, {edge.id}</option
246
+ ><option value="">All equipment</option>{#each equipmentOptions as option, i (i)}<option
247
+ value={option.id}>{option.label}</option
233
248
  >{/each}</select
234
249
  ></label
235
250
  >