From be2dcdd369a6c1bf4e823a26b10031517164ba96 Mon Sep 17 00:00:00 2001 From: Guilhem Date: Mon, 31 Mar 2025 17:15:58 +0100 Subject: [PATCH] use scroll for Resources page --- .../(root)/(logged)/resources/+page.svelte | 812 +++++++++--------- 1 file changed, 410 insertions(+), 402 deletions(-) diff --git a/frontend/src/routes/(root)/(logged)/resources/+page.svelte b/frontend/src/routes/(root)/(logged)/resources/+page.svelte index fce835107f..298a60ef3b 100644 --- a/frontend/src/routes/(root)/(logged)/resources/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/resources/+page.svelte @@ -60,6 +60,7 @@ import EditableSchemaWrapper from '$lib/components/schema/EditableSchemaWrapper.svelte' import ResourceEditorDrawer from '$lib/components/ResourceEditorDrawer.svelte' import GfmMarkdown from '$lib/components/GfmMarkdown.svelte' + import Scroll from '$lib/components/Scroll.svelte' type ResourceW = ListableResource & { canWrite: boolean; marked?: string } type ResourceTypeW = ResourceType & { canWrite: boolean } @@ -603,422 +604,429 @@ f={(x) => x.path + ' ' + x.resource_type + ' ' + x.description + ' '} /> -{#if $userStore?.operator && $workspaceStore && !$userWorkspaces.find(_ => _.id === $workspaceStore)?.operator_settings?.resources} - -{:else} - - -
- - -
-
-
- { - if (e.detail == 'cache') { - loading.resources = true - loadCache() - } else if (e.detail == 'states') { - loading.resources = true - loadState() - } - }} - > - -
- - Workspace -
-
- -
- Resource Types - - Every resource has a Resource Type attached to it which contains its schema and make it - easy in scripts and flows to accept only resources of a specific resource type. - -
-
- -
- States - - States are actually resources (but excluded from the Workspace tab for clarity). States - are used by scripts to keep data persistent between runs of the same script by the same - trigger (schedule or user) - -
-
- -
- Cache - - Cached results are actually resources (but excluded from the Workspace tab for clarity). - Cache are used by flows's step to cache result to avoid recomputing unnecessarily - -
-
- -
- Theme - - Theme are actually resources (but excluded from the Workspace tab for clarity). Theme - are used by the apps to customize their look and feel. - -
-
-
-
-
+{#if $userStore?.operator && $workspaceStore && !$userWorkspaces.find((_) => _.id === $workspaceStore)?.operator_settings?.resources} + - {#if tab == 'workspace' || tab == 'states' || tab == 'cache' || tab == 'theme'} -
- -
- - {#if tab != 'states' && tab != 'cache'} - - {:else} -
- {/if} - -
- {#if loading.resources} - - {#each new Array(6) as _} - - {/each} - {:else if filteredItems?.length == 0} -
-
No resources found
-
- Try changing the filters or creating a new resource -
+{:else} + + + +
+ +
- {:else} - - - - - Path - Resource type - Description - - - - - - {#if filteredItems} - {#each filteredItems as { path, description, resource_type, extra_perms, canWrite, is_oauth, is_linked, account, refresh_error, is_expired, marked, is_refreshed }} +
+
+ { + if (e.detail == 'cache') { + loading.resources = true + loadCache() + } else if (e.detail == 'states') { + loading.resources = true + loadState() + } + }} + > + +
+ + Workspace +
+
+ +
+ Resource Types + + Every resource has a Resource Type attached to it which contains its schema and make + it easy in scripts and flows to accept only resources of a specific resource type. + +
+
+ +
+ States + + States are actually resources (but excluded from the Workspace tab for clarity). + States are used by scripts to keep data persistent between runs of the same script + by the same trigger (schedule or user) + +
+
+ +
+ Cache + + Cached results are actually resources (but excluded from the Workspace tab for + clarity). Cache are used by flows's step to cache result to avoid recomputing + unnecessarily + +
+
+ +
+ Theme + + Theme are actually resources (but excluded from the Workspace tab for clarity). + Theme are used by the apps to customize their look and feel. + +
+
+
+
+
+
+ {#if tab == 'workspace' || tab == 'states' || tab == 'cache' || tab == 'theme'} +
+ +
+ + {#if tab != 'states' && tab != 'cache'} + + {:else} +
+ {/if} + +
+ {#if loading.resources} + + {#each new Array(6) as _} + + {/each} + {:else if filteredItems?.length == 0} +
+
No resources found
+
+ Try changing the filters or creating a new resource +
+
+ {:else} + + - - - - - resourceEditor?.initEdit?.(path)} - >{#if marked}{@html marked}{:else}{path}{/if} - - - { - const linkedRt = resourceTypes?.find((rt) => rt.name === resource_type) - if (linkedRt) { - resourceTypeViewerObj = { - rt: linkedRt.name, - //@ts-ignore - schema: linkedRt.schema, - description: linkedRt.description ?? '', - formatExtension: linkedRt.format_extension - } - resourceTypeViewer.openDrawer?.() - } else { - sendUserToast( - `Resource type ${resource_type} not found in workspace.`, - true - ) - } - }} - > - - - - - - {removeMarkdown(truncate(description ?? '', 30))} - - - -
-
- {#if is_linked} - - -
- This resource is linked with a variable of the same path. They are - deleted and renamed together. -
-
- {/if} -
-
- {#if is_refreshed} - - -
- The OAuth token will be kept up-to-date in the background by Windmill - using its refresh token -
-
- {/if} -
+ + Path + Resource type + Description + + + + + + {#if filteredItems} + {#each filteredItems as { path, description, resource_type, extra_perms, canWrite, is_oauth, is_linked, account, refresh_error, is_expired, marked, is_refreshed }} + + + + + + resourceEditor?.initEdit?.(path)} + >{#if marked}{@html marked}{:else}{path}{/if} + + + { + const linkedRt = resourceTypes?.find((rt) => rt.name === resource_type) + if (linkedRt) { + resourceTypeViewerObj = { + rt: linkedRt.name, + //@ts-ignore + schema: linkedRt.schema, + description: linkedRt.description ?? '', + formatExtension: linkedRt.format_extension + } + resourceTypeViewer.openDrawer?.() + } else { + sendUserToast( + `Resource type ${resource_type} not found in workspace.`, + true + ) + } + }} + > + + + + + + {removeMarkdown(truncate(description ?? '', 30))} + + + +
+
+ {#if is_linked} + + +
+ This resource is linked with a variable of the same path. They are + deleted and renamed together. +
+
+ {/if} +
+
+ {#if is_refreshed} + + +
+ The OAuth token will be kept up-to-date in the background by + Windmill using its refresh token +
+
+ {/if} +
- {#if is_oauth} -
- {#if refresh_error} - - -
- Latest exchange of the refresh token did not succeed. Error: {refresh_error} -
-
- {:else if is_expired} - - + {#if is_oauth} +
+ {#if refresh_error} + + +
+ Latest exchange of the refresh token did not succeed. Error: {refresh_error} +
+
+ {:else if is_expired} + + -
- The access_token is expired, it will get renewed the next time this - variable is fetched or you can request is to be refreshed in the - dropdown on the right. -
-
- {:else} - - -
- The resource was connected through OAuth and the token is not - expired. -
-
+
+ The access_token is expired, it will get renewed the next time + this variable is fetched or you can request is to be refreshed + in the dropdown on the right. +
+ + {:else} + + +
+ The resource was connected through OAuth and the token is not + expired. +
+
+ {/if} +
{/if}
- {/if} -
-
- - { - shareModal.openDrawer?.(path, 'resource') - } - }, - { - displayName: 'Edit', - icon: Pen, - disabled: !canWrite, - action: () => { - resourceEditor?.initEdit?.(path) - } - }, - ...(isDeployable('resource', path, deployUiSettings) - ? [ - { - displayName: 'Deploy to prod/staging', - icon: FileUp, - action: () => { - deploymentDrawer.openDrawer(path, 'resource') - } + + + { + shareModal.openDrawer?.(path, 'resource') } - ] - : []), - { - displayName: 'Delete', - disabled: !canWrite, - icon: Trash, - type: 'delete', - action: (event) => { - // TODO - // @ts-ignore - if (event?.shiftKey) { - deleteResource(path, account) - } else { - deleteConfirmedCallback = () => { - deleteResource(path, account) + }, + { + displayName: 'Edit', + icon: Pen, + disabled: !canWrite, + action: () => { + resourceEditor?.initEdit?.(path) } - } - } - }, - ...(account != undefined - ? [ - { - displayName: 'Refresh token', - icon: RotateCw, - action: async () => { - await OauthService.refreshToken({ - workspace: $workspaceStore ?? '', - id: account ?? 0, - requestBody: { - path + }, + ...(isDeployable('resource', path, deployUiSettings) + ? [ + { + displayName: 'Deploy to prod/staging', + icon: FileUp, + action: () => { + deploymentDrawer.openDrawer(path, 'resource') } - }) - sendUserToast('Token refreshed') - loadResources() + } + ] + : []), + { + displayName: 'Delete', + disabled: !canWrite, + icon: Trash, + type: 'delete', + action: (event) => { + // TODO + // @ts-ignore + if (event?.shiftKey) { + deleteResource(path, account) + } else { + deleteConfirmedCallback = () => { + deleteResource(path, account) + } } } - ] - : []) - ]} - /> - -
- {/each} - {/if} - - - {/if} -
- {:else if tab == 'types'} - {#if loading.types} - - {#each new Array(6) as _} - - {/each} - {:else} -
- - - - Name - Description - - - - - {#if resourceTypes} - {#each resourceTypes as { name, description, schema, canWrite, format_extension }} + }, + ...(account != undefined + ? [ + { + displayName: 'Refresh token', + icon: RotateCw, + action: async () => { + await OauthService.refreshToken({ + workspace: $workspaceStore ?? '', + id: account ?? 0, + requestBody: { + path + } + }) + sendUserToast('Token refreshed') + loadResources() + } + } + ] + : []) + ]} + /> + + + {/each} + {/if} + + + {/if} +
+ {:else if tab == 'types'} + {#if loading.types} + + {#each new Array(6) as _} + + {/each} + {:else} +
+ + - - { - resourceTypeViewerObj = { - rt: name, - //@ts-ignore - schema: schema, - description: description ?? '', - formatExtension: format_extension - } - - resourceTypeViewer.openDrawer?.() - }} - > - - - - - - {removeMarkdown(truncate(description ?? '', 200))} - - - - {#if !canWrite} - - Shared globally - - This resource type is from the 'admins' workspace shared with all - workspaces - - - {:else if $userStore?.is_admin || $userStore?.is_super_admin} -
- - -
- {:else} - - Non Editable - - Since resource types are shared with the whole workspace, only admins can - edit/delete them - - - {/if} -
+ Name + Description +
- {/each} - {/if} - -
-
- {/if} - {/if} - + + + {#if resourceTypes} + {#each resourceTypes as { name, description, schema, canWrite, format_extension }} + + + { + resourceTypeViewerObj = { + rt: name, + //@ts-ignore + schema: schema, + description: description ?? '', + formatExtension: format_extension + } + + resourceTypeViewer.openDrawer?.() + }} + > + + + + + + {removeMarkdown(truncate(description ?? '', 200))} + + + + {#if !canWrite} + + Shared globally + + This resource type is from the 'admins' workspace shared with all + workspaces + + + {:else if $userStore?.is_admin || $userStore?.is_super_admin} +
+ + +
+ {:else} + + Non Editable + + Since resource types are shared with the whole workspace, only admins + can edit/delete them + + + {/if} +
+
+ {/each} + {/if} + +
+
+ {/if} + {/if} + + {/if}