mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-04 16:03:06 +00:00
UI improvements
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
import { sleep } from '$lib/utils'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import Required from './Required.svelte'
|
||||
import Popover from './Popover.svelte'
|
||||
|
||||
type PathKind = 'resource' | 'script' | 'variable' | 'flow' | 'schedule'
|
||||
export let meta: Meta = {
|
||||
@@ -164,9 +165,15 @@
|
||||
<div class="flex flex-col sm:grid sm:grid-cols-4 sm:gap-4 pb-0 mb-1">
|
||||
<label class="block">
|
||||
<span class="text-gray-700 text-sm whitespace-nowrap">
|
||||
Owner Kind <Tooltip>
|
||||
<slot name="ownerToolkit" />
|
||||
</Tooltip>
|
||||
<Popover
|
||||
>Owner Kind
|
||||
<span slot="text"
|
||||
>Select the group <span class="font-mono">all</span>
|
||||
to share it with all workspace users, and <span class="font-mono">user</span> to keep it
|
||||
private.
|
||||
<a href="https://docs.windmill.dev/docs/reference/namespaces">docs</a>
|
||||
</span>
|
||||
</Popover>
|
||||
</span>
|
||||
|
||||
<select
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<script lang="ts">
|
||||
import { createPopperActions } from 'svelte-popperjs'
|
||||
const [popperRef, popperContent] = createPopperActions({
|
||||
placement: 'auto'
|
||||
})
|
||||
const betterPreventOverflow = (options) => ({
|
||||
name: 'preventOverflow',
|
||||
options,
|
||||
effect: ({ state }) => {
|
||||
const { padding = 0 } = options
|
||||
|
||||
state.elements.popper.style.maxWidth = `calc(100vw - ${padding * 2}px)`
|
||||
}
|
||||
})
|
||||
const extraOpts = {
|
||||
modifiers: [
|
||||
betterPreventOverflow({ padding: 10 }),
|
||||
{ name: 'offset', options: { offset: [8, 8] } },
|
||||
{
|
||||
name: 'arrow',
|
||||
options: {
|
||||
padding: 10 // 5px from the edges of the popper
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
let showTooltip = false
|
||||
let timeout: NodeJS.Timeout
|
||||
|
||||
function open() {
|
||||
clearTimeout(timeout)
|
||||
showTooltip = true
|
||||
}
|
||||
function close() {
|
||||
timeout = setTimeout(() => (showTooltip = false), 100)
|
||||
}
|
||||
</script>
|
||||
|
||||
<button use:popperRef on:mouseenter={open} on:mouseleave={close}>
|
||||
<slot />
|
||||
</button>
|
||||
{#if showTooltip}
|
||||
<div id="tooltip" use:popperContent={extraOpts} on:mouseenter={open} on:mouseleave={close}>
|
||||
<div class="max-w-sm">
|
||||
<slot name="text" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
#tooltip {
|
||||
@apply z-50 text-sm font-normal text-gray-300 bg-gray-800 p-4 rounded-xl whitespace-normal text-left;
|
||||
}
|
||||
</style>
|
||||
@@ -137,15 +137,7 @@
|
||||
{initialPath}
|
||||
namePlaceholder="my_resource"
|
||||
kind="resource"
|
||||
>
|
||||
<div slot="ownerToolkit">
|
||||
Resource permissions depend on their path. Select the group <span class="font-mono"
|
||||
>all</span
|
||||
>
|
||||
to share it, and <span class="font-mono">user</span> to keep it private.
|
||||
<a href="https://docs.windmill.dev/docs/reference/namespaces">docs</a>
|
||||
</div>
|
||||
</Path>
|
||||
/>
|
||||
</div>
|
||||
<span class=" mt-3 font-semibold text-gray-700 "
|
||||
>Description <Required required={false} />
|
||||
|
||||
@@ -174,14 +174,7 @@
|
||||
on:enter={() => changeStep(2)}
|
||||
namePlaceholder="my_script"
|
||||
kind="script"
|
||||
>
|
||||
<div slot="ownerToolkit">
|
||||
Script permissions depend on their path. Select the group
|
||||
<span class="font-mono"> all </span>
|
||||
to share your script, and <span class="font-mono">user</span> to keep it private.
|
||||
<a href="https://docs.windmill.dev/docs/reference/namespaces">docs</a>
|
||||
</div>
|
||||
</Path>
|
||||
/>
|
||||
<label class="block ">
|
||||
<span class="text-gray-700 text-sm">Summary <Required required={false} /></span>
|
||||
<textarea
|
||||
|
||||
@@ -60,15 +60,15 @@
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="flex flex-row flex-wrap items-center gap-4">
|
||||
<div class="w-80 -mb-2">
|
||||
{#if options.length > 1}
|
||||
<div class="flex flex-row flex-wrap items-center gap-4 w-full">
|
||||
{#if options.length > 1}
|
||||
<div class="w-80 -mb-2">
|
||||
<RadioButton bind:value={itemKind} {options} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center grow gap-4">
|
||||
<input type="text" value={scriptPath ?? 'No path chosen yet'} disabled />
|
||||
<input class="grow w-full" type="text" value={scriptPath ?? 'No path chosen yet'} disabled />
|
||||
<Button
|
||||
size="sm"
|
||||
endIcon={{ icon: faSearch }}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<tr>
|
||||
{#each keys as key, i}
|
||||
<td
|
||||
class="py-2 text-sm text-gray-700 {i == 0
|
||||
class="py-2 text-sm text-gray-700 break-all {i == 0
|
||||
? 'pl-4 pr-3 sm:pl-6 md:pl-0 font-semibold'
|
||||
: 'px-3'} {twTextSize}"
|
||||
>
|
||||
|
||||
@@ -1,65 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons'
|
||||
import Icon from 'svelte-awesome'
|
||||
import { createPopperActions } from 'svelte-popperjs'
|
||||
const [popperRef, popperContent] = createPopperActions({
|
||||
placement: 'auto'
|
||||
})
|
||||
const betterPreventOverflow = (options) => ({
|
||||
name: 'preventOverflow',
|
||||
options,
|
||||
effect: ({ state }) => {
|
||||
const { padding = 0 } = options
|
||||
|
||||
state.elements.popper.style.maxWidth = `calc(100vw - ${padding * 2}px)`
|
||||
}
|
||||
})
|
||||
const extraOpts = {
|
||||
modifiers: [
|
||||
betterPreventOverflow({ padding: 10 }),
|
||||
{ name: 'offset', options: { offset: [8, 8] } },
|
||||
{
|
||||
name: 'arrow',
|
||||
options: {
|
||||
padding: 10 // 5px from the edges of the popper
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
let showTooltip = false
|
||||
let timeout: NodeJS.Timeout
|
||||
|
||||
function open() {
|
||||
clearTimeout(timeout)
|
||||
showTooltip = true
|
||||
}
|
||||
function close() {
|
||||
timeout = setTimeout(() => (showTooltip = false), 100)
|
||||
}
|
||||
import Popover from './Popover.svelte'
|
||||
</script>
|
||||
|
||||
<button use:popperRef on:mouseenter={open} on:mouseleave={close}>
|
||||
<Popover>
|
||||
<Icon
|
||||
class="text-gray-500 font-thin inline-block align-middle w-4"
|
||||
data={faInfoCircle}
|
||||
scale={0.8}
|
||||
/>
|
||||
</button>
|
||||
{#if showTooltip}
|
||||
<div
|
||||
id="tooltip"
|
||||
use:popperContent={extraOpts}
|
||||
on:mouseenter={open}
|
||||
on:mouseleave={close}
|
||||
class="w-96 text-left"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
#tooltip {
|
||||
@apply z-50 text-base font-normal text-gray-300 bg-gray-800 p-4 rounded-xl whitespace-normal;
|
||||
}
|
||||
</style>
|
||||
<span slot="text"> <slot /> </span>
|
||||
</Popover>
|
||||
|
||||
@@ -90,21 +90,23 @@
|
||||
$: endIconClass = classNames(iconOnly ? undefined : isSmall ? 'ml-1' : 'ml-2', endIcon?.classes)
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={href ? 'a' : 'button'}
|
||||
bind:this={element}
|
||||
on:click={onClick}
|
||||
on:focus
|
||||
on:blur
|
||||
{...buttonProps}
|
||||
>
|
||||
{#if startIcon}
|
||||
<Icon data={startIcon.icon} class={startIconClass} scale={ButtonType.IconScale[size]} />
|
||||
{/if}
|
||||
{#if !iconOnly}
|
||||
<slot />
|
||||
{/if}
|
||||
{#if endIcon}
|
||||
<Icon data={endIcon.icon} class={endIconClass} scale={ButtonType.IconScale[size]} />
|
||||
{/if}
|
||||
</svelte:element>
|
||||
<div class="inline-flex">
|
||||
<svelte:element
|
||||
this={href ? 'a' : 'button'}
|
||||
bind:this={element}
|
||||
on:click={onClick}
|
||||
on:focus
|
||||
on:blur
|
||||
{...buttonProps}
|
||||
>
|
||||
{#if startIcon}
|
||||
<Icon data={startIcon.icon} class={startIconClass} scale={ButtonType.IconScale[size]} />
|
||||
{/if}
|
||||
{#if !iconOnly}
|
||||
<slot />
|
||||
{/if}
|
||||
{#if endIcon}
|
||||
<Icon data={endIcon.icon} class={endIconClass} scale={ButtonType.IconScale[size]} />
|
||||
{/if}
|
||||
</svelte:element>
|
||||
</div>
|
||||
|
||||
@@ -25,14 +25,7 @@
|
||||
|
||||
<svelte:fragment slot="content">
|
||||
<TabContent value="metadata" class="p-4">
|
||||
<Path bind:path={$flowStore.path} {initialPath} namePlaceholder="my_flow" kind="flow">
|
||||
<div slot="ownerToolkit">
|
||||
Flow permissions depend on their path. Select the group
|
||||
<span class="font-mono"> all </span>
|
||||
to share your flow, and <span class="font-mono">user</span> to keep it private.
|
||||
<a href="https://docs.windmill.dev/docs/reference/namespaces">docs</a>
|
||||
</div>
|
||||
</Path>
|
||||
<Path bind:path={$flowStore.path} {initialPath} namePlaceholder="my_flow" kind="flow" />
|
||||
|
||||
<label class="block my-4">
|
||||
<span class="text-gray-700 text-sm">Summary <Required required={false} /></span>
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<CenteredPage>
|
||||
<PageHeader
|
||||
title="Audit logs"
|
||||
tooltip="You can only see the audit logs you have visibility on, so only your own as a user."
|
||||
tooltip="You can only see your own audit logs unless you are an admin."
|
||||
/>
|
||||
|
||||
<Alert type="info" title="Audit logs are a team or enterprise feature - Unlimited during beta">
|
||||
|
||||
@@ -68,7 +68,10 @@
|
||||
<GroupModal bind:this={groupModal} />
|
||||
|
||||
<CenteredPage>
|
||||
<PageHeader title="Groups">
|
||||
<PageHeader
|
||||
title="Groups"
|
||||
tooltip="Group users together to grant roles and homegenous permissions. Same users can be in many groups at the same time."
|
||||
>
|
||||
<div class="flex flex-row">
|
||||
<input
|
||||
class="mr-2"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { canWrite, emptySchema, sendUserToast } from '$lib/utils'
|
||||
import { canWrite, emptySchema, sendUserToast, truncate } from '$lib/utils'
|
||||
import { ResourceService, VariableService } from '$lib/gen'
|
||||
import type { Resource, ResourceType } from '$lib/gen'
|
||||
import PageHeader from '$lib/components/PageHeader.svelte'
|
||||
@@ -50,6 +50,7 @@
|
||||
let resourceViewer: Modal
|
||||
let resourceViewerTitle: string = ''
|
||||
let resourceViewerSchema: Schema = emptySchema()
|
||||
let resourceViewerDescription = ''
|
||||
let typeModalMode: 'view' | 'view-type' | 'create' = 'view'
|
||||
let newResourceTypeName: string
|
||||
let newResourceTypeSchema: Schema
|
||||
@@ -153,7 +154,10 @@
|
||||
</script>
|
||||
|
||||
<CenteredPage>
|
||||
<PageHeader title="Resources">
|
||||
<PageHeader
|
||||
title="Resources"
|
||||
tooltip="Save and permission rich objects (JSON) including credentials obtained through OAuth."
|
||||
>
|
||||
<div class="flex flex-row space-x-4">
|
||||
<Button size="sm" startIcon={{ icon: faChain }} on:click={() => appConnect.open()}>
|
||||
Connect an API
|
||||
@@ -174,7 +178,7 @@
|
||||
<TableCustom>
|
||||
<tr slot="header-row">
|
||||
<th>path</th>
|
||||
<th>resource_type</th>
|
||||
<th>resource type</th>
|
||||
<th>description</th>
|
||||
<th>OAuth</th>
|
||||
<th />
|
||||
@@ -189,12 +193,12 @@
|
||||
href="#{path}"
|
||||
on:click={async () => {
|
||||
resourceViewerTitle = `Resource ${path}`
|
||||
resourceViewerSchema = (
|
||||
await ResourceService.getResource({
|
||||
workspace: $workspaceStore ?? 'no_workspace',
|
||||
path
|
||||
})
|
||||
).value
|
||||
const resource = await ResourceService.getResource({
|
||||
workspace: $workspaceStore ?? 'no_workspace',
|
||||
path
|
||||
})
|
||||
resourceViewerSchema = resource.value
|
||||
resourceViewerDescription = resource.description ?? ''
|
||||
typeModalMode = 'view'
|
||||
resourceViewer.openModal()
|
||||
}}>{path}</a
|
||||
@@ -202,8 +206,12 @@
|
||||
<div class="mb-1 -mt-1"><SharedBadge {canWrite} extraPerms={extra_perms} /></div>
|
||||
</td>
|
||||
<td class="px-2"><IconedResourceType name={resource_type} after={true} /></td>
|
||||
<td><SvelteMarkdown source={description ?? ''} /></td>
|
||||
<td>
|
||||
<td
|
||||
><span class="text-gray-500 text-xs"
|
||||
><SvelteMarkdown source={truncate(description ?? '', 30)} /></span
|
||||
></td
|
||||
>
|
||||
<td class="text-center">
|
||||
{#if is_oauth}
|
||||
<Icon
|
||||
class="text-green-600"
|
||||
@@ -263,7 +271,11 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="py-10" />
|
||||
<PageHeader title="Resources types" primary={false}>
|
||||
<PageHeader
|
||||
title="Resources types"
|
||||
primary={false}
|
||||
tooltip="Schema and label to filter resources by type"
|
||||
>
|
||||
<Button size="sm" startIcon={{ icon: faPlus }} on:click={startNewType}>Add a type</Button>
|
||||
</PageHeader>
|
||||
|
||||
@@ -289,17 +301,23 @@
|
||||
on:click={() => {
|
||||
resourceViewerTitle = `Resource type ${name}`
|
||||
resourceViewerSchema = schema
|
||||
resourceViewerDescription = description ?? ''
|
||||
typeModalMode = 'view-type'
|
||||
resourceViewer.openModal()
|
||||
}}><IconedResourceType after={true} {name} /></a
|
||||
></td
|
||||
>
|
||||
<td><SvelteMarkdown source={description ?? ''} /></td>
|
||||
<td
|
||||
><span class="text-gray-500 text-xs"
|
||||
><SvelteMarkdown source={truncate(description ?? '', 30)} /></span
|
||||
></td
|
||||
>
|
||||
<td>
|
||||
{#if canWrite}
|
||||
<Button
|
||||
size="sm"
|
||||
color="red"
|
||||
variant="border"
|
||||
startIcon={{ icon: faTrash }}
|
||||
on:click={() => handleDeleteResourceType(name)}
|
||||
disabled={!($userStore?.is_admin || false)}
|
||||
@@ -358,8 +376,16 @@
|
||||
</div>
|
||||
</div>
|
||||
{:else if typeModalMode === 'view'}
|
||||
<Highlight language={json} code={JSON.stringify(resourceViewerSchema, null, 4)} />
|
||||
<div class="py-2 bg-gray-100">
|
||||
<SvelteMarkdown source={resourceViewerDescription} />
|
||||
</div>
|
||||
<div class="border p-2">
|
||||
<Highlight language={json} code={JSON.stringify(resourceViewerSchema, null, 4)} />
|
||||
</div>
|
||||
{:else if typeModalMode === 'view-type'}
|
||||
<div class="py-2 bg-gray-100">
|
||||
<SvelteMarkdown source={resourceViewerDescription} />
|
||||
</div>
|
||||
<SchemaViewer schema={resourceViewerSchema} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
import { Skeleton } from '$lib/components/common'
|
||||
import Tooltip from '../../lib/components/Tooltip.svelte'
|
||||
import { goto } from '$app/navigation'
|
||||
import PageHeader from '$lib/components/PageHeader.svelte'
|
||||
|
||||
let jobs: Job[] | undefined
|
||||
let error: Error | undefined
|
||||
@@ -147,16 +148,13 @@
|
||||
</script>
|
||||
|
||||
<CenteredPage>
|
||||
<div class="flex items-center min-h-[48px] my-4">
|
||||
<h1 class="mr-1">Runs {path ? `of ${path}` : ''}</h1>
|
||||
<Tooltip>
|
||||
All past and schedule executions of scripts and flows, including previews.
|
||||
<br />
|
||||
You only see your own runs or runs of groups you belong to unless you are an admin.
|
||||
</Tooltip>
|
||||
</div>
|
||||
<PageHeader
|
||||
title="Runs {path ? `of ${path}` : ''}"
|
||||
tooltip="All past and schedule executions of scripts and flows, including previews.
|
||||
You only see your own runs or runs of groups you belong to unless you are an admin."
|
||||
/>
|
||||
|
||||
<div class="max-w-7x">
|
||||
<div class="max-w-7x mt-6">
|
||||
<div class="flex flex-row space-x-4">
|
||||
<select
|
||||
bind:value={success}
|
||||
|
||||
@@ -126,15 +126,7 @@
|
||||
{initialPath}
|
||||
namePlaceholder={'my_schedule'}
|
||||
kind="schedule"
|
||||
>
|
||||
<div slot="ownerToolkit">
|
||||
Schedule permissions depend on their path. Select the group <span class="font-mono"
|
||||
>all</span
|
||||
>
|
||||
to share it, and <span class="font-mono">user</span> to keep it private.
|
||||
<a href="https://docs.windmill.dev/docs/reference/namespaces">docs</a>
|
||||
</div></Path
|
||||
>
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<h2 class="border-b pb-1 mt-8 mb-2">Script</h2>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</script>
|
||||
|
||||
<CenteredPage>
|
||||
<PageHeader title="Schedules">
|
||||
<PageHeader title="Schedules" tooltip="Trigger Scripts and Flows according to a cron schedule">
|
||||
<Button size="sm" startIcon={{ icon: faPlus }} href="/schedule/add">New schedule</Button>
|
||||
</PageHeader>
|
||||
<div class="relative mt-10">
|
||||
|
||||
@@ -162,12 +162,9 @@
|
||||
<CenteredPage>
|
||||
<PageHeader
|
||||
title="Scripts"
|
||||
tooltip="A script can either be used standalone or as part of a Flow.
|
||||
When standalone, it has an auto-generated UI from its parameters whom you can access clicking on 'Run'.
|
||||
Like everything in windmill, scripts have owners (users or groups) and can be shared to other users and other groups. It is enough to have
|
||||
read-access on a script to be able to execute it. However, you will also need to have been
|
||||
granted visibility on the resources and variables it uses, otherwise it will behave as if those
|
||||
items did not exist at runtime of the script."
|
||||
tooltip="A Script can be used standalone or as part of a Flow.
|
||||
When standalone, it has webhooks and an auto-generated UI from its parameters whom you can access clicking on 'Run'.
|
||||
Scripts have owners (users or groups) and can be shared to users and groups."
|
||||
>
|
||||
<CreateActions />
|
||||
</PageHeader>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { page } from '$app/stores'
|
||||
import { usersWorkspaceStore, workspaceStore } from '$lib/stores'
|
||||
import CenteredModal from '$lib/components/CenteredModal.svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import { Alert, Button } from '$lib/components/common'
|
||||
|
||||
const rd = $page.url.searchParams.get('rd')
|
||||
|
||||
@@ -82,15 +82,12 @@
|
||||
|
||||
<CenteredModal title="Create a new workspace">
|
||||
{#if $page.url.hostname != 'app.windmill.dev'}
|
||||
<div class="bg-blue-100 border-l-4 border-blue-600 text-blue-700 p-4 m-4" role="alert">
|
||||
<p class="font-bold">
|
||||
More than 1 user-created workspace for self-hosted will require a team or enterprise license
|
||||
- Unlimited during beta
|
||||
</p>
|
||||
</div>
|
||||
<Alert title="Restricted to 1 workspace - unlimited during beta" type="info">
|
||||
More than 1 user-created workspace for self-hosted will require a team or enterprise license
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
<label class="block pb-2">
|
||||
<label class="block pb-2 pt-4">
|
||||
<span class="text-gray-700">workspace name:</span>
|
||||
<input bind:value={name} class="mt-1" />
|
||||
</label>
|
||||
@@ -109,7 +106,9 @@
|
||||
<input bind:value={username} on:keyup={handleKeyUp} class="mt-1" />
|
||||
</label>
|
||||
<div class="flex flex-row justify-between pt-4">
|
||||
<a href="/user/workspaces">← Back to workspaces</a>
|
||||
<Button variant="border" size="sm" href="/user/workspaces"
|
||||
>← Back to workspaces</Button
|
||||
>
|
||||
<Button
|
||||
disabled={errorId != '' || errorUser != '' || !name || !username || !id}
|
||||
on:click={createWorkspace}
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
color="dark"
|
||||
variant="border"
|
||||
endIcon={{ icon }}
|
||||
btnClasses="mt-2"
|
||||
btnClasses="mt-2 w-full"
|
||||
on:click={() => storeRedirect(type)}
|
||||
>
|
||||
{name}
|
||||
|
||||
@@ -100,14 +100,14 @@
|
||||
</label>
|
||||
{/each}
|
||||
<div class="flex flex-row-reverse pt-4">
|
||||
<a
|
||||
<Button
|
||||
href="/user/create_workspace{rd ? `?rd=${encodeURIComponent(rd)}` : ''}"
|
||||
class="primary-button"
|
||||
>Create a new workspace →
|
||||
</a>
|
||||
variant="border"
|
||||
>+ Create a new workspace
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<h2 class="mt-6 mb-4">Invitations</h2>
|
||||
<h2 class="mt-6 mb-4">Invites to join a Workspace</h2>
|
||||
{#if invites.length == 0}
|
||||
<p class="text-sm text-gray-600 mt-2">You have no invites to any workspaces at the moment.</p>
|
||||
{/if}
|
||||
@@ -149,12 +149,12 @@
|
||||
{/each}
|
||||
<div class="flex justify-between items-center mt-10">
|
||||
{#if $superadmin}
|
||||
<a class="mr-10" href="/user/superadmin_settings">
|
||||
<Icon data={faCrown} class="mr-1" scale={1} />Superadmin settings</a
|
||||
<Button variant="border" size="sm" href="/user/superadmin_settings">
|
||||
<Icon data={faCrown} class="mr-1" scale={1} />Superadmin settings</Button
|
||||
>
|
||||
{/if}
|
||||
<a class="mr-10" href="/user/settings">
|
||||
<Icon data={faUserCog} class="mr-1" scale={1} />User settings</a
|
||||
<Button variant="border" size="sm" href="/user/settings">
|
||||
<Icon data={faUserCog} class="mr-1" scale={1} />User settings</Button
|
||||
>
|
||||
<Button
|
||||
variant="border"
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import CenteredPage from '$lib/components/CenteredPage.svelte'
|
||||
import Icon from 'svelte-awesome'
|
||||
import { faPlus, faCircle } from '@fortawesome/free-solid-svg-icons'
|
||||
import { faPlus, faCircle, faLock, faEyeSlash } from '@fortawesome/free-solid-svg-icons'
|
||||
import { Button } from '$lib/components/common'
|
||||
import ConfirmationModal from '$lib/components/common/confirmationModal/ConfirmationModal.svelte'
|
||||
import { Alert, Badge, Skeleton } from '$lib/components/common'
|
||||
import Popover from '$lib/components/Popover.svelte'
|
||||
|
||||
type ListableVariableW = ListableVariable & { canWrite: boolean }
|
||||
|
||||
@@ -74,7 +75,10 @@
|
||||
</script>
|
||||
|
||||
<CenteredPage>
|
||||
<PageHeader title="Variables">
|
||||
<PageHeader
|
||||
title="Variables"
|
||||
tooltip="Save and permission strings to be reused in Scripts and Flows."
|
||||
>
|
||||
<Button size="sm" startIcon={{ icon: faPlus }} on:click={() => variableEditor.initNew()}>
|
||||
New variable
|
||||
</Button>
|
||||
@@ -91,8 +95,8 @@
|
||||
<TableCustom>
|
||||
<tr slot="header-row">
|
||||
<th>path</th>
|
||||
|
||||
<th>value</th>
|
||||
<th>secret</th>
|
||||
<th>description</th>
|
||||
<th>OAuth</th>
|
||||
<th />
|
||||
@@ -109,13 +113,30 @@
|
||||
>
|
||||
<div><SharedBadge {canWrite} extraPerms={extra_perms} /></div>
|
||||
</td>
|
||||
<td>{truncate(value ?? '******', 40)}</td>
|
||||
<td>{is_secret ? 'secret' : 'visible'}</td>
|
||||
<td>{truncate(description ?? '', 50)}</td>
|
||||
<td>
|
||||
<td
|
||||
><span class="text-sm break-all">
|
||||
{truncate(value ?? '******', 20)}
|
||||
{#if is_secret}
|
||||
<Popover>
|
||||
<Icon
|
||||
label="Secret"
|
||||
class="text-gray-700 mb-2 ml-2"
|
||||
data={faEyeSlash}
|
||||
scale={0.8}
|
||||
/>
|
||||
<span slot="text">This item is secret</span>
|
||||
</Popover>
|
||||
{/if}
|
||||
</span></td
|
||||
>
|
||||
<td class="break-all"
|
||||
><span class="text-xs text-gray-500">{truncate(description ?? '', 50)}</span></td
|
||||
>
|
||||
|
||||
<td class="text-center">
|
||||
{#if is_oauth}
|
||||
<Icon
|
||||
class="text-green-600"
|
||||
class="text-green-500"
|
||||
data={faCircle}
|
||||
scale={0.7}
|
||||
label="Variable is tied to an OAuth app"
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
import AppConnect from '$lib/components/AppConnect.svelte'
|
||||
import { onMount } from 'svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
|
||||
let users: User[] = []
|
||||
let invites: WorkspaceInvite[] = []
|
||||
@@ -226,18 +227,18 @@
|
||||
Disconnect Slack
|
||||
</Button>
|
||||
{/if}
|
||||
<h3 class="mt-5 text-gray-700">Select a script to run on /windmill command:</h3>
|
||||
<h3 class="mt-5 text-gray-700"
|
||||
>Script to run on /windmill command <Tooltip>
|
||||
A script run from slack /windmill command is run as group 'slack'. The script chosen is
|
||||
passed the parameters <pre>response_url: string, text: string</pre> respectively the url to
|
||||
reply directly to the trigger and the text of the command.
|
||||
<a href="/scripts/add?template=u/admin/triggered_from_slack_command"
|
||||
>Define your own trigger script from a compatible template</a
|
||||
></Tooltip
|
||||
></h3
|
||||
>
|
||||
<ScriptPicker kind={Script.kind.SCRIPT} bind:scriptPath on:select={editSlackCommand} />
|
||||
|
||||
<p class="text-sm text-gray-700 italic mt-3">
|
||||
A script run from slack /windmill command is run as group 'slack' and hence every variables or
|
||||
resources used within it be visible to that group. The script chosen must be able to take as
|
||||
parameter `response_url: str, text: str`, respectively the url to reply directly to the
|
||||
trigger and the text of the command.
|
||||
<a href="/scripts/add?template=u/admin/triggered_from_slack_command"
|
||||
>Define your own trigger script from a compatible template</a
|
||||
>
|
||||
</p>
|
||||
<div class="mt-10" />
|
||||
<PageHeader title="Export workspace" primary={false} />
|
||||
<div class="flex justify-start">
|
||||
|
||||
@@ -254,7 +254,8 @@ const config = {
|
||||
'.table-custom': {
|
||||
'& th': {
|
||||
paddingTop: theme('spacing.3'),
|
||||
paddingRight: theme('spacing.2'),
|
||||
paddingRight: theme('spacing.1'),
|
||||
paddingLeft: theme('spacing.1'),
|
||||
paddingBottom: theme('spacing.3'),
|
||||
fontSize: theme('fontSize.sm'),
|
||||
textAlign: 'left',
|
||||
|
||||
Reference in New Issue
Block a user