mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-04 00:02:17 +00:00
fix(frontend): apply operator write locks from the session's operating workspace (#11395)
Claude-Session: https://claude.ai/code/session_01VAj4mmm2YThZLVkivrgsbb Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f4dcaf3e45
commit
5e59cefd1f
@@ -106,11 +106,12 @@
|
||||
import { UserDraft } from '$lib/userDraft.svelte'
|
||||
import { setOpenInSessionHandoff } from './sessions/openInSessionContext'
|
||||
import { getEditorStoragePath, setEditorStoragePath } from './editorStoragePathContext'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import {
|
||||
useOperatingUser,
|
||||
useOperatingWorkspace
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const operatingUser = useOperatingUser()
|
||||
|
||||
@@ -118,7 +118,8 @@
|
||||
import WacExportDrawer from './scripts/WacExportDrawer.svelte'
|
||||
import { UserDraft } from '$lib/userDraft.svelte'
|
||||
import { UserDraftDbSyncer } from '$lib/userDraftDbSyncer.svelte'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
let {
|
||||
script = $bindable(),
|
||||
|
||||
@@ -22,11 +22,13 @@
|
||||
import Toggle from './Toggle.svelte'
|
||||
import { Trash } from 'lucide-svelte'
|
||||
import { DEMO_RESTRICTION_HINT, isDemoWorkspaceRestricted } from '$lib/cloud'
|
||||
import { scheduleLock, triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useScheduleLock, useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import {
|
||||
useOperatingWorkspace,
|
||||
useOperatingUser
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const scheduleLock = useScheduleLock()
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const operatingUser = useOperatingUser()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
WorkspaceService
|
||||
} from '$lib/gen'
|
||||
import { canWrite, displayDate, getLocalSetting, storeLocalSetting } from '$lib/utils'
|
||||
import { scheduleLock } from '$lib/operatorWriteRights'
|
||||
import { useScheduleLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import { base } from '$app/paths'
|
||||
import CenteredPage from '$lib/components/CenteredPage.svelte'
|
||||
@@ -59,6 +59,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingUser
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const scheduleLock = useScheduleLock()
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const operatingUser = useOperatingUser()
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
import MqttIcon from '$lib/components/icons/MqttIcon.svelte'
|
||||
import NatsIcon from '$lib/components/icons/NatsIcon.svelte'
|
||||
import TriggerModeToggle from './TriggerModeToggle.svelte'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { getHttpRoute } from './http/utils'
|
||||
import { getEmailAddress, getEmailDomain } from './email/utils'
|
||||
import { TRIGGER_LIST_CONFIG, type TriggerRow } from './triggerListConfig'
|
||||
@@ -78,6 +78,7 @@
|
||||
useOperatingUser,
|
||||
useOperatingWorkspace
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
let { triggerKind }: { triggerKind: TriggerKind } = $props()
|
||||
|
||||
|
||||
@@ -32,13 +32,14 @@
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import Badge from '../common/badge/Badge.svelte'
|
||||
import Tooltip from '../meltComponents/Tooltip.svelte'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import {
|
||||
errorHandlerArgs,
|
||||
slackErrorHandlerHubPathEnding
|
||||
} from '../ErrorOrRecoveryHandler.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
type Props = {
|
||||
triggerPath: string
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
import TriggerRunnablePicker from '$lib/components/triggers/TriggerRunnablePicker.svelte'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -46,6 +46,7 @@
|
||||
useOperatingUser,
|
||||
useOperatingWorkspace
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
import { emptyStringTrimmed } from '$lib/utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
import { RefreshCw } from 'lucide-svelte'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
can_write?: boolean
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -45,6 +45,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
let initialPath = $state('')
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
useOperatingUser,
|
||||
useOperatingWorkspace
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
const triggerLock = useTriggerLock()
|
||||
interface Props {
|
||||
initialTriggerPath?: string | undefined
|
||||
dirtyLocalPart?: boolean
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -43,6 +43,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
let {
|
||||
useDrawer = true,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -48,6 +48,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
let initialPath = $state('')
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import {
|
||||
useOperatingUser,
|
||||
useOperatingWorkspace
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
initialTriggerPath?: string | undefined
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
generateRandomString,
|
||||
sendUserToast
|
||||
} from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2, Pipette, Plus } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -82,6 +82,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
let {
|
||||
useDrawer = true,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import { KafkaTriggerService, type ErrorHandler, type Retry, type TriggerMode } from '$lib/gen'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2, RotateCcw } from 'lucide-svelte'
|
||||
@@ -42,6 +42,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
import TriggerRunnablePicker from '$lib/components/triggers/TriggerRunnablePicker.svelte'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -51,6 +51,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
} from './utils'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { Button } from '$lib/components/common'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
@@ -32,6 +32,7 @@
|
||||
useOperatingUser,
|
||||
useOperatingWorkspace
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const operatingUser = useOperatingUser()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { ExtendedNativeTrigger } from './utils'
|
||||
import { getServiceConfig } from './utils'
|
||||
import { canWrite, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { userStore } from '$lib/stores'
|
||||
import TriggerModeToggle from '$lib/components/triggers/TriggerModeToggle.svelte'
|
||||
import Skeleton from '$lib/components/common/skeleton/Skeleton.svelte'
|
||||
@@ -18,6 +18,7 @@
|
||||
import GoogleDriveIcon from '$lib/components/icons/GoogleDriveIcon.svelte'
|
||||
import GoogleCalendarIcon from '$lib/components/icons/GoogleCalendarIcon.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
import { NatsTriggerService, type ErrorHandler, type Retry, type TriggerMode } from '$lib/gen'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -37,6 +37,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, emptyString, emptyStringTrimmed, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -59,6 +59,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
} from '$lib/gen'
|
||||
import { enterpriseLicense } from '$lib/stores'
|
||||
import { canWrite, emptyString, formatCron, sendUserToast, cronV1toV2 } from '$lib/utils'
|
||||
import { scheduleLock } from '$lib/operatorWriteRights'
|
||||
import { useScheduleLock } from '$lib/operatorWriteRights'
|
||||
import { base } from '$lib/base'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { List, Loader2, Save, AlertTriangle } from 'lucide-svelte'
|
||||
@@ -55,6 +55,7 @@
|
||||
import PermissionedAsLine from '../PermissionedAsLine.svelte'
|
||||
import { useActingUser } from '$lib/actingUser.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
const scheduleLock = useScheduleLock()
|
||||
|
||||
let {
|
||||
useDrawer = true,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -43,6 +43,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds } from '$lib/stores'
|
||||
import { canWrite, emptySchema, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2, X, Plus } from 'lucide-svelte'
|
||||
@@ -59,6 +59,7 @@
|
||||
useOperatingWorkspace,
|
||||
useOperatingWorkspaceHref
|
||||
} from '$lib/components/operatingWorkspace.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { derived } from 'svelte/store'
|
||||
import { userWorkspaces, workspaceStore } from '$lib/stores'
|
||||
import { userWorkspaces } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
/**
|
||||
* Why writes of this kind are locked in the active workspace, or `undefined` when they are not —
|
||||
* Why writes of this kind are locked in the operating workspace, or `undefined` when they are not —
|
||||
* the shape `title` and `disabled` both want. See `docs/operator-write-rights.md`.
|
||||
*
|
||||
* Only `false` locks. A workspace that never configured the key and a non-operator (whose
|
||||
@@ -10,8 +11,8 @@ import { userWorkspaces, workspaceStore } from '$lib/stores'
|
||||
* for everyone.
|
||||
*/
|
||||
function writeLock(key: 'manage_schedules' | 'manage_triggers', noun: string) {
|
||||
return derived([userWorkspaces, workspaceStore], ([$userWorkspaces, $workspaceStore]) => {
|
||||
const settings = $userWorkspaces.find((w) => w.id === $workspaceStore)?.operator_settings
|
||||
return derived([userWorkspaces, useOperatingWorkspace()], ([$userWorkspaces, $workspace]) => {
|
||||
const settings = $userWorkspaces.find((w) => w.id === $workspace)?.operator_settings
|
||||
// Worded as the server words its refusal of the same write.
|
||||
return settings?.[key] === false
|
||||
? `Operators cannot manage ${noun} in this workspace`
|
||||
@@ -19,5 +20,7 @@ function writeLock(key: 'manage_schedules' | 'manage_triggers', noun: string) {
|
||||
})
|
||||
}
|
||||
|
||||
export const scheduleLock = writeLock('manage_schedules', 'schedules')
|
||||
export const triggerLock = writeLock('manage_triggers', 'triggers')
|
||||
/** Reads context: call during component initialisation. */
|
||||
export const useScheduleLock = () => writeLock('manage_schedules', 'schedules')
|
||||
/** Reads context: call during component initialisation. */
|
||||
export const useTriggerLock = () => writeLock('manage_triggers', 'triggers')
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
} from '$lib/components/triggers/native/utils'
|
||||
import NativeTriggerTable from '$lib/components/triggers/native/NativeTriggerTable.svelte'
|
||||
import NativeTriggerEditor from '$lib/components/triggers/native/NativeTriggerEditor.svelte'
|
||||
import { triggerLock } from '$lib/operatorWriteRights'
|
||||
import { useTriggerLock } from '$lib/operatorWriteRights'
|
||||
import {
|
||||
sendUserToast,
|
||||
removeTriggerKindIfUnused,
|
||||
@@ -29,6 +29,7 @@
|
||||
import { page } from '$app/state'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import ListFilters from '$lib/components/home/ListFilters.svelte'
|
||||
const triggerLock = useTriggerLock()
|
||||
|
||||
type TriggerW = ExtendedNativeTrigger & { marked?: any }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user