mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-18 16:02:10 +00:00
feat(frontend): Add the ability to lock components so they don't move around (#1035)
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
|
||||
export let component: AppComponent
|
||||
export let selected: boolean
|
||||
export let locked: boolean = false
|
||||
|
||||
$: shouldDisplayOverlay = selected && $mode !== 'preview'
|
||||
|
||||
@@ -26,12 +27,12 @@
|
||||
|
||||
<div class="h-full flex flex-col w-full">
|
||||
{#if shouldDisplayOverlay}
|
||||
<ComponentHeader {component} {selected} on:delete />
|
||||
<ComponentHeader {component} {selected} on:delete on:lock {locked} />
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class={classNames(
|
||||
' border cursor-pointer h-full bg-white',
|
||||
'border cursor-pointer h-full bg-white',
|
||||
shouldDisplayOverlay ? 'border-blue-500' : 'border-white',
|
||||
!selected && $mode !== 'preview' && !component.card ? 'border-gray-100' : '',
|
||||
$mode !== 'preview' && !$connectingInput.opened ? 'hover:border-blue-500' : '',
|
||||
@@ -77,10 +78,7 @@
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
{:else if component.type === 'selectcomponent'}
|
||||
<SelectComponent
|
||||
{...component}
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
<SelectComponent {...component} bind:staticOutputs={$staticOutputs[component.id]} />
|
||||
{:else if component.type === 'formcomponent'}
|
||||
<AppForm
|
||||
{...component}
|
||||
@@ -92,9 +90,17 @@
|
||||
{:else if component.type === 'textinputcomponent'}
|
||||
<TextInputComponent {...component} bind:staticOutputs={$staticOutputs[component.id]} />
|
||||
{:else if component.type === 'passwordinputcomponent'}
|
||||
<TextInputComponent inputType='password' {...component} bind:staticOutputs={$staticOutputs[component.id]} />
|
||||
<TextInputComponent
|
||||
inputType="password"
|
||||
{...component}
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
{:else if component.type === 'dateinputcomponent'}
|
||||
<DateInputComponent inputType='date' {...component} bind:staticOutputs={$staticOutputs[component.id]} />
|
||||
<DateInputComponent
|
||||
inputType="date"
|
||||
{...component}
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
{:else if component.type === 'numberinputcomponent'}
|
||||
<NumberInputComponent {...component} bind:staticOutputs={$staticOutputs[component.id]} />
|
||||
{/if}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { classNames } from '$lib/utils'
|
||||
import type { AppComponent } from '../types'
|
||||
import { displayData } from '../utils'
|
||||
import { X } from 'lucide-svelte'
|
||||
import { Lock, X } from 'lucide-svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let component: AppComponent
|
||||
export let selected: boolean
|
||||
export let locked: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
@@ -19,6 +19,23 @@
|
||||
>
|
||||
{component.id}
|
||||
</span>
|
||||
|
||||
<button
|
||||
class={classNames(
|
||||
'text-white px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute -top-5 right-8 cursor-pointer',
|
||||
'bg-gray-600 hover:bg-gray-800'
|
||||
)}
|
||||
on:click={() => {
|
||||
dispatch('lock')
|
||||
}}
|
||||
>
|
||||
{#if locked}
|
||||
<Lock size={16} class="text-red-500" />
|
||||
{:else}
|
||||
<Lock size={16} />
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<button
|
||||
class={classNames(
|
||||
'text-white px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute -top-5 right-0 cursor-pointer',
|
||||
|
||||
@@ -4,7 +4,14 @@
|
||||
import Grid from 'svelte-grid'
|
||||
import ComponentEditor from './ComponentEditor.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { columnConfiguration, disableDrag, enableDrag, gridColumns } from '../gridUtils'
|
||||
import {
|
||||
columnConfiguration,
|
||||
disableDrag,
|
||||
enableDrag,
|
||||
gridColumns,
|
||||
isFixed,
|
||||
toggleFixed
|
||||
} from '../gridUtils'
|
||||
import { Alert } from '$lib/components/common'
|
||||
import { fly } from 'svelte/transition'
|
||||
import gridHelp from 'svelte-grid/build/helper/index.mjs'
|
||||
@@ -40,40 +47,37 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="bg-white h-full relative"
|
||||
on:click|preventDefault={() => $selectedComponent = undefined}
|
||||
>
|
||||
<div class="bg-white h-full relative">
|
||||
<RecomputeAllComponents />
|
||||
|
||||
<Grid
|
||||
bind:items={$app.grid}
|
||||
let:dataItem
|
||||
rowHeight={64}
|
||||
cols={columnConfiguration}
|
||||
fastStart={true}
|
||||
fillSpace={true}
|
||||
throttleUpdate={50}
|
||||
on:pointerup={({ detail }) => {
|
||||
if (!$connectingInput.opened) {
|
||||
$selectedComponent = detail.id
|
||||
}
|
||||
}}
|
||||
>
|
||||
{#each $app.grid as gridComponent (gridComponent.id)}
|
||||
{#if gridComponent.data.id === dataItem.data.id}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
|
||||
<div
|
||||
class={classNames(
|
||||
'h-full w-full flex justify-center align-center',
|
||||
gridComponent.data.card ? 'border border-gray-100' : ''
|
||||
)}
|
||||
on:click|stopPropagation={() => {
|
||||
if (!$connectingInput.opened) {
|
||||
$selectedComponent = dataItem.data.id
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ComponentEditor
|
||||
bind:component={gridComponent.data}
|
||||
selected={$selectedComponent === dataItem.data.id}
|
||||
on:delete={() => deleteComponent(gridComponent.data)}
|
||||
on:lock={() => {
|
||||
gridComponent = toggleFixed(gridComponent)
|
||||
}}
|
||||
locked={isFixed(gridComponent)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -22,6 +22,24 @@ function disableDrag(component: GridItem): GridItem {
|
||||
return component
|
||||
}
|
||||
|
||||
function toggleFixed(component: GridItem): GridItem {
|
||||
gridColumns.forEach((column: number) => {
|
||||
component[column].fixed = !component[column].fixed
|
||||
})
|
||||
|
||||
return component
|
||||
}
|
||||
|
||||
function isFixed(component: GridItem): boolean {
|
||||
let fixed = false
|
||||
gridColumns.forEach((column: number) => {
|
||||
if (component[column].fixed) {
|
||||
fixed = true
|
||||
}
|
||||
})
|
||||
return fixed
|
||||
}
|
||||
|
||||
function enableDrag(component: GridItem): GridItem {
|
||||
gridColumns.forEach((column: number) => {
|
||||
component[column].customDragger = false
|
||||
@@ -30,4 +48,12 @@ function enableDrag(component: GridItem): GridItem {
|
||||
return component
|
||||
}
|
||||
|
||||
export { gridColumns, columnConfiguration, disableDrag, enableDrag, Breakpoints }
|
||||
export {
|
||||
gridColumns,
|
||||
columnConfiguration,
|
||||
disableDrag,
|
||||
enableDrag,
|
||||
Breakpoints,
|
||||
toggleFixed,
|
||||
isFixed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user