overhaul app creation flow
This commit is contained in:
@@ -1,77 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { faPlus } from '@fortawesome/free-solid-svg-icons'
|
||||
import { AppService, Policy } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { Button, Drawer, DrawerContent } from '$lib/components/common'
|
||||
|
||||
let path: string = ''
|
||||
let initialPath = ''
|
||||
let pathError = ''
|
||||
|
||||
import type { App } from '$lib/components/apps/types'
|
||||
import { goto } from '$app/navigation'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { LayoutDashboard } from 'lucide-svelte'
|
||||
|
||||
let drawerOpen = false
|
||||
|
||||
function closeDrawer() {
|
||||
drawerOpen = false
|
||||
}
|
||||
|
||||
async function createApp() {
|
||||
const appJson: App = {
|
||||
grid: [],
|
||||
title: 'New app',
|
||||
unusedInlineScripts: [],
|
||||
fullscreen: false
|
||||
}
|
||||
|
||||
const policy = {
|
||||
triggerables: {},
|
||||
execution_mode: Policy.execution_mode.PUBLISHER,
|
||||
on_behalf_of: `u/${$userStore?.username}`
|
||||
}
|
||||
try {
|
||||
const appId = await AppService.createApp({
|
||||
workspace: $workspaceStore!,
|
||||
requestBody: {
|
||||
value: appJson,
|
||||
path,
|
||||
summary: 'App summary',
|
||||
policy
|
||||
}
|
||||
})
|
||||
|
||||
goto(`/apps/edit/${appId}`)
|
||||
} catch (e) {
|
||||
sendUserToast('Error creating app', e)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Drawer bind:open={drawerOpen} size="800px">
|
||||
<DrawerContent title="Create an App" on:close={() => closeDrawer()}>
|
||||
<Path bind:error={pathError} bind:path {initialPath} namePlaceholder="my_app" kind="app">
|
||||
<div slot="ownerToolkit">
|
||||
App 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 slot="actions">
|
||||
<Button on:click={() => createApp()}>Create app</Button>
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<Button
|
||||
size="sm"
|
||||
spacingSize="lg"
|
||||
startIcon={{ icon: faPlus }}
|
||||
on:click={() => (drawerOpen = true)}
|
||||
>
|
||||
New App (alpha) <LayoutDashboard class="ml-1.5" size={18} />
|
||||
</Button>
|
||||
@@ -27,8 +27,7 @@
|
||||
import { userStore } from '$lib/stores'
|
||||
|
||||
import InlineScriptsPanel from './inlineScriptsPanel/InlineScriptsPanel.svelte'
|
||||
import TablePanel from './TablePanel.svelte'
|
||||
import { grid } from 'd3-dag'
|
||||
|
||||
import SettingsPanel from './SettingsPanel.svelte'
|
||||
import { fly } from 'svelte/transition'
|
||||
import type { Policy } from '$lib/gen'
|
||||
@@ -72,18 +71,7 @@
|
||||
|
||||
function saveDraft() {
|
||||
timeout && clearTimeout(timeout)
|
||||
timeout = setTimeout(
|
||||
() =>
|
||||
localStorage.setItem(
|
||||
'app',
|
||||
encodeState({
|
||||
path,
|
||||
value: $appStore,
|
||||
policy
|
||||
})
|
||||
),
|
||||
500
|
||||
)
|
||||
timeout = setTimeout(() => localStorage.setItem('app', encodeState($appStore)), 500)
|
||||
}
|
||||
|
||||
let mounted = false
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation'
|
||||
import { page } from '$app/stores'
|
||||
import { Drawer, DrawerContent } from '$lib/components/common'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton/ToggleButton.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton/ToggleButtonGroup.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import { AppService, Policy } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { faExternalLink } from '@fortawesome/free-solid-svg-icons'
|
||||
import { faExternalLink, faSave } from '@fortawesome/free-solid-svg-icons'
|
||||
import { Eye, Laptop2, Pencil, PenTool, Smartphone } from 'lucide-svelte'
|
||||
import { getContext } from 'svelte'
|
||||
import { sendUserToast } from '../../../utils'
|
||||
import type { AppEditorContext, EditorBreakpoint, EditorMode } from '../types'
|
||||
import AppExportButton from './AppExportButton.svelte'
|
||||
|
||||
const { app } = getContext<AppEditorContext>('AppEditorContext')
|
||||
export let title: string = $app.title || ''
|
||||
@@ -21,7 +25,42 @@
|
||||
save: false
|
||||
}
|
||||
|
||||
let newPath: string = ''
|
||||
let pathError: string | undefined = undefined
|
||||
|
||||
let drawerOpen = false
|
||||
|
||||
function closeDrawer() {
|
||||
drawerOpen = false
|
||||
}
|
||||
|
||||
async function createApp(path: string) {
|
||||
const policy = {
|
||||
triggerables: {},
|
||||
execution_mode: Policy.execution_mode.PUBLISHER,
|
||||
on_behalf_of: `u/${$userStore?.username}`
|
||||
}
|
||||
try {
|
||||
const appId = await AppService.createApp({
|
||||
workspace: $workspaceStore!,
|
||||
requestBody: {
|
||||
value: $app,
|
||||
path,
|
||||
summary: 'App summary',
|
||||
policy
|
||||
}
|
||||
})
|
||||
goto(`/apps/edit/${appId}`)
|
||||
} catch (e) {
|
||||
sendUserToast('Error creating app', e)
|
||||
}
|
||||
}
|
||||
|
||||
async function save() {
|
||||
if ($page.params.path == undefined) {
|
||||
drawerOpen = true
|
||||
return
|
||||
}
|
||||
loading.save = true
|
||||
AppService.updateApp({
|
||||
workspace: $workspaceStore!,
|
||||
@@ -48,6 +87,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Drawer bind:open={drawerOpen} size="800px">
|
||||
<DrawerContent title="Create an App" on:close={() => closeDrawer()}>
|
||||
<Path
|
||||
bind:error={pathError}
|
||||
bind:path={newPath}
|
||||
initialPath=""
|
||||
namePlaceholder="my_app"
|
||||
kind="app"
|
||||
/>
|
||||
|
||||
<div slot="actions">
|
||||
<Button
|
||||
startIcon={{ icon: faSave }}
|
||||
disabled={pathError != ''}
|
||||
on:click={() => createApp(newPath)}>Create app</Button
|
||||
>
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<div class="border-b flex flex-row justify-between py-1 px-4 items-center">
|
||||
<input class="text-sm w-64" bind:value={title} />
|
||||
<div class="flex gap-8 items-center">
|
||||
@@ -73,13 +132,14 @@
|
||||
</ToggleButtonGroup>
|
||||
</div>
|
||||
|
||||
<Toggle
|
||||
size="xs"
|
||||
bind:checked={$app.fullscreen}
|
||||
options={{ left: 'max-width (1152px)', right: 'fullscreen' }}
|
||||
/>
|
||||
<ToggleButtonGroup bind:selected={$app.fullscreen}>
|
||||
<ToggleButton position="left" value={false} size="xs">Centered</ToggleButton>
|
||||
<ToggleButton position="right" value={true} size="xs">Full Width</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</div>
|
||||
<div class="flex flex-row gap-2 w-64 justify-end">
|
||||
<div class="flex flex-row gap-4 justify-end">
|
||||
<AppExportButton app={$app} />
|
||||
|
||||
<Button
|
||||
on:click={() => sendUserToast('Publishing apps publically at secret urls is coming soon')}
|
||||
color="dark"
|
||||
@@ -89,6 +149,12 @@
|
||||
>
|
||||
Publish
|
||||
</Button>
|
||||
<Button loading={loading.save} on:click={save} color="dark" size="xs">Save</Button>
|
||||
<Button
|
||||
loading={loading.save}
|
||||
startIcon={{ icon: faSave }}
|
||||
on:click={save}
|
||||
color="dark"
|
||||
size="xs">Save</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<script lang="ts">
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
|
||||
import { copyToClipboard } from '$lib/utils'
|
||||
|
||||
import { faClipboard, faFileExport } from '@fortawesome/free-solid-svg-icons'
|
||||
import Icon from 'svelte-awesome'
|
||||
import { Highlight } from 'svelte-highlight'
|
||||
import json from 'svelte-highlight/languages/json'
|
||||
import { Button } from '../../common'
|
||||
import type { App } from '../types'
|
||||
|
||||
let jsonViewerDrawer: Drawer
|
||||
|
||||
export let app: App
|
||||
</script>
|
||||
|
||||
<Button
|
||||
btnClasses="pr-4"
|
||||
size="sm"
|
||||
variant="border"
|
||||
color="light"
|
||||
on:click={() => jsonViewerDrawer.toggleDrawer()}
|
||||
>
|
||||
<Icon data={faFileExport} scale={0.6} class="inline mr-2" />
|
||||
Export JSON
|
||||
</Button>
|
||||
|
||||
<Drawer bind:this={jsonViewerDrawer} size="800px">
|
||||
<DrawerContent title="App JSON" on:close={() => jsonViewerDrawer.toggleDrawer()}>
|
||||
<div class="relative">
|
||||
<Button
|
||||
on:click={() => copyToClipboard(JSON.stringify(app, null, 4))}
|
||||
color="dark"
|
||||
variant="border"
|
||||
size="sm"
|
||||
startIcon={{ icon: faClipboard }}
|
||||
btnClasses="absolute top-2 right-2"
|
||||
>
|
||||
Copy content
|
||||
</Button>
|
||||
<Highlight language={json} code={JSON.stringify(app, null, 4)} />
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
@@ -12,6 +12,7 @@
|
||||
import { faAngleDown } from '@fortawesome/free-solid-svg-icons'
|
||||
import { isOpenStore } from './store'
|
||||
import { gridColumns } from '../../gridUtils'
|
||||
import { dirtyStore } from '$lib/components/common/confirmationModal/dirtyStore'
|
||||
|
||||
const { app, selectedComponent } = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
@@ -57,6 +58,7 @@
|
||||
}
|
||||
|
||||
function addComponent(appComponent: AppComponent) {
|
||||
$dirtyStore = true
|
||||
const grid = $app.grid ?? []
|
||||
const id = getNextId(grid.map((gridItem) => gridItem.data.id))
|
||||
|
||||
|
||||
7
frontend/src/lib/components/apps/store.ts
Normal file
7
frontend/src/lib/components/apps/store.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { writable } from "svelte/store";
|
||||
import type {
|
||||
App,
|
||||
|
||||
} from './types'
|
||||
|
||||
export const importStore = writable<App | undefined>(undefined)
|
||||
48
frontend/src/lib/components/flows/CreateActionsApp.svelte
Normal file
48
frontend/src/lib/components/flows/CreateActionsApp.svelte
Normal file
@@ -0,0 +1,48 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation'
|
||||
import { faBarsStaggered, faPlus } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
import { Button, ButtonPopup, ButtonPopupItem } from '$lib/components/common'
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
|
||||
import { Icon } from 'svelte-awesome'
|
||||
import { importStore } from '../apps/store'
|
||||
import { LayoutDashboard } from 'lucide-svelte'
|
||||
|
||||
let drawer: Drawer | undefined = undefined
|
||||
let pendingJson: string
|
||||
|
||||
async function importJson() {
|
||||
$importStore = JSON.parse(pendingJson)
|
||||
await goto('/apps/add')
|
||||
drawer?.closeDrawer?.()
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="flex flex-row gap-2">
|
||||
<ButtonPopup
|
||||
size="sm"
|
||||
spacingSize="xl"
|
||||
startIcon={{ icon: faPlus }}
|
||||
href="/apps/add?nodraft=true"
|
||||
>
|
||||
<svelte:fragment slot="main"
|
||||
>New App (alpha) <LayoutDashboard class="ml-1.5" size={18} />
|
||||
</svelte:fragment>
|
||||
<ButtonPopupItem on:click={() => drawer?.toggleDrawer?.()}>
|
||||
Import from raw JSON
|
||||
</ButtonPopupItem>
|
||||
</ButtonPopup>
|
||||
</div>
|
||||
|
||||
<!-- Raw JSON -->
|
||||
<Drawer bind:this={drawer} size="800px">
|
||||
<DrawerContent title="Import app from JSON" on:close={() => drawer?.toggleDrawer?.()}>
|
||||
<SimpleEditor bind:code={pendingJson} lang="json" class="h-full" fixedOverflowWidgets={false} />
|
||||
<svelte:fragment slot="actions">
|
||||
<Button size="sm" on:click={importJson}>Import</Button>
|
||||
</svelte:fragment>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
@@ -23,7 +23,12 @@
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="flex flex-row gap-2">
|
||||
<ButtonPopup size="sm" spacingSize="xl" startIcon={{ icon: faPlus }} href="/flows/add">
|
||||
<ButtonPopup
|
||||
size="sm"
|
||||
spacingSize="xl"
|
||||
startIcon={{ icon: faPlus }}
|
||||
href="/flows/add?nodraft=true"
|
||||
>
|
||||
<svelte:fragment slot="main"
|
||||
>New Flow <Icon data={faBarsStaggered} scale={0.8} class="ml-1.5" />
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
|
||||
<Drawer bind:this={jsonViewerDrawer} size="800px">
|
||||
<DrawerContent title="See JSON" on:close={() => jsonViewerDrawer.toggleDrawer()}>
|
||||
<DrawerContent title="OpenFlow JSON" on:close={() => jsonViewerDrawer.toggleDrawer()}>
|
||||
{#if $flowStore}
|
||||
<FlowViewer flow={cleanInputs($flowStore)} tab="json" />
|
||||
{/if}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore, userWorkspaces } from '$lib/stores'
|
||||
import { workspaceStore, userWorkspaces, switchWorkspace } from '$lib/stores'
|
||||
import { classNames } from '$lib/utils'
|
||||
import Icon from 'svelte-awesome'
|
||||
import { Building } from 'lucide-svelte'
|
||||
@@ -33,7 +33,7 @@
|
||||
<tr
|
||||
class="text-xs cursor-pointer hover:bg-gray-100"
|
||||
on:click={() => {
|
||||
workspaceStore.set(workspace.id)
|
||||
switchWorkspace(workspace.id)
|
||||
close()
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -69,8 +69,6 @@ export const hubScripts = writable<
|
||||
if (browser) {
|
||||
workspaceStore.subscribe(async (workspace) => {
|
||||
if (workspace) {
|
||||
localStorage.removeItem("flow")
|
||||
localStorage.removeItem("app")
|
||||
localStorage.setItem("workspace", String(workspace));
|
||||
userStore.set(await getUserExt(workspace));
|
||||
} else {
|
||||
@@ -79,6 +77,12 @@ if (browser) {
|
||||
});
|
||||
}
|
||||
|
||||
export function switchWorkspace(workspace: string | undefined) {
|
||||
localStorage.removeItem("flow")
|
||||
localStorage.removeItem("app")
|
||||
workspaceStore.set(workspace);
|
||||
}
|
||||
|
||||
export function clearStores(): void {
|
||||
localStorage.removeItem("flow")
|
||||
localStorage.removeItem("app")
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
import HighlightCode from '$lib/components/HighlightCode.svelte'
|
||||
import { Building, Globe2 } from 'lucide-svelte'
|
||||
|
||||
import CreateApp from '$lib/components/apps/CreateApp.svelte'
|
||||
import ItemsList from '$lib/components/home/ItemsList.svelte'
|
||||
import CreateActionsApp from '$lib/components/flows/CreateActionsApp.svelte'
|
||||
|
||||
type Tab = 'hubscripts' | 'hubflows' | 'workspace'
|
||||
|
||||
@@ -132,9 +132,9 @@
|
||||
<PageHeader title="Home">
|
||||
<div class="flex flex-row gap-3 flex-wrap">
|
||||
{#if !$userStore?.operator}
|
||||
<CreateApp />
|
||||
<CreateActionsScript />
|
||||
<CreateActionsFlow />
|
||||
<CreateActionsApp />
|
||||
{/if}
|
||||
</div>
|
||||
</PageHeader>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export function load() {
|
||||
return {
|
||||
stuff: { title: `New App` }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<script lang="ts">
|
||||
import { importStore } from '$lib/components/apps/store'
|
||||
|
||||
import AppEditor from '$lib/components/apps/editor/AppEditor.svelte'
|
||||
import { Policy } from '$lib/gen'
|
||||
import { page } from '$app/stores'
|
||||
import { decodeState } from '$lib/utils'
|
||||
import { dirtyStore } from '$lib/components/common/confirmationModal/dirtyStore'
|
||||
import { userStore } from '$lib/stores'
|
||||
import type { App } from '$lib/components/apps/types'
|
||||
import { goto } from '$app/navigation'
|
||||
|
||||
let nodraft = $page.url.searchParams.get('nodraft')
|
||||
|
||||
if (nodraft) {
|
||||
goto('?', { replaceState: true })
|
||||
}
|
||||
|
||||
const importJson = $importStore
|
||||
if ($importStore) {
|
||||
$importStore = undefined
|
||||
}
|
||||
|
||||
const initialState = nodraft ? undefined : localStorage.getItem('app')
|
||||
|
||||
let value: App =
|
||||
importJson ??
|
||||
(initialState != undefined
|
||||
? decodeState(initialState)
|
||||
: {
|
||||
grid: [],
|
||||
title: 'New App',
|
||||
fullscreen: false,
|
||||
unusedInlineScripts: []
|
||||
})
|
||||
|
||||
$dirtyStore = false
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<div class="h-screen">
|
||||
<AppEditor
|
||||
app={value}
|
||||
path={''}
|
||||
policy={{
|
||||
on_behalf_of: `u/${$userStore?.username}`,
|
||||
execution_mode: Policy.execution_mode.PUBLISHER
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export function load({ params }) {
|
||||
return {
|
||||
stuff: { title: `Edit App ${params.path}` }
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,6 @@
|
||||
let path = $page.params.path
|
||||
|
||||
let nodraft = $page.url.searchParams.get('nodraft')
|
||||
const initialState = nodraft ? undefined : localStorage.getItem('app')
|
||||
let stateLoadedFromUrl = initialState != undefined ? decodeState(initialState) : undefined
|
||||
|
||||
if (nodraft) {
|
||||
goto('?', { replaceState: true })
|
||||
@@ -21,15 +19,16 @@
|
||||
let loading = true
|
||||
async function loadApp(): Promise<void> {
|
||||
loading = true
|
||||
console.log(stateLoadedFromUrl)
|
||||
app =
|
||||
stateLoadedFromUrl != undefined && stateLoadedFromUrl?.path == path
|
||||
? stateLoadedFromUrl
|
||||
: await AppService.getAppByPath({
|
||||
path,
|
||||
workspace: $workspaceStore!
|
||||
})
|
||||
app = await AppService.getAppByPath({
|
||||
path,
|
||||
workspace: $workspaceStore!
|
||||
})
|
||||
|
||||
const initialState = nodraft ? undefined : localStorage.getItem('app')
|
||||
let stateLoadedFromUrl = initialState != undefined ? decodeState(initialState) : undefined
|
||||
if (stateLoadedFromUrl) {
|
||||
app.value = stateLoadedFromUrl
|
||||
}
|
||||
loading = false
|
||||
$dirtyStore = false
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation'
|
||||
import { page } from '$app/stores'
|
||||
import { dirtyStore } from '$lib/components/common/confirmationModal/dirtyStore'
|
||||
|
||||
@@ -8,9 +9,15 @@
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { decodeState, emptySchema } from '$lib/utils'
|
||||
|
||||
let nodraft = $page.url.searchParams.get('nodraft')
|
||||
|
||||
if (nodraft) {
|
||||
goto('?', { replaceState: true })
|
||||
}
|
||||
|
||||
const hubId = $page.url.searchParams.get('hub')
|
||||
const templatePath = $page.url.searchParams.get('template')
|
||||
const initialState = hubId || templatePath ? undefined : localStorage.getItem('flow')
|
||||
const initialState = hubId || templatePath || nodraft ? undefined : localStorage.getItem('flow')
|
||||
|
||||
let selectedId: string = 'settings-metadata'
|
||||
let loading = false
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
// Default
|
||||
let schema: Schema = emptySchema()
|
||||
|
||||
let nodraft = $page.url.searchParams.get('nodraft')
|
||||
|
||||
const templatePath = $page.url.searchParams.get('template')
|
||||
const hubPath = $page.url.searchParams.get('hub')
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { sendUserToast, validateUsername } from '$lib/utils'
|
||||
import { logoutWithRedirect } from '$lib/logout'
|
||||
import { page } from '$app/stores'
|
||||
import { usersWorkspaceStore, workspaceStore } from '$lib/stores'
|
||||
import { switchWorkspace, usersWorkspaceStore, workspaceStore } from '$lib/stores'
|
||||
import CenteredModal from '$lib/components/CenteredModal.svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
@@ -56,7 +56,8 @@
|
||||
sendUserToast(`Created workspace id: ${id}`)
|
||||
|
||||
usersWorkspaceStore.set(await WorkspaceService.listUserWorkspaces())
|
||||
workspaceStore.set(id)
|
||||
switchWorkspace(id)
|
||||
|
||||
goto(rd ?? '/')
|
||||
}
|
||||
|
||||
@@ -135,8 +136,8 @@
|
||||
options={{ right: `Auto invite users as operators` }}
|
||||
/>
|
||||
<Tooltip
|
||||
>An operator can only execute and view scripts/flows/apps from your workspace, and only
|
||||
those that he has visibility on</Tooltip
|
||||
>An operator can only execute and view scripts/flows/apps from your workspace, and only those
|
||||
that he has visibility on</Tooltip
|
||||
>
|
||||
</div>
|
||||
{#if !isDomainAllowed}
|
||||
|
||||
@@ -4,7 +4,13 @@
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { logout, logoutWithRedirect } from '$lib/logout'
|
||||
import { UserService, type WorkspaceInvite, WorkspaceService } from '$lib/gen'
|
||||
import { superadmin, usersWorkspaceStore, userWorkspaces, workspaceStore } from '$lib/stores'
|
||||
import {
|
||||
superadmin,
|
||||
switchWorkspace,
|
||||
usersWorkspaceStore,
|
||||
userWorkspaces,
|
||||
workspaceStore
|
||||
} from '$lib/stores'
|
||||
import { faCrown, faUserCog } from '@fortawesome/free-solid-svg-icons'
|
||||
import Icon from 'svelte-awesome'
|
||||
import { Button, Skeleton } from '$lib/components/common'
|
||||
@@ -38,7 +44,7 @@
|
||||
}
|
||||
if ($usersWorkspaceStore) {
|
||||
if (!$workspaceStore) {
|
||||
workspaceStore.set(localStorage.getItem('workspace')?.toString())
|
||||
switchWorkspace(localStorage.getItem('workspace')?.toString())
|
||||
}
|
||||
} else {
|
||||
await logoutWithRedirect($page.url.pathname + $page.url.search)
|
||||
|
||||
Reference in New Issue
Block a user