feat: add move to drawer for script and flows

This commit is contained in:
Ruben Fiszel
2022-12-21 06:55:24 +01:00
parent f7a40d5284
commit 8fe77cf15a
20 changed files with 179 additions and 50 deletions
+1
View File
@@ -4275,6 +4275,7 @@ components:
- hash
- path
- summary
- description
- content
- created_by
- created_at
+6 -5
View File
@@ -36,16 +36,17 @@
dispatch('click', { item: item?.eventName })
}
}}
class="block w-full whitespace-nowrap hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30 px-4 py-2 text-sm text-gray-700 text-left {item.separatorTop
? 'border-t'
: ''} {item.separatorBottom ? 'border-b' : ''} {item.type == 'delete'
class="block w-full whitespace-nowrap hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30
px-4 py-2 text-sm text-gray-700 text-left
{item.disabled ? 'bg-gray-100' : ''}
{item.separatorTop ? 'border-t' : ''} {item.separatorBottom ? 'border-b' : ''} {item.type ==
'delete'
? 'text-red-500'
: ''}"
role="menuitem"
tabindex="-1"
id="user-menu-item-{name}-{i}}"
disabled={item.disabled}
class:disabled={item.disabled}
>
{#if item.icon}
<Icon
@@ -66,7 +67,7 @@
e.preventDefault()
}
}}
class="block w-full px-4 py-2 text-sm text-gray-700 hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30"
class="block w-full px-4 font-semibold py-2 text-sm text-gray-700 hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30"
role="menuitem"
tabindex="-1"
id="user-menu-item-{name}-{i}}"
@@ -64,7 +64,8 @@
async function loadFolder(): Promise<void> {
folder = await FolderService.getFolder({ workspace: $workspaceStore!, name })
can_write = folder.owners.includes('u/' + $userStore?.username)
can_write =
folder.owners.includes('u/' + $userStore?.username) || ($userStore?.is_admin ?? false)
perms = Array.from(
new Set(
Object.entries(folder?.extra_perms ?? {})
@@ -216,7 +217,7 @@
(scripts/flows/apps/schedules/resources/variables) inside the folder</Tooltip
></ToggleButton
>
<ToggleButton position="right" value="owner" size="xs"
<ToggleButton position="right" value="admin" size="xs"
>Admin&nbsp;<Tooltip
>An admin of a folder has read AND write access to all the elements inside
the folders and can manage the permissions as well as add new admins</Tooltip
@@ -0,0 +1,84 @@
<script lang="ts">
import { isOwner } from '$lib/utils'
import { createEventDispatcher } from 'svelte'
import { userStore, workspaceStore } from '$lib/stores'
import { Alert, Button, Drawer } from './common'
import DrawerContent from './common/drawer/DrawerContent.svelte'
import Path from './Path.svelte'
import { FlowService, ScriptService } from '$lib/gen'
const dispatch = createEventDispatcher()
type Kind = 'script' | 'resource' | 'schedule' | 'variable' | 'flow' | 'app'
let kind: Kind
let initialPath: string = ''
let path: string = ''
let drawer: Drawer
let own = false
export async function openDrawer(initialPath_l: string, kind_l: Kind) {
kind = kind_l
initialPath = initialPath_l
drawer.openDrawer()
}
$: $userStore && $workspaceStore && loadOwner()
async function loadOwner() {
own = await isOwner(path, $userStore!, $workspaceStore!)
}
async function updatePath() {
if (kind == 'flow') {
const flow = await FlowService.getFlowByPath({
workspace: $workspaceStore!,
path: initialPath
})
await FlowService.updateFlow({
workspace: $workspaceStore!,
path: initialPath,
requestBody: {
path,
summary: flow.summary,
description: flow.description,
value: flow.value
}
})
} else if (kind == 'script') {
const script = await ScriptService.getScriptByPath({
workspace: $workspaceStore!,
path: initialPath
})
await ScriptService.createScript({
workspace: $workspaceStore!,
requestBody: {
...script,
description: script.description ?? '',
lock: script.lock?.split('\n'),
parent_hash: script.hash,
path
}
})
}
dispatch('update', path)
drawer.closeDrawer()
}
</script>
<Drawer bind:this={drawer}>
<DrawerContent title="Move {initialPath}" on:close={drawer.closeDrawer}>
<div class="flex flex-col gap-6">
<h1>Move {initialPath} to</h1>
{#if !own}
<Alert type="warning" title="Not owner"
>Since you do not own this item, you cannot move this item(you can however fork it!)</Alert
>
{/if}
<Path disabled={!own} {kind} {initialPath} bind:path />
<Button disabled={!own} on:click={updatePath}>Move</Button>
<div />
</div>
</DrawerContent>
</Drawer>
+2 -2
View File
@@ -350,7 +350,7 @@
></span
>
<div class="flex flex-row gap-1 w-full">
<div class="flex flex-row gap-1">
<select class="grow w-full" {disabled} bind:value={meta.owner}>
{#each groups as g}
<option>{g}</option>
@@ -366,7 +366,7 @@
</label>
{/if}
</div>
<label class="block grow">
<label class="block grow w-full max-w-md">
<span class="text-gray-700 text-sm">
Name
<Required required={true} />
@@ -13,8 +13,10 @@
const dispatch = createEventDispatcher()
export let kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow'
export let path: string = ''
type Kind = 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow'
let kind: Kind
let path: string = ''
let ownerKind: 'user' | 'group' = 'user'
let owner: string = ''
@@ -30,8 +32,9 @@
$: newOwner = [ownerKind === 'group' ? 'g' : 'u', owner].join('/')
let own = false
export async function openDrawer(newPath: string) {
export async function openDrawer(newPath: string, kind_l: Kind) {
path = newPath
kind = kind_l
loadAcls()
loadGroups()
loadUsernames()
@@ -66,7 +69,7 @@
requestBody: { owner }
})
loadAcls()
dispatch('change')
dispatch('change', { path, kind })
} catch (err) {
sendUserToast(err.toString(), true)
}
@@ -80,7 +83,7 @@
requestBody: { owner, write }
})
loadAcls()
dispatch('change')
dispatch('change', { path, kind })
}
</script>
@@ -1,6 +1,7 @@
<script lang="ts">
import { goto } from '$app/navigation'
import Dropdown from '$lib/components/Dropdown.svelte'
import type MoveDrawer from '$lib/components/MoveDrawer.svelte'
import ScheduleEditor from '$lib/components/ScheduleEditor.svelte'
import SharedBadge from '$lib/components/SharedBadge.svelte'
import type ShareModal from '$lib/components/ShareModal.svelte'
@@ -14,6 +15,7 @@
faCodeFork,
faEdit,
faEye,
faFileExport,
faList,
faPlay,
faShare
@@ -27,6 +29,7 @@
export let marked: string | undefined
export let starred: boolean
export let shareModal: ShareModal
export let moveDrawer: MoveDrawer
let { summary, path, extra_perms, canWrite, workspace_id } = flow
@@ -133,6 +136,13 @@
icon: faList,
href: `/runs/${path}`
},
{
displayName: 'Move',
icon: faFileExport,
action: () => {
moveDrawer.openDrawer(path, 'flow')
}
},
{
displayName: 'Schedule',
icon: faCalendarAlt,
@@ -141,10 +151,10 @@
}
},
{
displayName: 'Share',
displayName: canWrite ? 'Share' : 'See Permissions',
icon: faShare,
action: () => {
shareModal.openDrawer && shareModal.openDrawer(path)
shareModal.openDrawer && shareModal.openDrawer(path, 'flow')
}
},
{
@@ -1,6 +1,7 @@
<script lang="ts">
import { goto } from '$app/navigation'
import Dropdown from '$lib/components/Dropdown.svelte'
import type MoveDrawer from '$lib/components/MoveDrawer.svelte'
import ScheduleEditor from '$lib/components/ScheduleEditor.svelte'
import SharedBadge from '$lib/components/SharedBadge.svelte'
import type ShareModal from '$lib/components/ShareModal.svelte'
@@ -14,6 +15,7 @@
faCodeFork,
faEdit,
faEye,
faFileExport,
faList,
faPlay,
faShare
@@ -28,6 +30,7 @@
export let marked: string | undefined
export let starred: boolean
export let shareModal: ShareModal
export let moveDrawer: MoveDrawer
let {
summary,
@@ -153,6 +156,13 @@
icon: faCodeFork,
href: `/scripts/add?template=${path}`
},
{
displayName: 'Move',
icon: faFileExport,
action: () => {
moveDrawer.openDrawer(path, 'script')
}
},
{
displayName: 'View runs',
icon: faList,
@@ -166,10 +176,10 @@
}
},
{
displayName: 'Share',
displayName: canWrite ? 'Share' : 'See Permissions',
icon: faShare,
action: () => {
shareModal.openDrawer && shareModal.openDrawer(path)
shareModal.openDrawer && shareModal.openDrawer(path, 'script')
}
},
{
@@ -139,7 +139,7 @@ export function buildExtraLib(flowInput: Record<string, any>, results: Record<st
return `
/**
* get variable (including secret) at path
* @param {string} path - path of the variable (e.g: g/all/pretty_secret)
* @param {string} path - path of the variable (e.g: f/examples/secret)
*/
declare function variable(path: string): string;
@@ -19,6 +19,7 @@
import SearchItems from '../SearchItems.svelte'
import { Icon } from 'svelte-awesome'
import { faBarsStaggered } from '@fortawesome/free-solid-svg-icons'
import MoveDrawer from '../MoveDrawer.svelte'
type TableItem<T, U extends 'script' | 'flow' | 'app'> = T & {
canWrite: boolean
@@ -40,8 +41,8 @@
let itemKind: 'script' | 'flow' | 'app' | 'all' = 'all'
let shareModalScripts: ShareModal
let shareModalFlows: ShareModal
let shareModal: ShareModal
let moveDrawer: MoveDrawer
let loading = true
@@ -208,17 +209,19 @@
/>
<ShareModal
bind:this={shareModalScripts}
kind="script"
bind:this={shareModal}
on:change={() => {
loadScripts()
loadApps()
loadFlows()
}}
/>
<ShareModal
bind:this={shareModalFlows}
kind="flow"
on:change={() => {
<MoveDrawer
bind:this={moveDrawer}
on:update={() => {
loadScripts()
loadApps()
loadFlows()
}}
/>
@@ -300,7 +303,8 @@
marked={item.marked}
on:change={loadScripts}
script={item}
shareModal={shareModalScripts}
{shareModal}
{moveDrawer}
/>
{:else if item.type == 'flow'}
<FlowRow
@@ -308,7 +312,8 @@
marked={item.marked}
on:change={loadFlows}
flow={item}
shareModal={shareModalFlows}
{shareModal}
{moveDrawer}
/>
{:else if item.type == 'app'}
<AppRow
+4 -4
View File
@@ -25,11 +25,11 @@ def main(no_default: str,
# secret fetching is audited by windmill.
try:
secret = wmill.get_variable("g/all/pretty_secret")
secret = wmill.get_variable("f/examples/secret")
except:
secret = "No secret yet at g/all/pretty_secret!"
secret = "No secret yet at f/examples/secret !"
print(f"The variable at \`g/all/pretty_secret\`: {secret}")
print(f"The variable at \`f/examples/secret\`: {secret}")
# Get last state of this script execution by the same trigger/user
last_state = wmill.get_state()
@@ -73,7 +73,7 @@ func main(x string, nested struct{ Foo string \`json:"foo"\` }) (interface{}, er
fmt.Println("Hello, World")
fmt.Println(nested.Foo)
fmt.Println(quote.Opt())
// v, _ := wmill.GetVariable("g/all/pretty_secret")
// v, _ := wmill.GetVariable("f/examples/secret")
return x, nil
}
`
@@ -161,7 +161,7 @@
Schedule
</Button>
<Button
on:click={() => shareModal.openDrawer(flow?.path ?? '')}
on:click={() => shareModal.openDrawer(flow?.path ?? '', 'flow')}
variant="border"
color="light"
size="xs"
@@ -218,7 +218,7 @@
<h2 class="font-bold pb-4">{flow.path}</h2>
{/if}
{/if}
<ShareModal bind:this={shareModal} kind="flow" path={flow?.path ?? ''} />
<ShareModal bind:this={shareModal} />
<div class="grid grid-cols-1 gap-6 max-w-7xl pb-6">
<Skeleton
+5 -1
View File
@@ -103,7 +103,11 @@
<tbody slot="body">
{#if folders === undefined}
{#each new Array(6) as _}
<Skeleton layout={[0.25, [2], 0.25]} />
<tr>
<td colspan="4">
<Skeleton layout={[[2]]} />
</td>
</tr>
{/each}
{:else}
{#if folders.length === 0}
+5 -3
View File
@@ -94,9 +94,11 @@
</tr>
<tbody slot="body">
{#if groups === undefined}
{#each new Array(6) as _}
<Skeleton layout={[0.25, [2], 0.25]} />
{/each}
<tr>
<td colspan="4">
<Skeleton layout={[[2]]} />
</td>
</tr>
{:else}
{#each groups as { name, summary, extra_perms, canWrite }}
<tr>
+2 -3
View File
@@ -459,10 +459,10 @@
placement="bottom-end"
dropdownItems={[
{
displayName: 'Share',
displayName: !canWrite ? 'View Permissions' : 'Share',
icon: faShare,
action: () => {
shareModal.openDrawer?.(path)
shareModal.openDrawer?.(path, 'resource')
}
},
{
@@ -604,7 +604,6 @@
<ShareModal
bind:this={shareModal}
kind="resource"
on:change={() => {
loadResources()
}}
+2 -3
View File
@@ -185,10 +185,10 @@
}
},
{
displayName: 'Share',
displayName: canWrite ? 'Share' : 'See Permissions',
icon: faShare,
action: () => {
shareModal.openDrawer(path)
shareModal.openDrawer(path, 'schedule')
}
}
]}
@@ -204,7 +204,6 @@
<ShareModal
bind:this={shareModal}
kind="schedule"
on:change={() => {
loadSchedules()
}}
@@ -272,7 +272,7 @@
Publish to Hub
</Button>
<Button
on:click={() => shareModal.openDrawer(script?.path ?? '')}
on:click={() => shareModal.openDrawer(script?.path ?? '', 'script')}
variant="border"
color="light"
size="xs"
@@ -487,4 +487,4 @@
<UserSettings bind:this={userSettings} />
<ShareModal bind:this={shareModal} kind="script" path={script?.path ?? ''} />
<ShareModal bind:this={shareModal} />
+2 -3
View File
@@ -124,7 +124,6 @@
<VariableEditor bind:this={variableEditor} on:create={loadVariables} />
<ShareModal
bind:this={shareModal}
kind="variable"
on:change={() => {
loadVariables()
}}
@@ -308,9 +307,9 @@
disabled: !canWrite
},
{
displayName: 'Share',
displayName: canWrite ? 'Share' : 'See Permissions',
action: () => {
shareModal.openDrawer(path)
shareModal.openDrawer(path, 'variable')
},
icon: faShare
},
+1
View File
@@ -40,3 +40,4 @@ rsa = "*"
cryptography = "*"
pyparsing = "*"
jmespath = "*"
boto3 = "*"
+10
View File
@@ -4,6 +4,7 @@ from typing import Generic, TypeVar, TypeAlias
import os
from time import sleep
from windmill_api.models.whoami_response_200 import WhoamiResponse200
from windmill_api.client import AuthenticatedClient
@@ -179,6 +180,15 @@ def get_resource(path: str | None = None, none_if_undefined: bool = False) -> An
return _transform_leaf(raw)
def whoami() -> WhoamiResponse200 | None:
"""
Returns the current user
"""
from windmill_api.api.user import whoami
return whoami.sync(client=create_client(), workspace=get_workspace())
def get_state() -> Any:
"""
Get the state