{#if showAddMenu}
{/if}
{#if connectionMode || mountMode}
{#if connectionMode} {#if connectionSource} Click target service {:else} Click source service {/if} {:else if mountMode} {#if mountSource} Click target service {:else} Click volume/network/config/secret {/if} {/if}
{/if}
{#if showLayoutMenu}
showLayoutMenu = false} >
{/if}
{#if parseError}

YAML Parse Error

{parseError}

{/if}
Service
Network
Volume
Config
Secret
{#if selectedNode || selectedEdge}
{#if selectedNode} {@const NodeIcon = getNodeIcon(selectedNode.type)}

{selectedNode.label}

{selectedNode.type}

{#if (selectedNode.type === 'service' && serviceEditDirty) || (selectedNode.type === 'network' && networkEditDirty) || (selectedNode.type === 'volume' && volumeEditDirty) || (selectedNode.type === 'config' && configEditDirty) || (selectedNode.type === 'secret' && secretEditDirty)} {/if}
{:else if selectedEdge}

{selectedEdge.type.replace('-', ' ')}

{selectedEdge.source.replace(/^(service|network|volume|config|secret)-/, '')} → {selectedEdge.target.replace(/^(service|network|volume|config|secret)-/, '')}

{/if}
{#if selectedNode} {#if selectedNode.type === 'service'}
Image
Command
Restart policy { serviceEditDirty = true; }}> {editServiceRestart === 'no' ? 'No' : editServiceRestart === 'always' ? 'Always' : editServiceRestart === 'on-failure' ? 'On failure' : 'Unless stopped'}
Port mappings
{#each editServicePorts as port, index}
Host
Container
{/each}
Volumes
{#each editServiceVolumes as vol, index}
Host
Container
{/each}
Environment
{#each editServiceEnvVars as env, index}
Key
Value
{/each}
Labels
{#each editServiceLabels as label, index}
Key
Value
{/each}
{#if selectedNode.dependsOn?.length > 0}
Depends on
{#each selectedNode.dependsOn as dep}
{dep}
{/each}
{/if}
{:else if selectedNode.type === 'network'}
Driver { networkEditDirty = true; }}> {#if editNetworkDriver === 'bridge'} {:else if editNetworkDriver === 'host'} {:else if editNetworkDriver === 'overlay'} {:else if editNetworkDriver === 'macvlan'} {:else if editNetworkDriver === 'ipvlan'} {:else} {/if} {editNetworkDriver} {#snippet children()}
Bridge
{/snippet}
{#snippet children()}
Host
{/snippet}
{#snippet children()}
Overlay
{/snippet}
{#snippet children()}
Macvlan
{/snippet}
{#snippet children()}
IPvlan
{/snippet}
{#snippet children()}
None
{/snippet}
IPAM configuration
Subnet
Gateway
Labels
{#each editNetworkLabels as label, index}
Key
Value
{/each}
Driver options
{#each editNetworkOptions as opt, index}
Key
Value
{/each}
{:else if selectedNode.type === 'volume'}
Driver
Labels
{#each editVolumeLabels as label, index}
Key
Value
{/each}
Driver options
{#each editVolumeOptions as opt, index}
Key
Value
{/each}
{:else if selectedNode.type === 'config'}
{#if editConfigExternal}
External name (optional)
{:else}

Specify one of: file, content, or environment

File path
Content (inline)
Environment variable
{/if}
{:else if selectedNode.type === 'secret'}
{#if editSecretExternal}
External name (optional)
{:else}

Specify one of: file or environment

File path
Environment variable
{/if}
{/if} {:else if selectedEdge} {#if selectedEdge.type === 'dependency'}

This service depends on {selectedEdge.source.replace('service-', '')} and will start after it.

{:else if selectedEdge.type === 'volume-mount'}

Volume mounted to this service.

{:else if selectedEdge.type === 'network-connection'}

Service connected to this network.

{:else if selectedEdge.type === 'config-mount'}

Config mounted to this service.

{:else if selectedEdge.type === 'secret-mount'}

Secret mounted to this service.

{/if} {/if}
{/if}
{@const DialogIcon = getNodeIcon(addElementType)} Add {getElementTypeLabel(addElementType)}
{#if addElementType === 'service'}
{/if}
{#if showAddMenu} {/if}