mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 00:06:06 +00:00
* feat: add dev workspaces paired with a lockable prod workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: gate dev-workspace prod-lock on admin and prevent attach cycles Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: redirect locked-prod edits into the dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: make dev-workspace settings tab available on CE (was EE-gated) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: lock prod against forking too and funnel edits to the dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: open dev item page on edit and tailor dev-workspace lock messages Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: prevent nested dev workspaces and hide dev option when one exists Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: drop the redundant already-has-dev hint on the fork form Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: badge dev workspaces and sort them ahead of forks in the tree/switcher Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: label dev workspaces as 'Dev workspace of X' instead of 'Fork of X' Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: label edit as 'Edit in <dev>', cover editor headers, auto-expand dev in tree Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: split prod lock into separate block-deploy and prevent-forking toggles Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: make resources/variables workspace-specific from compare page Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: steer AI-chat sessions to the dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: refine session fork options and lock guidance for dev/prod Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: session picker reads prod's real rules, default to current ws Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: copy members into forks and clarify dev-workspace root labeling Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: place the workspace id field under the fork name Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: address dev-workspace review findings and harden fork detection Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: regenerate sqlx offline cache Restores entries dropped during the origin/main merge and adds the dev-workspace queries (is_dev_workspace, ws_specific, has_parent). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: address second-round dev-workspace review findings Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: address Pi and Codex review findings on dev-workspace endpoints Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: gate locked-dev git-branch fork on admin and validate ws_specific path Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: clear prod dev-lock when deleting an attached dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: consolidate dev-workspace migration and scope all-group join to attach Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: restore dev-workspace CHECK into consolidated migration and scope all-group join Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: drop copy_members from the dev-workspace attach path Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: dev-workspace lifecycle/auth fixes from Codex review round Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: explicit create-in-other for workspace-specific items Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: make create-in-other strictly create-only (never overwrite target) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: return 403 (not 401) for dev-workspace permission denials Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: allow attaching a same-family fork as a dev workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: emphasize the go-to-dev action in the no-direct-deploy alert Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: seed a resource's linked variables when creating it in the other workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: judge workspace deploy/fork locks against the user's identity in that workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: clarify create-in help text in workspace-specific panel Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: admin-gate dev-workspace creation and harden lock/seed edges Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: preserve a staged fork's source on picker create-mode re-entry Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: clear dev flag on archive and check dev existence server-side Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: make create-in-other atomically create-only via direct create Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: create-only resource insert, ws-specific list scopes, archive lock guard Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: reserve the dev_workspace_lock protection-rule name from the public API Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: reattach create_protection_rule doc comment to its function Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: make dev-archive pairing teardown atomic with the archive Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: follow deploy_to on root rename; show dev pairing to non-member prod admins Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: copy creator metadata on fork; invalidate fork routing cache on rename Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: accept g/ paths in set_ws_specific; gate copy_members to dev workspaces Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
90 lines
3.3 KiB
TypeScript
90 lines
3.3 KiB
TypeScript
import { base } from '$lib/base'
|
|
import { get } from 'svelte/store'
|
|
import {
|
|
userStore,
|
|
userWorkspaces,
|
|
workspaceStore,
|
|
type UserWorkspace,
|
|
type UserExt
|
|
} from '$lib/stores'
|
|
import { findCanonicalDevWorkspace } from '$lib/utils/workspaceHierarchy'
|
|
import { isRuleActive, canUserBypassRuleKind } from '$lib/workspaceProtectionRules.svelte'
|
|
|
|
type ItemType = 'script' | 'flow' | 'app' | 'raw_app'
|
|
|
|
/**
|
|
* Whether to show the "edit in fork / dev workspace" affordance. Allowed when forking isn't disabled,
|
|
* when the user can bypass the forking rule (workspace admins, mirroring `canCreateFork`), OR when the
|
|
* current workspace has a canonical dev to route to — routing into an existing dev workspace creates
|
|
* no fork, so it survives a locked prod that has `DisableWorkspaceForking` set. User identity is read
|
|
* non-reactively (it's stable within a session); reactivity comes from the workspace args.
|
|
*/
|
|
export function editInForkAllowed(
|
|
currentWorkspaceId: string | undefined,
|
|
allWorkspaces: UserWorkspace[]
|
|
): boolean {
|
|
return (
|
|
!isRuleActive('DisableWorkspaceForking') ||
|
|
canUserBypassRuleKind('DisableWorkspaceForking', get(userStore)) ||
|
|
!!findCanonicalDevWorkspace(currentWorkspaceId, allWorkspaces)
|
|
)
|
|
}
|
|
|
|
/** Label for the affordance: "Edit in <dev name>" when routed to a canonical dev, else "Edit in fork". */
|
|
export function editInForkLabel(
|
|
currentWorkspaceId: string | undefined,
|
|
allWorkspaces: UserWorkspace[]
|
|
): string {
|
|
const dev = findCanonicalDevWorkspace(currentWorkspaceId, allWorkspaces)
|
|
return dev ? `Edit in ${dev.name}` : 'Edit in fork'
|
|
}
|
|
|
|
/**
|
|
* Whether the user may CREATE a new fork of the current workspace: forking not disabled, or the user
|
|
* can bypass the rule (workspace admins). Keeps the "Fork workspace" entry available to admins as the
|
|
* last-resort escape hatch on a locked prod.
|
|
*/
|
|
export function canCreateFork(user: UserExt | undefined): boolean {
|
|
return (
|
|
!isRuleActive('DisableWorkspaceForking') ||
|
|
canUserBypassRuleKind('DisableWorkspaceForking', user)
|
|
)
|
|
}
|
|
|
|
function editPathFor(itemType: ItemType, itemPath: string): string {
|
|
switch (itemType) {
|
|
case 'script':
|
|
return `${base}/scripts/edit/${itemPath}`
|
|
case 'flow':
|
|
return `${base}/flows/edit/${itemPath}`
|
|
case 'app':
|
|
return `${base}/apps/edit/${itemPath}`
|
|
case 'raw_app':
|
|
return `${base}/apps_raw/edit/${itemPath}`
|
|
}
|
|
}
|
|
|
|
function viewPathFor(itemType: ItemType, itemPath: string): string {
|
|
switch (itemType) {
|
|
case 'script':
|
|
return `${base}/scripts/get/${itemPath}`
|
|
case 'flow':
|
|
return `${base}/flows/get/${itemPath}`
|
|
case 'app':
|
|
return `${base}/apps/get/${itemPath}`
|
|
case 'raw_app':
|
|
return `${base}/apps_raw/get/${itemPath}`
|
|
}
|
|
}
|
|
|
|
export function buildForkEditUrl(itemType: ItemType, itemPath: string): string {
|
|
// When the current ("prod") workspace has a canonical dev workspace, edits are funneled there:
|
|
// land on the item's page in the dev workspace (not straight in the editor) so the workspace
|
|
// switch is legible and the user opens the editor deliberately from there.
|
|
const dev = findCanonicalDevWorkspace(get(workspaceStore), get(userWorkspaces))
|
|
if (dev) {
|
|
return `${viewPathFor(itemType, itemPath)}?workspace=${encodeURIComponent(dev.id)}`
|
|
}
|
|
return `${base}/user/fork_workspace?rd=${encodeURIComponent(editPathFor(itemType, itemPath))}`
|
|
}
|