From 73ada67432f77c0b2d09f9ebe54b9d192442fa03 Mon Sep 17 00:00:00 2001 From: Abdenasser Date: Wed, 13 Nov 2024 13:50:11 +0100 Subject: [PATCH] extracting ProcessIcon component --- .../components/process/ActionButtons.svelte | 147 --------- src/lib/components/process/ProcessIcon.svelte | 36 ++- src/lib/components/process/ProcessRow.svelte | 60 ---- .../components/process/ProcessTable.svelte | 294 +++++++++++++++++- src/lib/components/process/TableHeader.svelte | 136 -------- .../process/cells/ProcessCell.svelte | 289 ----------------- 6 files changed, 307 insertions(+), 655 deletions(-) diff --git a/src/lib/components/process/ActionButtons.svelte b/src/lib/components/process/ActionButtons.svelte index e219821..e69de29 100644 --- a/src/lib/components/process/ActionButtons.svelte +++ b/src/lib/components/process/ActionButtons.svelte @@ -1,147 +0,0 @@ - - -
- - - -
- - diff --git a/src/lib/components/process/ProcessIcon.svelte b/src/lib/components/process/ProcessIcon.svelte index 660134a..a4c71a6 100644 --- a/src/lib/components/process/ProcessIcon.svelte +++ b/src/lib/components/process/ProcessIcon.svelte @@ -2,6 +2,7 @@ import * as SimpleIcons from "simple-icons"; export let processName: string; + export let size: number = 16; function handleImageError(event: Event) { const img = event.target as HTMLImageElement; @@ -20,11 +21,20 @@ SimpleIcons[companyIconKey as keyof typeof SimpleIcons]; if (companyIcon) { - return createSvgDataUrl(companyIcon); + // Use theme color instead of brand color + const color = getComputedStyle(document.documentElement) + .getPropertyValue("--text") + .trim(); + const svg = + typeof companyIcon === "object" && "svg" in companyIcon + ? companyIcon.svg + : ""; + const svgWithColor = svg.replace(" diff --git a/src/lib/components/process/ProcessRow.svelte b/src/lib/components/process/ProcessRow.svelte index d79481c..e69de29 100644 --- a/src/lib/components/process/ProcessRow.svelte +++ b/src/lib/components/process/ProcessRow.svelte @@ -1,60 +0,0 @@ - - - - {#each columns.filter((col) => col.visible) as column} - - {/each} - - - - - - diff --git a/src/lib/components/process/ProcessTable.svelte b/src/lib/components/process/ProcessTable.svelte index dfbb576..b658ed9 100644 --- a/src/lib/components/process/ProcessTable.svelte +++ b/src/lib/components/process/ProcessTable.svelte @@ -1,7 +1,12 @@
- + + + {#each columns.filter((col) => col.visible) as column} + + {/each} + + + {#each processes as process (process.pid)} - 50 || + 50 || process.memory_usage / (systemStats?.memory_total || 0) > 0.1} - {onTogglePin} - {onShowDetails} - {onKillProcess} - /> + class:pinned={pinnedProcesses.has(process.command)} + > + {#each columns.filter((col) => col.visible) as column} + + {/each} + + {/each}
onToggleSort(column.id)}> +
+ {column.label} + + {getSortIndicator(column.id)} + +
+
Actions
+ {#if column.id === "name"} +
+ + {process.name} +
+ {:else if column.format} + {@html column.format(process[column.id])} + {:else} + {process[column.id]} + {/if} +
+
+ + + +
+
@@ -83,4 +146,211 @@ border-collapse: collapse; font-size: 13px; } + + th { + position: sticky; + top: 0; + background: var(--mantle); + text-align: left; + padding: 8px 12px; + font-weight: 500; + color: var(--subtext0); + border-bottom: 1px solid var(--surface0); + transition: background-color 0.2s ease; + z-index: 3; + } + + td { + padding: 6px 12px; + border-bottom: 1px solid var(--surface0); + color: var(--text); + z-index: 1; + } + + tr:hover { + background-color: var(--surface0); + } + + .truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 0; + } + + .sortable { + cursor: pointer; + user-select: none; + } + + .th-content { + display: flex; + align-items: center; + gap: 8px; + } + + .sort-indicator { + color: var(--overlay0); + font-size: 12px; + opacity: 0.5; + transition: all 0.2s ease; + } + + .sort-indicator.active { + color: var(--blue); + opacity: 1; + } + + .sortable:hover .sort-indicator { + opacity: 1; + } + + .high-usage { + background-color: color-mix(in srgb, var(--red) 10%, transparent); + } + + .high-usage:hover { + background-color: color-mix(in srgb, var(--red) 15%, transparent); + } + + tr.pinned { + background-color: color-mix(in srgb, var(--blue) 10%, transparent); + } + + tr.pinned:hover { + background-color: color-mix(in srgb, var(--blue) 15%, transparent); + } + + th:last-child { + width: 120px; + min-width: 120px; + max-width: 120px; + } + + td:last-child { + width: 120px; + min-width: 120px; + max-width: 120px; + padding: 6px 8px; + } + + .col-actions { + position: sticky; + right: 0; + z-index: 2; + background: var(--base); + border-left: 1px solid var(--surface0); + width: 120px; + } + + .action-buttons { + display: flex; + gap: 4px; + align-items: center; + justify-content: center; + } + + .btn-action { + display: inline-flex; + align-items: center; + justify-content: center; + border: none; + cursor: pointer; + background: transparent; + border-radius: 6px; + width: 28px; + height: 28px; + transition: all 0.2s ease; + position: relative; + overflow: hidden; + } + + .btn-action::before { + content: ""; + position: absolute; + inset: 0; + opacity: 0.1; + transition: opacity 0.2s ease; + } + + .btn-action:hover::before { + opacity: 0.15; + } + + .pin-btn { + color: var(--sapphire); + } + + .pin-btn::before { + background: var(--sapphire); + } + + .pin-btn.pinned { + color: var(--blue); + transform: rotate(45deg); + } + + .pin-btn.pinned::before { + background: var(--blue); + opacity: 0.15; + } + + .info-btn { + color: var(--lavender); + } + + .info-btn::before { + background: var(--lavender); + } + + .kill-btn { + color: var(--red); + border: 1px solid color-mix(in srgb, var(--red) 30%, transparent); + } + + .kill-btn:hover { + color: var(--base); + background: var(--red); + } + + .kill-btn:hover::before { + opacity: 1; + } + + .btn-action:hover { + box-shadow: 0 0 12px color-mix(in srgb, currentColor 20%, transparent); + } + + .btn-action:active { + transform: translateY(1px); + } + + .pin-btn.pinned:active { + transform: rotate(45deg) translateY(1px); + } + + .btn-action:focus { + outline: none; + box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 30%, transparent); + } + + .btn-action:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .btn-action:disabled:hover { + transform: none; + box-shadow: none; + } + + .btn-action:disabled::before { + display: none; + } + + .name-cell { + display: flex; + align-items: center; + gap: 8px; + } diff --git a/src/lib/components/process/TableHeader.svelte b/src/lib/components/process/TableHeader.svelte index 9d90706..e69de29 100644 --- a/src/lib/components/process/TableHeader.svelte +++ b/src/lib/components/process/TableHeader.svelte @@ -1,136 +0,0 @@ - - - - - {#each columns.filter((col) => col.visible) as column} - onToggleSort(column.id)} - > -
- {column.label} - - {getSortIndicator(column.id)} - -
- - {/each} - Actions - - - - diff --git a/src/lib/components/process/cells/ProcessCell.svelte b/src/lib/components/process/cells/ProcessCell.svelte index 107fb3d..e69de29 100644 --- a/src/lib/components/process/cells/ProcessCell.svelte +++ b/src/lib/components/process/cells/ProcessCell.svelte @@ -1,289 +0,0 @@ - - - - {#if field === "name"} -
- - {process.name} -
- {:else} - {formatValue(process[field])} - {/if} - - -