From b040a89b27f6dca41049e4bceeae4e3665c005ae Mon Sep 17 00:00:00 2001 From: Faton Ramadani Date: Tue, 7 Nov 2023 15:13:45 +0100 Subject: [PATCH] feat(frontend): Rework variable table (#2576) * feat(frontend): updated variable table * feat(frontend): updated variable table * feat(frontend): fix folder menu * feat(frontend): fix folder menu * fix(frontend): fix icons * fix(frontend): reduce table size --- frontend/src/lib/components/DropdownV2.svelte | 51 ++++++ .../lib/components/common/menu/MenuV2.svelte | 4 +- frontend/src/lib/components/table/Cell.svelte | 4 +- .../(root)/(logged)/folders/+page.svelte | 13 +- .../(root)/(logged)/variables/+page.svelte | 166 +++++++++--------- 5 files changed, 147 insertions(+), 91 deletions(-) create mode 100644 frontend/src/lib/components/DropdownV2.svelte diff --git a/frontend/src/lib/components/DropdownV2.svelte b/frontend/src/lib/components/DropdownV2.svelte new file mode 100644 index 0000000000..e6098e0280 --- /dev/null +++ b/frontend/src/lib/components/DropdownV2.svelte @@ -0,0 +1,51 @@ + + + +
+ +
+ +
+ {#each computeItems() ?? [] as item} + item?.action?.(e)} + href={item?.href} + disabled={item?.disabled} + class={twMerge( + 'px-4 py-2 text-primary hover:bg-surface-hover hover:text-primary cursor-pointer text-xs transition-all', + 'flex flex-row gap-2 items-center', + item?.type === 'delete' && 'text-red-500 hover:bg-red-100 hover:text-red-500' + )} + > + {#if item.icon} + + {/if} + {item.displayName} + + {/each} +
+
diff --git a/frontend/src/lib/components/common/menu/MenuV2.svelte b/frontend/src/lib/components/common/menu/MenuV2.svelte index f9278a11ad..d049f5ee61 100644 --- a/frontend/src/lib/components/common/menu/MenuV2.svelte +++ b/frontend/src/lib/components/common/menu/MenuV2.svelte @@ -3,8 +3,10 @@ import Portal from 'svelte-portal' import { offset, flip, shift } from 'svelte-floating-ui/dom' import { createFloatingActions } from 'svelte-floating-ui' + import { twMerge } from 'tailwind-merge' export let placement: any = 'bottom-start' + export let justifyEnd: boolean = false const [floatingRef, floatingContent] = createFloatingActions({ strategy: 'fixed', @@ -15,7 +17,7 @@
- +
diff --git a/frontend/src/lib/components/table/Cell.svelte b/frontend/src/lib/components/table/Cell.svelte index 8d75d246c2..f28e52865f 100644 --- a/frontend/src/lib/components/table/Cell.svelte +++ b/frontend/src/lib/components/table/Cell.svelte @@ -34,10 +34,10 @@ numeric ? 'text-right' : '', head ? 'font-semibold ' : '', $$restProps.class, + sticky ? `!p-0 sticky ${first ? 'left-0' : 'right-0'}` : 'px-2 py-3.5', size === 'sm' ? 'px-1.5 py-2.5' : '', size === 'lg' ? 'px-3 py-4' : '', - size === 'xs' ? 'px-1 py-1.5' : '', - sticky ? `!p-0 sticky ${first ? 'left-0' : 'right-0'}` : 'px-2 py-3.5' + size === 'xs' ? 'px-1 py-1.5' : '' )} > {#if sticky} diff --git a/frontend/src/routes/(root)/(logged)/folders/+page.svelte b/frontend/src/routes/(root)/(logged)/folders/+page.svelte index 961bf812b8..15d24ea4f6 100644 --- a/frontend/src/routes/(root)/(logged)/folders/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/folders/+page.svelte @@ -3,11 +3,11 @@ import { FolderService } from '$lib/gen' import CenteredPage from '$lib/components/CenteredPage.svelte' - import Dropdown from '$lib/components/Dropdown.svelte' + import Dropdown from '$lib/components/DropdownV2.svelte' import FolderEditor from '$lib/components/FolderEditor.svelte' import PageHeader from '$lib/components/PageHeader.svelte' import { userStore, workspaceStore } from '$lib/stores' - import { faEdit, faPlus, faTrash } from '@fortawesome/free-solid-svg-icons' + import { faPlus } from '@fortawesome/free-solid-svg-icons' import { Button, Drawer, DrawerContent, Popup, Skeleton } from '$lib/components/common' import FolderInfo from '$lib/components/FolderInfo.svelte' import FolderUsageInfo from '$lib/components/FolderUsageInfo.svelte' @@ -16,6 +16,7 @@ import Head from '$lib/components/table/Head.svelte' import Cell from '$lib/components/table/Cell.svelte' import Row from '$lib/components/table/Row.svelte' + import { Pen, Trash } from 'lucide-svelte' type FolderW = Folder & { canWrite: boolean } @@ -159,11 +160,10 @@ { editFolderName = name @@ -172,8 +172,7 @@ }, { displayName: 'Delete', - - icon: faTrash, + icon: Trash, type: 'delete', disabled: !canWrite, action: async () => { diff --git a/frontend/src/routes/(root)/(logged)/variables/+page.svelte b/frontend/src/routes/(root)/(logged)/variables/+page.svelte index b84c82fe4e..26449aef71 100644 --- a/frontend/src/routes/(root)/(logged)/variables/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/variables/+page.svelte @@ -3,14 +3,17 @@ import { Alert, Badge, Button, Skeleton, Tab, Tabs } from '$lib/components/common' import ConfirmationModal from '$lib/components/common/confirmationModal/ConfirmationModal.svelte' import DeployWorkspaceDrawer from '$lib/components/DeployWorkspaceDrawer.svelte' - import Dropdown from '$lib/components/Dropdown.svelte' + import Dropdown from '$lib/components/DropdownV2.svelte' import ListFilters from '$lib/components/home/ListFilters.svelte' import PageHeader from '$lib/components/PageHeader.svelte' import Popover from '$lib/components/Popover.svelte' import SearchItems from '$lib/components/SearchItems.svelte' import SharedBadge from '$lib/components/SharedBadge.svelte' import ShareModal from '$lib/components/ShareModal.svelte' - import TableCustom from '$lib/components/TableCustom.svelte' + import Cell from '$lib/components/table/Cell.svelte' + import DataTable from '$lib/components/table/DataTable.svelte' + import Head from '$lib/components/table/Head.svelte' + import Row from '$lib/components/table/Row.svelte' import TableSimple from '$lib/components/TableSimple.svelte' import Tooltip from '$lib/components/Tooltip.svelte' import VariableEditor from '$lib/components/VariableEditor.svelte' @@ -19,18 +22,8 @@ import { userStore, workspaceStore } from '$lib/stores' import { sendUserToast } from '$lib/toast' import { canWrite, isOwner, truncate } from '$lib/utils' - import { - faChain, - faCircle, - faEdit, - faEyeSlash, - faFileExport, - faPlus, - faRefresh, - faShare, - faTrash - } from '@fortawesome/free-solid-svg-icons' - import { Building, DollarSign } from 'lucide-svelte' + import { faCircle, faEyeSlash, faPlus } from '@fortawesome/free-solid-svg-icons' + import { Building, DollarSign, FileUp, Link, Pen, RefreshCw, Share, Trash } from 'lucide-svelte' import Icon from 'svelte-awesome' type ListableVariableW = ListableVariable & { canWrite: boolean } @@ -140,12 +133,13 @@
- Contextual Contextual variables are passed as environment variables when running a script and depends - on the execution context. + on the execution context. +
@@ -153,41 +147,55 @@
- - +
+ +
{#if !filteredItems} {#each new Array(3) as _} {/each} + {:else if filteredItems.length == 0} +
+
No variables found
+
+ Try changing the filters or creating a new variable +
+
{:else} - - - - Path - Value - Description - - - - + + + + + Path + Value + Description + + + + + {#each filteredItems as { path, value, is_secret, description, extra_perms, canWrite, account, is_refreshed, is_expired, refresh_error, is_linked, marked }} - - + + - - + + variableEditor.editVariable(path)} href="#{path}" > - {#if marked}{@html marked}{:else}{path}{/if} + {#if marked} + {@html marked} + {:else} + {path} + {/if} - - + + {truncate(value ?? '****', 20)} @@ -204,43 +212,39 @@ {/if} - - {truncate(description ?? '', 50)} + + + {truncate(description ?? '', 50)} + - -
-
- {#if is_linked} - - -
- This variable is linked with a resource of the same path. They are - deleted and renamed together. -
-
- {/if} -
-
- {#if account} - - -
- This OAuth token will be kept up-to-date in the background by Windmill - using its refresh token -
-
- {/if} -
+ +
+ {#if is_linked} + + +
+ This variable is linked with a resource of the same path. They are deleted + and renamed together. +
+
+ {/if} + {#if account} + + +
+ This OAuth token will be kept up-to-date in the background by Windmill + using its refresh token +
+
+ {/if} {#if is_refreshed} -
+
{#if refresh_error} - +
- +
+
Latest exchange of the refresh token did not succeed. Error: {refresh_error}
@@ -286,25 +291,24 @@
{/if}
- - + + { + items={() => { let owner = isOwner(path, $userStore, $workspaceStore) return [ { displayName: 'Edit', - icon: faEdit, + icon: Pen, action: () => variableEditor.editVariable(path), disabled: !canWrite }, { displayName: 'Delete', - icon: faTrash, + icon: Trash, type: 'delete', action: (event) => { - if (event?.shiftKey) { + if (event['shiftKey']) { deleteVariable(path, account) } else { deleteConfirmedCallback = () => { @@ -316,7 +320,7 @@ }, { displayName: 'Deploy to prod/staging', - icon: faFileExport, + icon: FileUp, action: () => { deploymentDrawer.openDrawer(path, 'variable') } @@ -326,13 +330,13 @@ action: () => { shareModal.openDrawer(path, 'variable') }, - icon: faShare + icon: Share }, ...(account != undefined ? [ { displayName: 'Refresh token', - icon: faRefresh, + icon: RefreshCw, action: async () => { await OauthService.refreshToken({ workspace: $workspaceStore ?? '', @@ -350,11 +354,11 @@ ] }} /> - - + + {/each} - + {/if}
{:else if tab == 'contextual'}