refactor: only show group/node panel when selected

This commit is contained in:
2026-05-04 23:47:03 +02:00
parent 106797de32
commit 83e0e47082
6 changed files with 94 additions and 110 deletions
@@ -556,7 +556,7 @@ export class GraphManager extends EventEmitter<{
const inputs = { const inputs = {
'groupId': { 'groupId': {
type: 'select', type: 'select',
label: 'Group', label: '',
value: node.props?.groupId, value: node.props?.groupId,
internal: true, internal: true,
options: this.graph.groups.map((g, i) => ({ options: this.graph.groups.map((g, i) => ({
+2 -1
View File
@@ -5,7 +5,8 @@ export const debugNode = {
}, },
inputs: { inputs: {
input: { input: {
type: '*' type: '*',
label: ''
} }
}, },
execute(_data: Int32Array): Int32Array { execute(_data: Int32Array): Int32Array {
@@ -1,99 +0,0 @@
<script lang="ts">
import type { GraphManager } from '$lib/graph-interface/graph-manager.svelte';
import NestedSettings from '$lib/settings/NestedSettings.svelte';
import type { NodeId, NodeInput, NodeInstance } from '@nodarium/types';
type InternalNodeInput = NodeInput & {
__node_type?: NodeId;
__node_input: string;
};
type Props = {
manager: GraphManager;
node: NodeInstance;
};
const { manager, node = $bindable() }: Props = $props();
function filterInputs(inputs?: Record<string, NodeInput>) {
const _inputs = $state.snapshot(
inputs as Record<string, InternalNodeInput>
);
return Object.fromEntries(
Object.entries(structuredClone(_inputs ?? {}))
.filter(([, value]) => {
return value.hidden === true;
})
.map(([key, value]) => {
value.__node_type = node.state.type?.id;
value.__node_input = key;
return [key, value];
})
);
}
const nodeDefinition = filterInputs(node.state.type?.inputs);
type Store = Record<string, number | number[]>;
let store = $state<Store>(createStore(node?.props, nodeDefinition));
function createStore(
props: NodeInstance['props'],
inputs: Record<string, NodeInput>
): Store {
const store: Store = {};
Object.keys(inputs).forEach((key) => {
if (props) {
const value = props[key] !== undefined ? props[key] : inputs[key].value;
if (Array.isArray(value) || typeof value === 'number') {
store[key] = value;
} else if (typeof value === 'boolean') {
store[key] = value ? 1 : 0;
} else {
console.error('Wrong error', { value });
}
}
});
return store;
}
let lastPropsHash = '';
function updateNode() {
if (!node || !store) return;
let needsUpdate = false;
Object.keys(store).forEach((_key: string) => {
node.props = node.props || {};
const key = _key as keyof typeof store;
if (node && store) {
needsUpdate = true;
const value = store[key];
if (value !== undefined) {
node.props[key] = value;
}
}
});
let propsHash = JSON.stringify(node.props);
if (propsHash === lastPropsHash) {
return;
}
lastPropsHash = propsHash;
if (needsUpdate) {
manager.save();
manager.execute();
}
}
$effect(() => {
if (store) {
updateNode();
}
});
</script>
{#if Object.keys(nodeDefinition).length}
<NestedSettings
id="activeNodeSettings"
bind:value={store}
type={nodeDefinition}
/>
{/if}
@@ -1,21 +1,103 @@
<script lang="ts"> <script lang="ts">
import type { GraphManager } from '$lib/graph-interface/graph-manager.svelte'; import type { GraphManager } from '$lib/graph-interface/graph-manager.svelte';
import type { NodeInstance } from '@nodarium/types'; import NestedSettings from '$lib/settings/NestedSettings.svelte';
import ActiveNodeSelected from './ActiveNodeSelected.svelte'; import type { NodeId, NodeInput, NodeInstance } from '@nodarium/types';
type InternalNodeInput = NodeInput & {
__node_type?: NodeId;
__node_input: string;
};
type Props = { type Props = {
manager: GraphManager; manager: GraphManager;
node: NodeInstance | undefined; node: NodeInstance | undefined;
}; };
let { manager, node = $bindable() }: Props = $props(); const { manager, node = $bindable() }: Props = $props();
function filterInputs(inputs?: Record<string, NodeInput>) {
if (!node) return {};
return Object.fromEntries(
Object.entries(inputs ?? {})
.filter(([, value]) => {
return value.hidden === true;
})
.map(([key, value]) => {
const v = value as InternalNodeInput;
v.__node_type = node.state.type?.id;
v.__node_input = key;
return [key, v];
})
);
}
const nodeDefinition = node ? filterInputs(node.state.type?.inputs) : {};
type Store = Record<string, number | number[]>;
let store = $state<Store>(createStore(node?.props, nodeDefinition));
function createStore(
props: NodeInstance['props'],
inputs: Record<string, NodeInput>
): Store {
const store: Store = {};
Object.keys(inputs).forEach((key) => {
if (props) {
const value = props[key] !== undefined ? props[key] : inputs[key].value;
if (Array.isArray(value) || typeof value === 'number') {
store[key] = value;
} else if (typeof value === 'boolean') {
store[key] = value ? 1 : 0;
} else {
console.error('Wrong error', { value });
}
}
});
return store;
}
let lastPropsHash = '';
function updateNode() {
if (!node || !store) return;
let needsUpdate = false;
Object.keys(store).forEach((_key: string) => {
node.props = node.props || {};
const key = _key as keyof typeof store;
if (node && store) {
needsUpdate = true;
const value = store[key];
if (value !== undefined) {
node.props[key] = value;
}
}
});
let propsHash = JSON.stringify(node.props);
if (propsHash === lastPropsHash) {
return;
}
lastPropsHash = propsHash;
if (needsUpdate) {
manager.save();
manager.execute();
}
}
const isGroupInstance = $derived(node?.type === '__internal/group/instance'); const isGroupInstance = $derived(node?.type === '__internal/group/instance');
$effect(() => {
if (store) {
updateNode();
}
});
</script> </script>
{#if node && !isGroupInstance} {#if !isGroupInstance && Object.keys(nodeDefinition).length}
<div class='{node?"border-l-2 pl-3.5!":""} bg-layer-2 flex items-center h-[70px] border-b-1 border-l-selected border-b-outline pl-4'> <div class='{node?"border-l-2 pl-3.5!":""} bg-layer-2 flex items-center h-[70px] border-b-1 border-l-selected border-b-outline pl-4'>
<h3>Node Settings</h3> <h3>Node Settings</h3>
</div> </div>
<ActiveNodeSelected {manager} bind:node /> <NestedSettings
id="activeNodeSettings"
bind:value={store}
type={nodeDefinition}
/>
{/if} {/if}
@@ -10,10 +10,8 @@
const { manager, node = $bindable() }: Props = $props(); const { manager, node = $bindable() }: Props = $props();
const activeGroup = $derived.by(() => { const activeGroup = $derived.by(() => {
console.log('isInsideGroup', manager?.isInsideGroup);
if (manager?.isInsideGroup) { if (manager?.isInsideGroup) {
const activeGroupId = manager.graphStack?.at(-1)?.groupId; const activeGroupId = manager.graphStack?.at(-1)?.groupId;
console.log('activeGroupId', activeGroupId);
if (activeGroupId !== undefined) { if (activeGroupId !== undefined) {
return manager.getGroup(activeGroupId); return manager.getGroup(activeGroupId);
} }
+4 -2
View File
@@ -343,8 +343,10 @@
type={graphSettingTypes} type={graphSettingTypes}
bind:value={graphSettings} bind:value={graphSettings}
/> />
<ActiveNodeSettings {manager} bind:node={activeNode} /> {#key activeNode}
<GroupSettings {manager} bind:node={activeNode} /> <ActiveNodeSettings {manager} bind:node={activeNode} />
<GroupSettings {manager} bind:node={activeNode} />
{/key}
</Panel> </Panel>
<Panel <Panel
id="changelog" id="changelog"