revert fix hub list

This commit is contained in:
Ruben Fiszel
2023-04-18 08:14:38 +02:00
parent 26a86ba0d8
commit cd8f0b5507
11 changed files with 293 additions and 316 deletions
+5 -11
View File
@@ -28,23 +28,20 @@ docker compose up db windmill_server windmill_worker
- Install llvm
**On OSX:**
```bash
brew install llvm caddy gsed
# make LLVM tools available on PATH
echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc
# now, restart your shell. You should now have the `lld` binary on your PATH.
```
- To test that you have Rust and Cargo installed run `cargo --version`
- In your terminal, go to the backend directory and run `cargo build`
- Run `cargo run`
**Known issue on M1 Mac while running `cargo build`**
- You may encounter `linking with cc failed` build time error.
- To solve this run:
```bash
@@ -52,6 +49,7 @@ docker compose up db windmill_server windmill_worker
source ~/.zshrc
```
**Do a Frontend Build**
In order to run the backend, you need to have a frontend build inside `frontend/build/`.
@@ -72,14 +70,11 @@ npm run build
```
**Known issue while running `npm run build`**
- You may encounter `FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory` error.
- To solve this run:
```bash
export NODE_OPTIONS=--max_old_space_size=8096
```
- run `npm run build` again
In the root folder:
@@ -151,13 +146,13 @@ Recommended config for VS Code:
- turn _format on save_ on
## Building
The project is built with [SvelteKit](https://kit.svelte.dev/) and uses as output static files.
There are others adapters for sveltekit, but we use the static adapter.
To build the frontend as static assets, use:
```
npm run build
```
@@ -165,11 +160,10 @@ npm run build
The output is in the `build` folder.
The default build assume you serve every non static files as the 200.html file which is catchall. If you prefer a normal layout, you can use:
```
NOTCATCHALL=true npm run build
```
which will generate an index.html and allow you to serve the frontend with any static server.
Env variables used for build are set in .env file. See [https://vitejs.dev/guide/env-and-mode.html#env-files](https://vitejs.dev/guide/env-and-mode.html#env-files) for more details.
+3 -3
View File
@@ -26,11 +26,11 @@
import DrawerContent from './common/drawer/DrawerContent.svelte'
import { Badge, Drawer } from './common'
import WorkspaceScriptPicker from './flows/pickers/WorkspaceScriptPicker.svelte'
import PickHubScript from './flows/pickers/PickHubScript.svelte'
import ToggleHubWorkspace from './ToggleHubWorkspace.svelte'
import Skeleton from './common/skeleton/Skeleton.svelte'
import Popover from './Popover.svelte'
import Kbd from './common/kbd/Kbd.svelte'
import PickHubItems from './flows/pickers/PickHubItems.svelte'
export let lang: 'python3' | 'deno' | 'go' | 'bash'
export let editor: Editor | undefined
@@ -86,9 +86,9 @@
<Drawer bind:this={scriptPicker} size="900px">
<DrawerContent title="Code" on:close={scriptPicker.closeDrawer}>
{#if pick_existing == 'hub'}
<PickHubItems bind:filter {kind} on:pickScript={onScriptPick} selectedKind="script">
<PickHubScript bind:filter {kind} on:pick={onScriptPick}>
<ToggleHubWorkspace bind:selected={pick_existing} />
</PickHubItems>
</PickHubScript>
{:else}
<WorkspaceScriptPicker bind:filter {kind} on:pick={onScriptPick}>
<ToggleHubWorkspace bind:selected={pick_existing} />
@@ -2,6 +2,7 @@
import type { Schema } from '$lib/common'
import { Button, Drawer, DrawerContent, Tab, Tabs } from '$lib/components/common'
import FlowScriptPicker from '$lib/components/flows/pickers/FlowScriptPicker.svelte'
import PickHubScript from '$lib/components/flows/pickers/PickHubScript.svelte'
import Tooltip from '$lib/components/Tooltip.svelte'
import { Script, type Preview } from '$lib/gen'
import { inferArgs } from '$lib/infer'
@@ -15,7 +16,6 @@
import { defaultCode } from '../component'
import InlineScriptList from '../settingsPanel/mainInput/InlineScriptList.svelte'
import WorkspaceScriptList from '../settingsPanel/mainInput/WorkspaceScriptList.svelte'
import PickHubItems from '$lib/components/flows/pickers/PickHubItems.svelte'
export let name: string
export let componentType: string | undefined = undefined
@@ -130,11 +130,7 @@
{:else if tab == 'workspacescripts'}
<WorkspaceScriptList on:pick={(e) => pickScript(e.detail)} />
{:else if tab == 'hubscripts'}
<PickHubItems
selectedKind="script"
bind:filter
on:pickScript={(e) => pickHubScript(e.detail.path)}
/>
<PickHubScript bind:filter on:pick={(e) => pickHubScript(e.detail.path)} />
{/if}
</div>
</div>
@@ -1,6 +1,7 @@
<script lang="ts">
import { faMousePointer, faPlus } from '@fortawesome/free-solid-svg-icons'
import { Button, Drawer, DrawerContent, Tab, Tabs } from '$lib/components/common'
import PickHubScript from '$lib/components/flows/pickers/PickHubScript.svelte'
import { Building, Globe2 } from 'lucide-svelte'
import InlineScriptList from './InlineScriptList.svelte'
import type { ResultAppInput } from '$lib/components/apps/inputType'
@@ -11,7 +12,6 @@
import type { Schema } from '$lib/common'
import { getAllScriptNames, loadSchema, schemaToInputsSpec } from '$lib/components/apps/utils'
import { emptySchema } from '$lib/utils'
import PickHubItems from '$lib/components/flows/pickers/PickHubItems.svelte'
type Tab = 'hubscripts' | 'workspacescripts' | 'workspaceflows' | 'inlinescripts'
@@ -165,11 +165,7 @@
{:else if tab == 'workspaceflows'}
<WorkspaceFlowList on:pick={(e) => pickFlow(e.detail)} />
{:else if tab == 'hubscripts'}
<PickHubItems
bind:filter
on:pickScript={(e) => pickHubScript(e.detail.path)}
selectedKind="script"
/>
<PickHubScript bind:filter on:pick={(e) => pickHubScript(e.detail.path)} />
{/if}
</div>
</div>
@@ -7,8 +7,8 @@
import { faBolt, faCheck, faCode } from '@fortawesome/free-solid-svg-icons'
import { createEventDispatcher } from 'svelte'
import FlowScriptPicker from '../pickers/FlowScriptPicker.svelte'
import PickHubScript from '../pickers/PickHubScript.svelte'
import WorkspaceScriptPicker from '../pickers/WorkspaceScriptPicker.svelte'
import PickHubItems from '../pickers/PickHubItems.svelte'
export let failureModule: boolean
export let shouldDisableTriggerScripts: boolean = false
@@ -157,9 +157,9 @@
>Use pre-made <span class="text-blue-500">{kind == 'script' ? 'action' : kind}</span> script</h3
>
{#if pick_existing == 'hub'}
<PickHubItems bind:filter {kind} on:pickScript={() => dispatch('pick')}>
<PickHubScript bind:filter {kind} on:pick>
<ToggleHubWorkspace bind:selected={pick_existing} />
</PickHubItems>
</PickHubScript>
{:else}
<WorkspaceScriptPicker displayLock bind:filter {kind} on:pick>
<ToggleHubWorkspace bind:selected={pick_existing} />
@@ -1,34 +1,81 @@
<script lang="ts">
import { Badge } from '$lib/components/common'
import { createEventDispatcher, onMount } from 'svelte'
import { Badge, Skeleton } from '$lib/components/common'
import SearchItems from '$lib/components/SearchItems.svelte'
import { loadHubApps } from '$lib/utils'
import ListFilters from '$lib/components/home/ListFilters.svelte'
import NoItemFound from '$lib/components/home/NoItemFound.svelte'
import RowIcon from '$lib/components/common/table/RowIcon.svelte'
import type { HubApp } from '$lib/stores'
import { createEventDispatcher } from 'svelte'
export let item: HubApp & { marked?: string }
export let filter = ''
type Item = { apps: string[]; summary: string; path: string }
let hubApps: any[] | undefined = undefined
let filteredItems: (Item & { marked?: string })[] = []
let appFilter: string | undefined = undefined
$: prefilteredItems = appFilter
? (hubApps ?? []).filter((i) => i.apps.includes(appFilter))
: hubApps ?? []
$: apps = Array.from(new Set(filteredItems?.flatMap((x) => x.apps) ?? [])).sort()
const dispatch = createEventDispatcher()
onMount(async () => {
hubApps = await loadHubApps()
})
</script>
<button
class="p-4 gap-4 flex flex-row grow justify-between hover:bg-gray-50 bg-white transition-all items-center rounded-md"
on:click={() => dispatch('pick', item)}
>
<div class="flex items-center gap-4">
<RowIcon kind="app" />
<SearchItems
{filter}
items={prefilteredItems}
bind:filteredItems
f={(x) => x.summary + ' (' + x.apps.join(', ') + ')'}
/>
<div class="w-full flex mt-1 items-center gap-2">
<slot />
<input type="text" placeholder="Search Hub Apps" bind:value={filter} class="text-2xl grow" />
</div>
<ListFilters filters={apps} bind:selectedFilter={appFilter} resourceType />
<div class="w-full text-left font-normal">
<div class="text-gray-900 flex-wrap text-md font-semibold mb-1">
{#if item.marked}
{@html item.marked ?? ''}
{:else}
{item.summary ?? ''}
{/if}
</div>
</div>
</div>
<div class="min-w-1/3 gap-2 flex flex-wrap justify-end">
{#each item.apps as app}
<Badge color="gray" baseClass="border">{app}</Badge>
{/each}
</div>
</button>
{#if hubApps}
{#if filteredItems.length == 0}
<NoItemFound />
{:else}
<ul class="divide-y divide-gray-200 border rounded-md">
{#each filteredItems as item (item)}
<li class="flex flex-row w-full">
<button
class="p-4 gap-4 flex flex-row grow justify-between hover:bg-gray-50 bg-white transition-all items-center rounded-md"
on:click={() => dispatch('pick', item)}
>
<div class="flex items-center gap-4">
<RowIcon kind="app" />
<div class="w-full text-left font-normal ">
<div class="text-gray-900 flex-wrap text-md font-semibold mb-1">
{#if item.marked}
{@html item.marked ?? ''}
{:else}
{item.summary ?? ''}
{/if}
</div>
</div>
</div>
<div class="min-w-1/3 gap-2 flex flex-wrap justify-end">
{#each item.apps as app}
<Badge color="gray" baseClass="border">{app}</Badge>
{/each}
</div>
</button>
</li>
{/each}
</ul>
{/if}
{:else}
<div class="my-2" />
{#each Array(10).fill(0) as _}
<Skeleton layout={[[4], 0.5]} />
{/each}
{/if}
@@ -1,34 +1,82 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Badge } from '$lib/components/common'
import { createEventDispatcher, onMount } from 'svelte'
import { Badge, Skeleton } from '$lib/components/common'
import SearchItems from '$lib/components/SearchItems.svelte'
import { loadHubFlows } from '$lib/utils'
import ListFilters from '$lib/components/home/ListFilters.svelte'
import NoItemFound from '$lib/components/home/NoItemFound.svelte'
import RowIcon from '$lib/components/common/table/RowIcon.svelte'
import type { HubFlow } from '$lib/stores'
export let item: HubFlow & { marked?: string }
export let filter = ''
type Item = { apps: string[]; summary: string; path: string }
let hubFlows: any[] | undefined = undefined
let filteredItems: (Item & { marked?: string })[] = []
let appFilter: string | undefined = undefined
$: prefilteredItems = appFilter
? (hubFlows ?? []).filter((i) => i.apps.includes(appFilter))
: hubFlows ?? []
$: apps = Array.from(new Set(filteredItems?.flatMap((x) => x.apps) ?? [])).sort()
const dispatch = createEventDispatcher()
onMount(async () => {
hubFlows = await loadHubFlows()
})
</script>
<button
class="p-4 gap-4 flex flex-row grow justify-between hover:bg-gray-50 bg-white transition-all items-center rounded-md"
on:click={() => dispatch('pick', item)}
>
<div class="flex items-center gap-4">
<RowIcon kind="flow" />
<SearchItems
{filter}
items={prefilteredItems}
bind:filteredItems
f={(x) => x.summary + ' (' + x.apps.join(', ') + ')'}
/>
<div class="w-full flex mt-1 items-center gap-2">
<slot />
<input type="text" placeholder="Search Hub Flows" bind:value={filter} class="text-2xl grow" />
</div>
<ListFilters filters={apps} bind:selectedFilter={appFilter} resourceType />
<div class="w-full text-left font-normal">
<div class="text-gray-900 flex-wrap text-md font-semibold mb-1">
{#if item.marked}
{@html item.marked ?? ''}
{:else}
{item.summary ?? ''}
{/if}
</div>
</div>
</div>
<div class="min-w-1/3 gap-2 flex flex-wrap justify-end">
{#each item.apps as app}
<Badge color="gray" baseClass="border">{app}</Badge>
{/each}
</div>
</button>
{#if hubFlows}
{#if filteredItems.length == 0}
<NoItemFound />
{:else}
<ul class="divide-y divide-gray-200 border rounded-md">
{#each filteredItems as item (item)}
<li class="flex flex-row w-full">
<button
class="p-4 gap-4 flex flex-row grow justify-between hover:bg-gray-50 bg-white transition-all items-center rounded-md"
on:click={() => dispatch('pick', item)}
>
<div class="flex items-center gap-4">
<RowIcon kind="flow" />
<div class="w-full text-left font-normal ">
<div class="text-gray-900 flex-wrap text-md font-semibold mb-1">
{#if item.marked}
{@html item.marked ?? ''}
{:else}
{item.summary ?? ''}
{/if}
</div>
</div>
</div>
<div class="min-w-1/3 gap-2 flex flex-wrap justify-end">
{#each item.apps as app}
<Badge color="gray" baseClass="border">{app}</Badge>
{/each}
</div>
</button>
</li>
{/each}
</ul>
{/if}
{:else}
<div class="my-2" />
{#each Array(10).fill(0) as _}
<Skeleton layout={[[4], 0.5]} />
{/each}
{/if}
@@ -1,150 +0,0 @@
<!-- PickHubItems.svelte -->
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte'
import { Skeleton, ToggleButton, ToggleButtonGroup } from '$lib/components/common'
import SearchItems from '$lib/components/SearchItems.svelte'
import { loadHubScripts, loadHubFlows, loadHubApps } from '$lib/utils'
import ListFilters from '$lib/components/home/ListFilters.svelte'
import NoItemFound from '$lib/components/home/NoItemFound.svelte'
import { hubScripts, hubFlows, hubApps, type HubItem } from '$lib/stores'
import PickHubScript from './PickHubScript.svelte'
import PickHubFlow from './PickHubFlow.svelte'
import PickHubApp from './PickHubApp.svelte'
import { faBarsStaggered } from '@fortawesome/free-solid-svg-icons'
import { Code2, LayoutDashboard } from 'lucide-svelte'
import { Icon } from 'svelte-awesome'
export let filter = ''
export let selectedKind: 'script' | 'flow' | 'app' | undefined = undefined
export let kind: 'script' | 'trigger' | 'approval' | 'failure' | undefined = undefined
let itemKind: 'script' | 'flow' | 'app' = 'app'
const dispatch = createEventDispatcher()
let filteredItems: (HubItem & { marked?: string })[] = []
let appFilter: string | undefined = undefined
$: items = [
...($hubScripts?.map((s) => ({ itemType: 'script', data: s })) ?? []),
...($hubFlows?.map((s) => ({ itemType: 'flow', data: s })) ?? []),
...($hubApps?.map((s) => ({ itemType: 'app', data: s })) ?? [])
] as HubItem[]
$: apps = Array.from(
new Set(
filteredItems
?.map((x) => {
if (x.itemType === 'script') {
return x.data.app
} else if (x.itemType === 'flow') {
return x.data.apps
} else if (x.itemType === 'app') {
return x.data.apps
} else {
return undefined
}
})
.filter(Boolean)
.flat() ?? []
)
).sort() as string[]
$: prefilteredItems =
appFilter || itemKind
? items.filter((i) => {
if (i.itemType !== itemKind) {
return false
}
if (selectedKind && i.itemType !== selectedKind) {
return false
}
if (i.itemType === 'script' && appFilter) {
return i.data.app === appFilter
} else if (i.itemType === 'flow' && appFilter) {
return i.data.apps.includes(appFilter)
} else if (i.itemType === 'app' && appFilter) {
return i.data.apps.includes(appFilter)
}
return true
})
: items
let notLoaded = true
async function loadApps() {
$hubApps = await loadHubApps()
notLoaded = false
}
async function loadFlows() {
loadHubFlows()
}
onMount(async () => {
loadHubScripts()
loadApps()
loadFlows()
})
</script>
<SearchItems {filter} items={prefilteredItems} bind:filteredItems f={(x) => x.data.summary} />
<div class="w-full flex mt-1 items-center gap-2">
{#if selectedKind === undefined}
<ToggleButtonGroup bind:selected={itemKind}>
<ToggleButton light position="left" value="script" size="sm">
<div class="flex gap-1 items-center">
<Code2 size={16} />
Scripts
</div>
</ToggleButton>
<ToggleButton light position="center" value="flow" size="sm">
<div class="flex gap-1 items-center">
<Icon data={faBarsStaggered} scale={0.8} class="mr-1" />
Flows
</div>
</ToggleButton>
<ToggleButton light position="right" value="app" size="sm">
<div class="flex gap-1 items-center">
<LayoutDashboard size={16} />
Apps
</div>
</ToggleButton>
</ToggleButtonGroup>
{/if}
<input type="text" placeholder="Search Hub Items" bind:value={filter} class="text-2xl grow" />
<slot />
</div>
<ListFilters filters={apps} bind:selectedFilter={appFilter} resourceType />
{#if Array.isArray(prefilteredItems)}
{#if notLoaded}
{#each Array(10).fill(0) as _}
<Skeleton layout={[[4], 0.5]} />
{/each}
{:else if filteredItems.length == 0}
<NoItemFound />
{:else}
<ul class="divide-y divide-gray-200 border rounded-md">
{#each filteredItems as item, index (index)}
<li class="flex flex-row w-full">
{#if item.itemType === 'script'}
<PickHubScript
item={item.data}
on:pick={() => dispatch('pickScript', item.data)}
{kind}
/>
{:else if item.itemType === 'flow'}
<PickHubFlow item={item.data} on:pick={() => dispatch('pickFlow', item.data)} />
{:else if item.itemType === 'app'}
<PickHubApp item={item.data} on:pick={() => dispatch('pickApp', item.data)} />
{/if}
</li>
{/each}
</ul>
{/if}
{:else}
<div class="my-2" />
{#each Array(10).fill(0) as _}
<Skeleton layout={[[4], 0.5]} />
{/each}
{/if}
@@ -1,44 +1,95 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Badge } from '$lib/components/common'
import { capitalize, classNames } from '$lib/utils'
import { hubScripts } from '$lib/stores'
import { createEventDispatcher, onMount } from 'svelte'
import type { HubItem } from './model'
import { Badge, Skeleton } from '$lib/components/common'
import SearchItems from '$lib/components/SearchItems.svelte'
import { capitalize, classNames, loadHubScripts } from '$lib/utils'
import NoItemFound from '$lib/components/home/NoItemFound.svelte'
import { APP_TO_ICON_COMPONENT } from '$lib/components/icons'
import type { HubScript } from '$lib/stores'
import ListFilters from '$lib/components/home/ListFilters.svelte'
export let kind: 'script' | 'trigger' | 'approval' | 'failure' = 'script'
export let item: HubScript & { marked?: string }
export let filter = ''
const dispatch = createEventDispatcher()
let filteredItems: (HubItem & { marked?: string })[] = []
let appFilter: string | undefined = undefined
$: items = ($hubScripts ?? []).filter((i) => i.kind === kind)
$: prefilteredItems = appFilter ? (items ?? []).filter((i) => i.app == appFilter) : items ?? []
$: apps = Array.from(new Set(filteredItems?.map((x) => x.app) ?? [])).sort()
onMount(() => {
if (!$hubScripts) {
loadHubScripts()
}
})
const maxItems = 40
</script>
<button
class="p-4 gap-4 flex flex-row grow hover:bg-gray-50 bg-white transition-all items-center rounded-md"
on:click={() => dispatch('pick', item)}
>
<div class="flex items-center gap-4">
<div
class={classNames(
'rounded-md p-1 flex justify-center items-center border',
'bg-gray-50 border-gray-200'
)}
>
<svelte:component this={APP_TO_ICON_COMPONENT[item['app']]} height={18} width={18} />
</div>
<SearchItems {filter} items={prefilteredItems} bind:filteredItems f={(x) => x.summary} />
<div class="w-full flex mt-1 items-center gap-2">
<slot />
<input type="text" placeholder="Search Hub Scripts" bind:value={filter} class="text-2xl grow" />
</div>
<ListFilters filters={apps} bind:selectedFilter={appFilter} resourceType />
<div class="w-full text-left font-normal">
<div class="text-gray-900 flex-wrap text-md font-semibold mb-1">
{#if item.marked}
{@html item.marked ?? ''}
{:else}
{item.summary ?? ''}
{/if}
</div>
<div class="text-gray-600 text-xs">
{item.path}
</div>
</div>
</div>
{#if kind !== 'script'}
<Badge color="gray" baseClass="border">{capitalize(kind)}</Badge>
{#if $hubScripts}
{#if filteredItems.length == 0}
<NoItemFound />
{:else}
<ul class="divide-y divide-gray-200 border rounded-md">
{#each filteredItems.slice(0, maxItems) as item (item.path)}
<li class="flex flex-row w-full">
<button
class="p-4 gap-4 flex flex-row grow hover:bg-gray-50 bg-white transition-all items-center rounded-md"
on:click={() => dispatch('pick', item)}
>
<div class="flex items-center gap-4">
<div
class={classNames(
'rounded-md p-1 flex justify-center items-center border',
'bg-gray-50 border-gray-200'
)}
>
<svelte:component
this={APP_TO_ICON_COMPONENT[item['app']]}
height={18}
width={18}
/>
</div>
<div class="w-full text-left font-normal ">
<div class="text-gray-900 flex-wrap text-md font-semibold mb-1">
{#if item.marked}
{@html item.marked ?? ''}
{:else}
{item.summary ?? ''}
{/if}
</div>
<div class="text-gray-600 text-xs ">
{item.path}
</div>
</div>
</div>
{#if kind !== 'script'}
<Badge color="gray" baseClass="border">{capitalize(kind)}</Badge>
{/if}
</button>
</li>
{/each}
</ul>
{/if}
</button>
{#if filteredItems.length > maxItems}
<div class="text-gray-500 text-sm py-4">
There are more items ({filteredItems.length}) than being displayed. Refine your search.
</div>
{/if}
{:else}
<div class="my-2" />
{#each Array(10).fill(0) as _}
<Skeleton layout={[0.5, [4]]} />
{/each}
{/if}
+11 -36
View File
@@ -52,42 +52,17 @@ export const userWorkspaces: Readable<
return originalWorkspaces
}
})
export type HubScript = {
path: string
summary: string
approved: boolean
kind: string
app: string
ask_id: number
}
export type HubFlow = {
id: number
flow_id: number
summary: string
apps: string[]
approved: boolean
votes: number
}
export type HubApp = {
id: number
app_id: number
summary: string
apps: Array<string>
approved: boolean
votes: number
}
export type HubItem =
| { itemType: 'script'; data: HubScript & { marked?: string } }
| { itemType: 'flow'; data: HubFlow & { marked?: string } }
| { itemType: 'app'; data: HubApp & { marked?: string } }
export const hubScripts = writable<Array<HubScript> | undefined>(undefined)
export const hubFlows = writable<Array<HubFlow> | undefined>(undefined)
export const hubApps = writable<Array<HubApp> | undefined>(undefined)
export const hubScripts = writable<
| Array<{
path: string
summary: string
approved: boolean
kind: string
app: string
ask_id: number
}>
| undefined
>(undefined)
if (browser) {
workspaceStore.subscribe(async (workspace) => {
@@ -8,19 +8,20 @@
import { getScriptByPath } from '$lib/utils'
import type { HubItem } from '$lib/components/flows/pickers/model'
import { faCodeFork } from '@fortawesome/free-solid-svg-icons'
import PickHubScript from '$lib/components/flows/pickers/PickHubScript.svelte'
import PickHubFlow from '$lib/components/flows/pickers/PickHubFlow.svelte'
import FlowViewer from '$lib/components/FlowViewer.svelte'
import HighlightCode from '$lib/components/HighlightCode.svelte'
import { Building, Globe2 } from 'lucide-svelte'
import ItemsList from '$lib/components/home/ItemsList.svelte'
import CreateActionsApp from '$lib/components/flows/CreateActionsApp.svelte'
import PickHubApp from '$lib/components/flows/pickers/PickHubApp.svelte'
import AppPreview from '$lib/components/apps/editor/AppPreview.svelte'
import { writable } from 'svelte/store'
import type { EditorBreakpoint } from '$lib/components/apps/types'
import PickHubItems from '$lib/components/flows/pickers/PickHubItems.svelte'
type Tab = 'hub' | 'workspace'
type Tab = 'hubscripts' | 'hubflows' | 'hubapps' | 'workspace'
let tab: Tab = window.location.hash?.includes('#')
? (window.location.hash?.replace('#', '') as Tab)
@@ -202,10 +203,22 @@
Workspace
</div>
</Tab>
<Tab size="md" value="hub">
<Tab size="md" value="hubscripts">
<div class="flex gap-2 items-center my-1">
<Globe2 size={18} />
Hub
Hub Scripts
</div>
</Tab>
<Tab size="md" value="hubflows">
<div class="flex gap-2 items-center my-1">
<Globe2 size={18} />
Hub Flows
</div>
</Tab>
<Tab size="md" value="hubapps">
<div class="flex gap-2 items-center my-1">
<Globe2 size={18} />
Hub Apps
</div>
</Tab>
</Tabs>
@@ -214,17 +227,24 @@
<div class="my-2" />
<div class="flex flex-col gap-y-16">
<div class="flex flex-col">
{#if tab == 'hub'}
<PickHubItems
bind:filter
on:pickApp={(e) => viewApp(e.detail)}
on:pickFlow={(e) => viewFlow(e.detail)}
on:pickScript={(e) => viewCode(e.detail)}
{#if tab == 'hubscripts'}
<PickHubScript bind:filter on:pick={(e) => viewCode(e.detail)}
><Button target="_blank" href="https://hub.windmill.dev" variant="border" color="light"
>Go to Hub</Button
></PickHubScript
>
{:else if tab == 'hubflows'}
<PickHubFlow bind:filter on:pick={(e) => viewFlow(e.detail)}
><Button target="_blank" href="https://hub.windmill.dev" variant="border" color="light"
>Go to Hub</Button
></PickHubFlow
>
{:else if tab == 'hubapps'}
<PickHubApp bind:filter on:pick={(e) => viewApp(e.detail)}
><Button target="_blank" href="https://hub.windmill.dev" variant="border" color="light"
>Go to Hub</Button
></PickHubApp
>
<Button target="_blank" href="https://hub.windmill.dev" variant="border" color="light">
Go to Hub
</Button>
</PickHubItems>
{/if}
</div>
</div>