diff --git a/frontend/src/lib/components/SharedBadge.svelte b/frontend/src/lib/components/SharedBadge.svelte index 3a687320a4..bbe1cf4884 100644 --- a/frontend/src/lib/components/SharedBadge.svelte +++ b/frontend/src/lib/components/SharedBadge.svelte @@ -1,9 +1,8 @@ -{#if kind == 'read' || kind == 'write'} - - {#if kind == 'read'} - - - read - {:else if kind == 'write'} - - {/if} - +{#if kind === 'read' || kind === 'write'} + + {kind} + {/if} diff --git a/frontend/src/lib/components/Tooltip.svelte b/frontend/src/lib/components/Tooltip.svelte index 927c2c71ba..65437b199e 100644 --- a/frontend/src/lib/components/Tooltip.svelte +++ b/frontend/src/lib/components/Tooltip.svelte @@ -58,6 +58,6 @@ diff --git a/frontend/src/lib/components/common/badge/Badge.svelte b/frontend/src/lib/components/common/badge/Badge.svelte new file mode 100644 index 0000000000..3f380cb163 --- /dev/null +++ b/frontend/src/lib/components/common/badge/Badge.svelte @@ -0,0 +1,94 @@ + + + + + {#if iconProps.data && iconProps.position === 'left'} + + {/if} + + {#if iconProps.data && iconProps.position === 'right'} + + {/if} + {#if dismissable} + + {/if} + + diff --git a/frontend/src/lib/components/common/badge/model.ts b/frontend/src/lib/components/common/badge/model.ts new file mode 100644 index 0000000000..8da75b055b --- /dev/null +++ b/frontend/src/lib/components/common/badge/model.ts @@ -0,0 +1,9 @@ +import type { IconProps } from 'svelte-awesome/components/Icon.svelte' + +type BaseColor = 'blue' | 'gray' | 'red' | 'green' | 'yellow' | 'indigo' | 'purple' | 'pink' +export const ColorModifier = 'dark-' +export type BadgeColor = BaseColor | `${typeof ColorModifier}${BaseColor}` + +export interface BadgeIconProps extends IconProps { + position?: 'left' | 'right' +} diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index 34f9b923b3..c98e976b31 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -571,3 +571,16 @@ export function scriptLangToEditorLang(lang: Script.language): 'typescript' | 'p return lang } } + +export async function copyToClipboard(value: string, sendToast = true): Promise { + let success = false + if (navigator?.clipboard) { + success = await navigator.clipboard + .writeText(value) + .then(() => true) + .catch(() => false) + } + sendToast && + sendUserToast(success ? 'Copied to clipboard!' : "Couldn't copy to clipboard", !success) + return success +} diff --git a/frontend/src/routes/scripts/get/[...hash].svelte b/frontend/src/routes/scripts/get/[...hash].svelte index bf9e630158..aaeb69343a 100644 --- a/frontend/src/routes/scripts/get/[...hash].svelte +++ b/frontend/src/routes/scripts/get/[...hash].svelte @@ -15,7 +15,8 @@ displayDaysAgo, canWrite, defaultIfEmptyString, - scriptToHubUrl + scriptToHubUrl, + copyToClipboard } from '$lib/utils' import Icon from 'svelte-awesome' import { @@ -28,7 +29,8 @@ faShare, faSpinner, faGlobe, - faCodeFork + faCodeFork, + faClipboard } from '@fortawesome/free-solid-svg-icons' import Tooltip from '$lib/components/Tooltip.svelte' @@ -41,6 +43,10 @@ import CenteredPage from '$lib/components/CenteredPage.svelte' import { onDestroy } from 'svelte' import HighlightCode from '$lib/components/HighlightCode.svelte' + import Badge from '$lib/components/common/badge/Badge.svelte' + import Tabs from '$lib/components/common/tabs/Tabs.svelte' + import Tab from '$lib/components/common/tabs/Tab.svelte' + import TabContent from '$lib/components/common/tabs/TabContent.svelte' let script: Script | undefined let topHash: string | undefined @@ -50,9 +56,17 @@ let shareModal: ShareModal - $: { - if ($workspaceStore) { - loadScript($page.params.hash) + $: if ($workspaceStore) { + loadScript($page.params.hash) + } + $: webhooks = { + uuid: { + hash: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run/h/${script?.hash}`, + path: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run/p/${script?.path}` + }, + result: { + hash: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run_wait_result/h/${script?.hash}`, + path: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run_wait_result/p/${script?.path}` } } @@ -118,35 +132,100 @@ -
-

- {script?.path ?? 'Loading...'} - - {truncateHash(script?.hash ?? '')} - Each script version has an immutable hash. - - {#if script?.is_template} - Template - {/if} - {#if script && script.kind != 'script'} - {script.kind} - {/if} - - {#if deploymentInProgress} - - Deployment in progress +
+
+
+

+ {script?.path ?? 'Loading...'} +

+
+ + {truncateHash(script?.hash ?? '')} + + {#if script?.is_template} + Template + {/if} + {#if script && script.kind !== 'script'} + + {script?.kind} + + {/if} + {#if deploymentInProgress} + + Deployment in progress + + {/if} +
+
+

+ + + {#if script} + Edited {displayDaysAgo(script.created_at || '')} by {script.created_by || 'unknown'} + {/if} - {/if} -

+

+
{#if script} - -
+
{#if script === undefined}

loading

{:else} -

Edited {displayDaysAgo(script.created_at ?? '')} by {script.created_by}

- -

{script.summary}

- -
- +
+

{script.summary}

+
+ +
- {#if script.lock_error_logs} - - {/if} - {#if topHash} - - {/if} - {#if script.archived} - - {/if} - {#if script.deleted} - - {/if} - -
-

- Current hash The hash is an immutable and perpetual unique identifier for this version of this - script. The history of all hashes of a script constitute its lineage. This mechanism - shares some of the principles of git which identify each commit with an equivalent hash -

-

- {script?.hash} -

-

- Webhook to run this script and get job's uuid as response - Send a POST http request with a token as bearer token (or pass it as query arg 'token') - and the args respecting the corresponding jsonschema as payload. To create a permanent - token, go to your user setting by clicking your username on the top-left. -

- -
By hash: {$page.url.hostname}/api/w/{$workspaceStore}/jobs/run/h/{script?.hash}
-
By path: {$page.url.hostname}/api/w/{$workspaceStore}/jobs/run/p/{script?.path}
-

- Endpoint to run this script and get job's result as response - Send a POST http request with a token as bearer token (or pass it as query arg 'token') - and the args respecting the corresponding jsonschema as payload. To create a permanent - token, go to your user setting by clicking your username on the top-left. -

- -
{$page.url.hostname}/api/w/{$workspaceStore}/jobs/run_wait_result/p/{script?.path}
-
{$page.url.hostname}/api/w/{$workspaceStore}/jobs/run_wait_result/h/{script?.hash}
-
-
-

- Previous versions of this script When you edit a script, a new hash is created and the hashes corresponding to the - previous versions of this script are archived -

-
    - {#each script?.parent_hashes ?? [] as p_hash} -
  • {p_hash}
  • - {/each} -
-
-
-
-

- Arguments JSON schema The jsonschema defines the constraints that the payload must respect to be compatible - with the input parameters of this script. The UI form is generated automatically from - the script jsonschema. See jsonschema documentation + {#if script.lock_error_logs} + + {/if} + {#if topHash} +

+

Not HEAD

+

+ This hash is not HEAD (latest non-archived version at this path) : + Go to the HEAD of this path +

+
+ {/if} + {#if script.archived} + + {/if} + {#if script.deleted} + + {/if}
+ {/if} + +
+
+

Webhooks

+
+ + UUID + Result + + {#each Object.keys(webhooks) as key} + +
    + {#each Object.keys(webhooks[key]) as type} + {@const url = webhooks[key][type]} +
  • + + {url} + +
    + + {type} + + +
    +
  • + {/each} +
+
+ {/each} +
+
+
+
+
+

Versions

+
+

Current

+
+ {script?.hash} +
+

Previous

+ {#if script?.parent_hashes?.length} +
    + {#each script.parent_hashes as hash} +
  • + {hash} +
  • + {/each} +
+ {:else} +

There are no previous versions

+ {/if} +
+
+
+
+

+ Arguments JSON schema + + The jsonschema defines the constraints that the payload must respect to be compatible + with the input parameters of this script. The UI form is generated automatically from + the script jsonschema. See + jsonschema documentation + +

-

Code

+

Code

-

Dependencies lock file

-
{script.lock}
+

Dependencies lock file

+ {#if script?.lock} +
{script.lock}
+ {:else} +

There is no lock file for this script

+ {/if}
{/if}
- -