|
21 | 21 | import { NODE_TYPES } from '$lib/constants/nodeTypes'; |
22 | 22 | import { exportRecordingData } from '$lib/utils/csvExport'; |
23 | 23 | import { createRecordingDataState } from '$lib/stores/recordingData.svelte'; |
| 24 | + import { getPortLabelConfigs } from '$lib/nodes/uiConfig'; |
| 25 | + import { PORT_NAME } from '$lib/constants/handles'; |
24 | 26 |
|
25 | 27 | // Code preview state (declared early — referenced by subscription below) |
26 | 28 | let showCode = $state(false); |
|
177 | 179 | closeNodeDialog(); |
178 | 180 | } |
179 | 181 |
|
| 182 | + // Port-label editing — hide for blocks whose port names are driven by a |
| 183 | + // regular param (Scope.labels, Adder.operations, …); for those the param |
| 184 | + // itself is the source of truth and editing port names directly would be |
| 185 | + // overwritten on the next param change. |
| 186 | + const hasParamDrivenPortLabels = $derived(node ? getPortLabelConfigs(node.type).length > 0 : false); |
| 187 | + const showPortLabels = $derived( |
| 188 | + !!node && !hasParamDrivenPortLabels && (node.inputs.length > 0 || node.outputs.length > 0) |
| 189 | + ); |
| 190 | +
|
| 191 | + function handlePortNameChange(direction: 'input' | 'output', index: number, value: string) { |
| 192 | + if (!node) return; |
| 193 | + const id = node.id; |
| 194 | + const trimmed = value.trim(); |
| 195 | + const fallback = direction === 'input' ? PORT_NAME.input(index) : PORT_NAME.output(index); |
| 196 | + const name = trimmed === '' ? fallback : trimmed; |
| 197 | + historyStore.mutate(() => graphStore.updateNodePortName(id, direction, index, name)); |
| 198 | + } |
| 199 | +
|
180 | 200 | // Check if node is a recording node (Scope or Spectrum) |
181 | 201 | const isRecordingNode = $derived(node?.type === 'Scope' || node?.type === 'Spectrum'); |
182 | 202 |
|
|
408 | 428 | <div class="no-params">No configurable parameters</div> |
409 | 429 | {/if} |
410 | 430 |
|
| 431 | + <!-- Port labels — customise the names shown on each handle --> |
| 432 | + {#if showPortLabels} |
| 433 | + <div class="section"> |
| 434 | + <div class="section-title">Port labels</div> |
| 435 | + <div class="params-grid"> |
| 436 | + {#each node.inputs as port, i (port.id)} |
| 437 | + <div class="param-item"> |
| 438 | + <label for="port-in-{i}">in {i}</label> |
| 439 | + <input |
| 440 | + id="port-in-{i}" |
| 441 | + type="text" |
| 442 | + value={port.name} |
| 443 | + placeholder={PORT_NAME.input(i)} |
| 444 | + onchange={(e) => handlePortNameChange('input', i, e.currentTarget.value)} |
| 445 | + /> |
| 446 | + </div> |
| 447 | + {/each} |
| 448 | + {#each node.outputs as port, i (port.id)} |
| 449 | + <div class="param-item"> |
| 450 | + <label for="port-out-{i}">out {i}</label> |
| 451 | + <input |
| 452 | + id="port-out-{i}" |
| 453 | + type="text" |
| 454 | + value={port.name} |
| 455 | + placeholder={PORT_NAME.output(i)} |
| 456 | + onchange={(e) => handlePortNameChange('output', i, e.currentTarget.value)} |
| 457 | + /> |
| 458 | + </div> |
| 459 | + {/each} |
| 460 | + </div> |
| 461 | + </div> |
| 462 | + {/if} |
| 463 | + |
411 | 464 | <!-- Documentation section (lazy loaded) --> |
412 | 465 | <DocumentationSection docstringHtml={docstringHtml} /> |
413 | 466 | {/if} |
|
0 commit comments