diff --git a/frontend/src/lib/components/LabelsInput.svelte b/frontend/src/lib/components/LabelsInput.svelte
index cd1555d147..5b0e11f621 100644
--- a/frontend/src/lib/components/LabelsInput.svelte
+++ b/frontend/src/lib/components/LabelsInput.svelte
@@ -1,11 +1,10 @@
{#each labels ?? [] as label (label)}
-
- pickColor(label, c)}
- >
- {#snippet anchor()}
-
- {/snippet}
-
-
-
+
{/each}
{#if adding}
-
-
+
- {#if suggestions.length > 0 || showCreateNew}
-
- {#each suggestions as suggestion, i}
-
- {/each}
- {#if showCreateNew}
-
- {/if}
-
- {/if}
{:else}
{/if}
diff --git a/frontend/src/lib/components/common/colorPicker/ColorSwatchGrid.svelte b/frontend/src/lib/components/common/colorPicker/ColorSwatchGrid.svelte
index e208553318..2d10255a75 100644
--- a/frontend/src/lib/components/common/colorPicker/ColorSwatchGrid.svelte
+++ b/frontend/src/lib/components/common/colorPicker/ColorSwatchGrid.svelte
@@ -16,17 +16,21 @@
{#each colors as color (color)}
+
{/each}
diff --git a/frontend/src/lib/components/home/ItemsList.svelte b/frontend/src/lib/components/home/ItemsList.svelte
index 1a039c8ca2..33ad2bb2fd 100644
--- a/frontend/src/lib/components/home/ItemsList.svelte
+++ b/frontend/src/lib/components/home/ItemsList.svelte
@@ -1,6 +1,5 @@
-
-
- {#snippet trigger()}
- {@render anchor()}
- {/snippet}
- {#snippet content()}
-
- {#if color != undefined}
-
- {/if}
- {/snippet}
-
diff --git a/frontend/src/lib/components/labels/LabelEditor.svelte b/frontend/src/lib/components/labels/LabelEditor.svelte
new file mode 100644
index 0000000000..2cbbfd4c9d
--- /dev/null
+++ b/frontend/src/lib/components/labels/LabelEditor.svelte
@@ -0,0 +1,52 @@
+
+
+
+ {#key opened}
+ {
+ isOpen = false
+ onSave?.(name)
+ }}
+ />
+ {/key}
+
diff --git a/frontend/src/lib/components/labels/LabelForm.svelte b/frontend/src/lib/components/labels/LabelForm.svelte
new file mode 100644
index 0000000000..1c627359ca
--- /dev/null
+++ b/frontend/src/lib/components/labels/LabelForm.svelte
@@ -0,0 +1,121 @@
+
+
+
+ {#if onBack}
+
+
+ {existing ? 'Edit label' : 'New label'}
+
+
+
+ {/if}
+
+ Name
+ {
+ if (e.key === 'Enter') {
+ e.preventDefault()
+ save()
+ }
+ }
+ }}
+ />
+ {#if existing}
+ To rename a label, edit the items that carry it.
+ {/if}
+
+
+ Color
+ (color = c)}
+ />
+
+
+
+
+
+
diff --git a/frontend/src/lib/components/labels/LabelManagerDrawer.svelte b/frontend/src/lib/components/labels/LabelManagerDrawer.svelte
deleted file mode 100644
index b10309ae47..0000000000
--- a/frontend/src/lib/components/labels/LabelManagerDrawer.svelte
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
- {#if labels == undefined}
-
- {:else if labels.length === 0}
-
- No labels yet. Labels appear here once you add one to a script, flow, app, resource,
- variable, schedule or folder.
-
- {:else}
-
- A color applies to the label everywhere it is used in this workspace.
-
-
- {#each labels as label (label.name)}
-
- pick(label.name, c)}>
- {#snippet anchor()}
-
- {/snippet}
-
-
- {/each}
-
- {/if}
-
-
diff --git a/frontend/src/lib/components/labels/LabelPickerDropdown.svelte b/frontend/src/lib/components/labels/LabelPickerDropdown.svelte
new file mode 100644
index 0000000000..40a87b17ac
--- /dev/null
+++ b/frontend/src/lib/components/labels/LabelPickerDropdown.svelte
@@ -0,0 +1,224 @@
+
+
+ (open = false) }}>
+
+ (open = true)}
+ class={twMerge(
+ inputBaseClass,
+ inputSizeClasses.sm,
+ inputBorderClass({ forceFocus: open }),
+ 'w-full',
+ inputClass
+ )}
+ />
+
+
+ inputEl!.getBoundingClientRect())}
+ innerClass="w-64"
+ maxHeight={400}
+>
+
+
+
diff --git a/frontend/src/lib/components/workspaceSettings/LabelSettings.svelte b/frontend/src/lib/components/workspaceSettings/LabelSettings.svelte
new file mode 100644
index 0000000000..c1eb03f799
--- /dev/null
+++ b/frontend/src/lib/components/workspaceSettings/LabelSettings.svelte
@@ -0,0 +1,72 @@
+
+
+ $workspaceStore && refresh($workspaceStore)}
+/>
+
+
+ {#snippet actions()}
+
+ {/snippet}
+
+
+{#if labels == undefined}
+
+{:else if labels.length === 0}
+
+ No labels yet. Create one here, or add one to a script, flow, app, resource, variable, schedule
+ or folder.
+
+{:else}
+
+ {#each labels as label (label.name)}
+
+
+
+ {/each}
+
+{/if}
diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte
index 782da1bb2c..a5faf306ec 100644
--- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte
+++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte
@@ -43,6 +43,7 @@
import { downloadViaClient, shouldDownloadViaClient } from '$lib/utils/downloadFile'
import { Slack, Target } from 'lucide-svelte'
import SidebarNavigation from '$lib/components/common/sidebar/SidebarNavigation.svelte'
+ import LabelSettings from '$lib/components/workspaceSettings/LabelSettings.svelte'
import PremiumInfo from '$lib/components/settings/PremiumInfo.svelte'
import Toggle from '$lib/components/Toggle.svelte'
@@ -374,6 +375,7 @@
| 'teams'
| 'premium'
| 'general'
+ | 'labels'
| 'webhook'
| 'deploy_to'
| 'dev_workspace'
@@ -1193,6 +1195,12 @@
aiId: 'workspace-settings-ai',
aiDescription: 'Windmill AI workspace settings'
},
+ {
+ id: 'labels',
+ label: 'Labels',
+ aiId: 'workspace-settings-labels',
+ aiDescription: 'Colors for the labels used across this workspace'
+ },
{
id: 'premium',
label: 'Premium plans',
@@ -2190,6 +2198,8 @@ export async function main(
/>
{:else if tab == 'shared_ui'}
+ {:else if tab == 'labels'}
+
{:else if tab == 'trashbin'}