mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-28 16:02:47 +00:00
* feat: operators get AI sessions `prefersSessionHandoff` stops taking the role, so every AI entry point an operator can reach — Ask AI, the home composer, Open in session, the flow editor's hand-off, the raw-app template picker — opens a session for them like anyone else. The sessions page drops its refusal, and the layout stops keeping them on the docked chat. In the sidebar they now get the Workspace/AI Sessions switch and session mode, and lose the Ask AI entry that stood in for them, since the pane behind it is no longer the one they are sent to. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: operators get run-oriented examples in the home composer Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: note builder_flows in the operator composer examples comment Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: gate session tools and editors on operator rights Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: keep operator AI sessions behind a browser opt-in Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep flows refused in the prompt for operators without builder rights Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * refactor: decide every frontend edit check through one editRights module Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: let admins who are also operators open session editors, as drafts.rs does Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: mirror drafts.rs exactly in roleCanDraft and correct the edit-rights docs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
69 lines
1.9 KiB
Svelte
69 lines
1.9 KiB
Svelte
<script lang="ts">
|
|
import { getContext, onMount } from 'svelte'
|
|
import DarkModeObserver from '../DarkModeObserver.svelte'
|
|
import { AppService, type ListableApp } from '$lib/gen'
|
|
import { useEditRights } from '$lib/operatorWriteRights'
|
|
import type { AppViewerContext } from '../apps/types'
|
|
import Alert from '../common/alert/Alert.svelte'
|
|
import Select from '../select/Select.svelte'
|
|
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
|
|
|
const operatingWorkspace = useOperatingWorkspace()
|
|
const editRights = useEditRights()
|
|
|
|
interface Props {
|
|
value?: string
|
|
}
|
|
|
|
let { value = $bindable('') }: Props = $props()
|
|
let darkMode = $state(false)
|
|
|
|
const { appPath } = getContext<AppViewerContext>('AppViewerContext')
|
|
|
|
let apps: ListableApp[] = $state([])
|
|
|
|
async function loadApps(): Promise<void> {
|
|
apps = (
|
|
await AppService.listApps({ workspace: $operatingWorkspace!, includeDraftOnly: true })
|
|
).map((app: ListableApp) => {
|
|
return {
|
|
canWrite:
|
|
editRights.canEditItem('app', app.path!, app.extra_perms) &&
|
|
app.workspace_id == $operatingWorkspace,
|
|
...app
|
|
}
|
|
})
|
|
}
|
|
|
|
onMount(() => {
|
|
loadApps()
|
|
if (value === '') value = $appPath
|
|
})
|
|
</script>
|
|
|
|
<DarkModeObserver bind:darkMode />
|
|
|
|
<div class="flex flex-col gap-2 w-full">
|
|
<Select
|
|
clearable
|
|
onClear={() => (value = '')}
|
|
bind:value
|
|
items={apps.map((app) => ({
|
|
value: app.path,
|
|
label: app.path === $appPath ? `${app.path} (current app)` : app.path
|
|
}))}
|
|
placeholder="Pick an app"
|
|
disablePortal
|
|
/>
|
|
{#if !appPath}
|
|
<Alert title="Current app not selectable" size="xs" type="warning" collapsible>
|
|
Current app is not selectable until you have deployed this app at least once.
|
|
</Alert>
|
|
{/if}
|
|
{#if appPath && $appPath === value}
|
|
<div class="text-2xs">
|
|
The current app is selected. If the path changes, the path needs to be updated manually.
|
|
</div>
|
|
{/if}
|
|
</div>
|