mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-25 08:03:45 +00:00
fix(frontend): collapse the dev-workspace edit notice into a badge
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Compact marker for a workspace locked against direct edits. It sits above list and detail
|
||||
* pages that are otherwise unremarkable, so it stays a badge: the rule names, the route into the
|
||||
* dev workspace and the admin bypass live in its popover. Renders nothing for operators, who
|
||||
* have no edit affordance for it to explain.
|
||||
*/
|
||||
import { userStore, userWorkspaces, workspaceStore } from '$lib/stores'
|
||||
import {
|
||||
canUserBypassRuleKind,
|
||||
@@ -6,11 +12,13 @@
|
||||
isRuleActive
|
||||
} from '$lib/workspaceProtectionRules.svelte'
|
||||
import { findCanonicalDevWorkspace } from '$lib/utils/workspaceHierarchy'
|
||||
import { devLabelNoun } from '$lib/utils/devWorkspaceLabel'
|
||||
import { devLabelKey, devLabelNoun } from '$lib/utils/devWorkspaceLabel'
|
||||
import { canCreateFork } from '$lib/utils/editInFork'
|
||||
import { switchWorkspace } from '$lib/storeUtils'
|
||||
import { Alert, Button } from './common'
|
||||
import { GitFork } from 'lucide-svelte'
|
||||
import { Badge, Button } from './common'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import { GitFork, Lock, ShieldOff } from 'lucide-svelte'
|
||||
|
||||
let activeDeployRulesets = $derived(getActiveRulesetsForKind('DisableDirectDeployment'))
|
||||
let canBypass = $derived(canUserBypassRuleKind('DisableDirectDeployment', $userStore))
|
||||
@@ -24,7 +32,10 @@
|
||||
: 'You will need to make your changes locally and submit a PR to an authorized user.'
|
||||
)
|
||||
let overrideChecked = $state(false)
|
||||
let canEdit = $derived(!isRuleActive('DisableDirectDeployment') || (canBypass && overrideChecked))
|
||||
// The toggle is only offered to a user who can bypass, but the answer can change under a
|
||||
// workspace switch, so the checked flag alone never grants the edit.
|
||||
let bypassActive = $derived(canBypass && overrideChecked)
|
||||
let canEdit = $derived(!isRuleActive('DisableDirectDeployment') || bypassActive)
|
||||
|
||||
let {
|
||||
onUpdateCanEditStatus = (value) => {}
|
||||
@@ -35,50 +46,82 @@
|
||||
$effect(() => {
|
||||
onUpdateCanEditStatus(canEdit)
|
||||
})
|
||||
|
||||
// Short enough to read as a chip: the destination workspace and the rules behind it are one
|
||||
// click away in the popover.
|
||||
let badgeLabel = $derived(
|
||||
bypassActive
|
||||
? 'Protection bypassed'
|
||||
: canonicalDev
|
||||
? `Edits in ${devLabelKey(canonicalDev.dev_workspace_label)}`
|
||||
: 'Edits restricted'
|
||||
)
|
||||
</script>
|
||||
|
||||
{#if !$userStore?.operator && activeDeployRulesets.length > 0}
|
||||
<div class="my-2">
|
||||
<Alert
|
||||
type="info"
|
||||
title={canonicalDev
|
||||
? `Edits happen in the ${devLabelNoun(canonicalDev.dev_workspace_label)}`
|
||||
: 'Workspace protection active'}
|
||||
<Popover
|
||||
placement="bottom-start"
|
||||
class="inline-flex items-center"
|
||||
triggerAttrs={{ 'aria-label': badgeLabel }}
|
||||
>
|
||||
<div class="flex flex-col gap-2">
|
||||
{#if canonicalDev}
|
||||
<p>
|
||||
Edits to this workspace are made in its {devLabelNoun(canonicalDev.dev_workspace_label)}
|
||||
<b>{canonicalDev.name}</b> ({canonicalDev.id}) and promoted here.
|
||||
</p>
|
||||
<div>
|
||||
<Button
|
||||
btnClasses="w-auto"
|
||||
{#snippet trigger()}
|
||||
<Badge
|
||||
small
|
||||
color={bypassActive ? 'yellow' : 'blue'}
|
||||
class={bypassActive
|
||||
? 'cursor-pointer hover:bg-yellow-200 dark:hover:bg-yellow-500/25'
|
||||
: 'cursor-pointer hover:bg-blue-100 dark:hover:bg-blue-700/60'}
|
||||
>
|
||||
{#if bypassActive}
|
||||
<ShieldOff class="h-3 w-3" />
|
||||
{:else if canonicalDev}
|
||||
<GitFork class="h-3 w-3" />
|
||||
{:else}
|
||||
<Lock class="h-3 w-3" />
|
||||
{/if}
|
||||
{badgeLabel}
|
||||
</Badge>
|
||||
{/snippet}
|
||||
{#snippet content()}
|
||||
<div class="flex flex-col gap-3 p-4 text-xs max-w-sm">
|
||||
{#if canonicalDev}
|
||||
<p class="text-primary">
|
||||
Edits to this workspace are made in its {devLabelNoun(
|
||||
canonicalDev.dev_workspace_label
|
||||
)}
|
||||
<b>{canonicalDev.name}</b> ({canonicalDev.id}) and promoted here.
|
||||
</p>
|
||||
<div>
|
||||
<Button
|
||||
btnClasses="w-auto"
|
||||
size="xs"
|
||||
variant="accent"
|
||||
startIcon={{ icon: GitFork }}
|
||||
onclick={() => {
|
||||
if (canonicalDev) switchWorkspace(canonicalDev.id)
|
||||
}}
|
||||
>
|
||||
Go to {devLabelNoun(canonicalDev.dev_workspace_label)}
|
||||
</Button>
|
||||
</div>
|
||||
{:else}
|
||||
<p class="text-primary">
|
||||
The rule{activeDeployRulesets.length > 1 ? 's' : ''}
|
||||
<b>{activeDeployRulesets.map((r) => r.name).join(', ')}</b>
|
||||
restrict{activeDeployRulesets.length > 1 ? '' : 's'} direct edits to this workspace.
|
||||
{editAdvice}
|
||||
</p>
|
||||
{/if}
|
||||
{#if canBypass}
|
||||
<Toggle
|
||||
size="xs"
|
||||
variant="accent"
|
||||
startIcon={{ icon: GitFork }}
|
||||
onclick={() => {
|
||||
if (canonicalDev) switchWorkspace(canonicalDev.id)
|
||||
}}
|
||||
>
|
||||
Go to {devLabelNoun(canonicalDev.dev_workspace_label)}
|
||||
</Button>
|
||||
</div>
|
||||
{:else}
|
||||
<p>
|
||||
The rule{activeDeployRulesets.length > 1 ? 's' : ''}
|
||||
<b>{activeDeployRulesets.map((r) => r.name).join(', ')}</b>
|
||||
restrict{activeDeployRulesets.length > 1 ? '' : 's'} direct edits to this workspace.
|
||||
{editAdvice}
|
||||
</p>
|
||||
{/if}
|
||||
{#if canBypass}
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input class="rounded max-w-4" type="checkbox" bind:checked={overrideChecked} />
|
||||
<span class="text-xs">Bypass restriction</span>
|
||||
</label>
|
||||
{/if}
|
||||
</div>
|
||||
</Alert>
|
||||
bind:checked={overrideChecked}
|
||||
options={{ right: 'Bypass restriction' }}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{/snippet}
|
||||
</Popover>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user