refactor: remove unused automation dropdown components

Two dropdown components in the automations area, one for folders and one for terminals, are not imported by any route or component. Both were superseded by a different picker that is in use today.

This removes around 265 lines. Two English translation keys lose their last consumer with them and are left in place, since regenerating the locale catalogues does not belong in this change.
This commit is contained in:
Classic298 2026-08-20 22:07:00 +02:00
parent 8a42aa53e8
commit b5ce7f9f8f
2 changed files with 0 additions and 266 deletions

View file

@ -1,148 +0,0 @@
<script lang="ts">
import { getContext } from 'svelte';
import { folders } from '$lib/stores';
import { decodeString } from '$lib/utils';
import Select from '$lib/components/common/Select.svelte';
import Check from '$lib/components/icons/Check.svelte';
import ChevronDown from '$lib/components/icons/ChevronDown.svelte';
import Folder from '$lib/components/icons/Folder.svelte';
import Search from '$lib/components/icons/Search.svelte';
import XMark from '$lib/components/icons/XMark.svelte';
const i18n = getContext('i18n');
export let folder_id = '';
export let side: 'top' | 'bottom' = 'top';
export let align: 'start' | 'end' = 'start';
export let onChange: () => void = () => {};
let folderSearch = '';
const folderName = (folder: any) => decodeString(folder?.name ?? $i18n.t('Folder'));
const folderPath = (folder: any) => {
const names: string[] = [];
const seen = new Set<string>();
let current = folder;
while (current?.parent_id && !seen.has(current.parent_id)) {
seen.add(current.parent_id);
const parent = folderById.get(current.parent_id);
if (!parent) break;
names.unshift(folderName(parent));
current = parent;
}
return names.join(' / ');
};
$: folderOptions = [...((($folders ?? []) as any[]) ?? [])]
.filter((folder) => folder?.id && !folder?.shared)
.sort((a, b) => folderName(a).localeCompare(folderName(b)));
$: folderById = new Map(folderOptions.map((folder) => [folder.id, folder]));
$: selectedFolder = folderOptions.find((folder) => folder.id === folder_id);
$: folderLabel = selectedFolder ? folderName(selectedFolder) : $i18n.t('Choose folder');
$: normalizedSearch = folderSearch.trim().toLowerCase();
$: filteredFolderOptions = normalizedSearch
? folderOptions.filter((folder) =>
`${folderName(folder)} ${folderPath(folder)}`.toLowerCase().includes(normalizedSearch)
)
: folderOptions;
</script>
<Select
bind:value={folder_id}
items={folderOptions.map((folder) => ({ value: folder.id, label: folderName(folder) }))}
placeholder={$i18n.t('Choose folder')}
{align}
{side}
triggerClass="relative h-8 max-w-[11rem] flex items-center gap-1.5 px-2.5 py-1.5 bg-transparent rounded-2xl text-xs font-normal text-gray-600 transition hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100"
contentClass="w-72 shadow-lg"
maxHeight="18rem"
onChange={() => onChange()}
onClose={() => {
folderSearch = '';
}}
>
<svelte:fragment slot="trigger">
<Folder className="size-3.5 shrink-0" />
<div class="inline-flex h-input min-w-0 flex-1 truncate bg-transparent outline-hidden">
{folderLabel}
</div>
{#if folder_id}
<button
class="outline-none"
type="button"
on:click|stopPropagation={() => {
folder_id = '';
folderSearch = '';
onChange();
}}
aria-label={$i18n.t('Clear')}
>
<XMark className="size-3.5" />
</button>
{:else}
<ChevronDown className="size-2.5 shrink-0" strokeWidth="2.5" />
{/if}
</svelte:fragment>
<svelte:fragment let:selectItem>
<div class="flex items-center gap-1.5 px-2 py-1">
<Search className="size-3.5 shrink-0" strokeWidth="2.5" />
<input
bind:value={folderSearch}
class="w-full bg-transparent text-[0.8125rem] outline-hidden"
placeholder={$i18n.t('Search folders')}
autocomplete="off"
on:click|stopPropagation
/>
</div>
{#if folderOptions.length > 0}
<hr class="mx-1 my-0.5 border-gray-50/30 dark:border-gray-800/30" />
<div class="px-2 py-1 text-[0.6875rem] text-gray-500 dark:text-gray-400">
{$i18n.t('Folders')}
</div>
{/if}
{#each filteredFolderOptions as folder (folder.id)}
{@const path = folderPath(folder)}
<button
type="button"
class="flex h-[1.6875rem] w-full cursor-pointer items-center justify-between gap-2 rounded-xl bg-transparent px-2 text-[0.8125rem] hover:bg-gray-50/40 hover:text-gray-900 dark:hover:bg-gray-800/40 dark:hover:text-gray-100 {folder_id ===
folder.id
? 'text-gray-900 dark:text-gray-100'
: 'text-gray-700 dark:text-gray-300'}"
title={path ? `${path} / ${folderName(folder)}` : folderName(folder)}
on:click={() => {
selectItem({
value: folder_id === folder.id ? '' : folder.id,
label: folder_id === folder.id ? $i18n.t('Choose folder') : folderName(folder)
});
folderSearch = '';
}}
>
<div class="flex min-w-0 items-center gap-1.5">
<Folder className="size-3.5 shrink-0" />
<span class="min-w-0 truncate">{folderName(folder)}</span>
{#if path}
<span class="min-w-0 truncate text-[0.6875rem] text-gray-400 dark:text-gray-500">
{path}
</span>
{/if}
</div>
{#if folder_id === folder.id}
<Check className="size-3.5 shrink-0" strokeWidth="2" />
{/if}
</button>
{:else}
<div class="px-2 py-1 text-[0.6875rem] text-gray-500 dark:text-gray-400">
{folderOptions.length > 0 ? $i18n.t('No results found') : $i18n.t('No folders')}
</div>
{/each}
</svelte:fragment>
</Select>

View file

@ -1,118 +0,0 @@
<script lang="ts">
import { getContext } from 'svelte';
import type { TerminalServer } from '$lib/apis/terminal/index';
import Dropdown from '$lib/components/common/Dropdown.svelte';
import Cloud from '$lib/components/icons/Cloud.svelte';
const i18n = getContext('i18n');
export let terminalServers: TerminalServer[] = [];
export let terminalServerId = '';
export let terminalCwd = '';
export let side: 'top' | 'bottom' = 'top';
export let align: 'start' | 'end' = 'start';
/** Optional callback when selection changes */
export let onChange: () => void = () => {};
let showDropdown = false;
$: terminalLabel = terminalServerId
? terminalServers.find((s) => s.id === terminalServerId)?.name || 'Terminal'
: $i18n.t('Terminal');
</script>
{#if terminalServers.length > 0}
<Dropdown bind:show={showDropdown} {side} {align}>
<button
type="button"
class="flex items-center gap-1.5 px-2.5 py-1.5 rounded-2xl text-xs transition
{terminalServerId ? 'text-black dark:text-gray-100' : 'text-gray-600 dark:text-gray-400'}
hover:text-gray-900 dark:hover:text-gray-100"
>
<Cloud className="size-3.5 shrink-0" strokeWidth="2" />
<span class="whitespace-nowrap max-w-32 truncate">{terminalLabel}</span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="size-2.5"
>
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg>
</button>
<div
slot="content"
class="rounded-xl shadow-lg border border-gray-200 dark:border-gray-800 flex flex-col bg-white dark:bg-gray-850 min-w-56 max-w-56 p-0.5"
>
<div class="px-2 text-[0.6875rem] text-gray-500 py-0.5">
{$i18n.t('Terminal')}
</div>
{#each terminalServers as server (server.id)}
<button
class="flex w-full h-[1.6875rem] justify-between gap-2 items-center px-2 text-[0.8125rem] cursor-pointer rounded-xl {terminalServerId ===
server.id
? 'text-gray-900 dark:text-gray-100'
: 'text-gray-700 hover:text-gray-900 dark:text-gray-300 dark:hover:text-gray-100'}"
type="button"
on:click={() => {
if (terminalServerId === server.id) {
terminalServerId = '';
terminalCwd = '';
} else {
terminalServerId = server.id;
}
showDropdown = false;
onChange();
}}
>
<div class="flex flex-1 gap-2 items-center truncate">
<Cloud className="size-3.5 shrink-0" strokeWidth="2" />
<span class="truncate">{server.name || server.id}</span>
</div>
{#if terminalServerId === server.id}
<div class="shrink-0 text-emerald-600 dark:text-emerald-400">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-3.5"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
clip-rule="evenodd"
/>
</svg>
</div>
{/if}
</button>
{/each}
{#if terminalServerId}
<div class="border-t border-gray-100 dark:border-gray-800 mt-1 pt-1">
<div class="px-2 py-0.5 text-[0.6875rem] text-gray-500">
{$i18n.t('Working Directory')}
</div>
<div class="px-2">
<input
type="text"
bind:value={terminalCwd}
placeholder="/home/user/project"
class="w-full bg-transparent outline-hidden text-[0.8125rem] py-1 placeholder:text-gray-400 dark:placeholder:text-gray-600"
on:click={(e) => e.stopPropagation()}
on:input={onChange}
/>
</div>
</div>
{/if}
</div>
</Dropdown>
{/if}