mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-12 08:05:44 +00:00
feat(frontend): add toast actions (#1411)
* feat(frontend): add toast actions * feat(frontend): Fix callback * feat(frontend): Add start from blank * feat(frontend): support flow as well
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
<script lang="ts">
|
||||
import type { ToastAction } from '$lib/utils'
|
||||
import { toast } from '@zerodevx/svelte-toast'
|
||||
import { CheckCircle2, XCircleIcon } from 'lucide-svelte'
|
||||
import { onMount } from 'svelte'
|
||||
import Button from './common/button/Button.svelte'
|
||||
|
||||
export let message: string
|
||||
export let toastId: string
|
||||
export let error: boolean = false
|
||||
export let actions: ToastAction[] = []
|
||||
|
||||
function handleClose() {
|
||||
toast.pop(toastId)
|
||||
@@ -33,6 +36,19 @@
|
||||
</div>
|
||||
<div class="ml-3 w-0 flex-1">
|
||||
<p class="text-sm text-gray-500">{message}</p>
|
||||
<div class="mt-2 flex flex-row gap-2 h-15">
|
||||
{#each actions as action, index (index)}
|
||||
<Button
|
||||
on:click={() => {
|
||||
action.callback()
|
||||
toast.pop(toastId)
|
||||
}}
|
||||
class="text-sm !text-black"
|
||||
>
|
||||
{action.label}
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-4 flex flex-shrink-0">
|
||||
<button
|
||||
|
||||
@@ -79,13 +79,23 @@ export function getToday() {
|
||||
return today
|
||||
}
|
||||
|
||||
export function sendUserToast(message: string, error: boolean = false): void {
|
||||
export type ToastAction = {
|
||||
label: string
|
||||
callback: () => void
|
||||
}
|
||||
|
||||
export function sendUserToast(
|
||||
message: string,
|
||||
error: boolean = false,
|
||||
actions: ToastAction[] = []
|
||||
): void {
|
||||
toast.push({
|
||||
component: {
|
||||
src: Toast,
|
||||
props: {
|
||||
message,
|
||||
error
|
||||
error,
|
||||
actions
|
||||
},
|
||||
sendIdTo: 'toastId'
|
||||
},
|
||||
|
||||
@@ -74,7 +74,20 @@
|
||||
sendUserToast('App loaded from Hub')
|
||||
goto('?', { replaceState: true })
|
||||
} else if (!templatePath && !hubId && state) {
|
||||
sendUserToast('App restored from draft')
|
||||
sendUserToast('App restored from draft', false, [
|
||||
{
|
||||
label: 'Start from blank',
|
||||
callback: () => {
|
||||
value = {
|
||||
grid: [],
|
||||
fullscreen: false,
|
||||
unusedInlineScripts: [],
|
||||
hiddenInlineScripts: [],
|
||||
css: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
value = decodeState(state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
import { AppService, AppWithLastVersion } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { page } from '$app/stores'
|
||||
import { decodeState, sendUserToast } from '$lib/utils'
|
||||
import { decodeState, sendUserToast, type ToastAction } from '$lib/utils'
|
||||
import { goto } from '$app/navigation'
|
||||
import { dirtyStore } from '$lib/components/common/confirmationModal/dirtyStore'
|
||||
|
||||
let app: AppWithLastVersion | undefined = undefined
|
||||
$: app = undefined as AppWithLastVersion | undefined
|
||||
|
||||
let redraw = 0
|
||||
let path = $page.params.path
|
||||
|
||||
let nodraft = $page.url.searchParams.get('nodraft')
|
||||
@@ -16,16 +18,37 @@
|
||||
goto('?', { replaceState: true })
|
||||
}
|
||||
|
||||
function restoreTempValue(tempValue) {
|
||||
if (app) {
|
||||
app.value = tempValue
|
||||
app = app
|
||||
redraw++
|
||||
}
|
||||
}
|
||||
|
||||
async function loadApp(): Promise<void> {
|
||||
app = await AppService.getAppByPath({
|
||||
path,
|
||||
workspace: $workspaceStore!
|
||||
})
|
||||
|
||||
const tempValue = app.value
|
||||
|
||||
const initialState = nodraft ? undefined : localStorage.getItem(`app-${$page.params.path}`)
|
||||
let stateLoadedFromUrl = initialState != undefined ? decodeState(initialState) : undefined
|
||||
|
||||
if (stateLoadedFromUrl) {
|
||||
sendUserToast('App restored from draft')
|
||||
const actions: ToastAction[] = []
|
||||
if (JSON.stringify(app.value) !== JSON.stringify(stateLoadedFromUrl)) {
|
||||
actions.push({
|
||||
label: 'Load from last save instead',
|
||||
callback: () => {
|
||||
restoreTempValue(tempValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
sendUserToast('App restored from draft', false, actions)
|
||||
app.value = stateLoadedFromUrl
|
||||
}
|
||||
$dirtyStore = false
|
||||
@@ -38,8 +61,10 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if app}
|
||||
<div class="h-screen">
|
||||
<AppEditor summary={app.summary} app={app.value} path={app.path} policy={app.policy} />
|
||||
</div>
|
||||
{/if}
|
||||
{#key redraw}
|
||||
{#if app}
|
||||
<div class="h-screen">
|
||||
<AppEditor summary={app.summary} app={app.value} path={app.path} policy={app.policy} />
|
||||
</div>
|
||||
{/if}
|
||||
{/key}
|
||||
|
||||
@@ -55,7 +55,24 @@
|
||||
$importFlowStore = undefined
|
||||
sendUserToast('Flow loaded from JSON')
|
||||
} else if (!templatePath && !hubId && state) {
|
||||
sendUserToast('Flow restored from draft')
|
||||
sendUserToast('Flow restored from draft', false, [
|
||||
{
|
||||
label: 'Start from blank instead',
|
||||
callback: () => {
|
||||
$flowStore = {
|
||||
summary: '',
|
||||
value: { modules: [] },
|
||||
path: '',
|
||||
edited_at: '',
|
||||
edited_by: '',
|
||||
archived: false,
|
||||
extra_perms: {},
|
||||
schema: emptySchema()
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
flow = state.flow
|
||||
state?.selectedId && (selectedId = state?.selectedId)
|
||||
} else {
|
||||
|
||||
@@ -40,7 +40,19 @@
|
||||
loading = true
|
||||
let flow: Flow
|
||||
if (stateLoadedFromUrl != undefined && stateLoadedFromUrl?.flow?.path == $page.params.path) {
|
||||
sendUserToast('Flow restored from draft')
|
||||
sendUserToast('Flow restored from draft', false, [
|
||||
{
|
||||
label: 'Restore last saved version instead',
|
||||
callback: () => {
|
||||
FlowService.getFlowByPath({
|
||||
workspace: $workspaceStore!,
|
||||
path: $page.params.path
|
||||
}).then((flow) => {
|
||||
$flowStore = flow
|
||||
})
|
||||
}
|
||||
}
|
||||
])
|
||||
flow = stateLoadedFromUrl.flow
|
||||
} else {
|
||||
flow = await FlowService.getFlowByPath({
|
||||
|
||||
Reference in New Issue
Block a user