mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-10 08:07:03 +00:00
* Add note component
* save note size and position
* move add note button up
* nit
* Add markdown support
* wip
* fix add sticky note button
* fix text update
* Add sticky note to saved flow data
* add note color picker
* Introduce node multiselect
* Add group notes
* Adapt layout to group node
* create a note manager class
* clean reactivity
* clean
* improve adaptive layout to group note
* modify layout based on cached text height
* fined grained graph rendering for notes
* separate noteManager into editor and render
* separate noteManager into editor and render
* create a note change observer
* render note node from context
* simplify note state managment
* show note in flow viewer
* clean dirty changes
* clean selection manager
* fix layout check
* improve bg surface select
* Handle z-index for stacked group notes
* clean selection manager
* exclude notes from rect select
* Allow switch between selection modes with keyboard keys
* improve selection box styling
* prevent dragging note when editing
* nit
* Simplify selection using svelte flow built in feature
* handle note selection separately
* Add min size for notes
* improve selection toggle
* improve mode switch
* make size and position optional for group notes
* Improve initial viewport position
* Add context menu for the canevas
* nit
* Add node context menu
* improve note select
* use clickoutside for note deselect
* use pointerdown outside to close context menu
* nit
* fix selection issues
* make edges non selectable
* improve color palette
* fix backend
* fix backend check
* cargo lock restore
* Add toggle to display notes
* fix note selection
* nit
* account for css offset in for loop
* fix multiple selection pannel styling
* clear flow selection when creating note
* Improve placeholder and note default text
* Escape note edit mode when pressing Esc
* Allow note edition in local dev
* clean
* Handle subflow selection
* prevent group note resizing
* nit
* allow notes in flow expand
* Improve multi select panel
* Allow context menu in note mode
* Add event listenner to fix pane click deselect
* prevent zoom in text area in notes
* improve bounding box styling
* Use control for box selection for non mac users
* nit
* clean notes groups
* nit
* use portal for note actions
* handle assets node when computing note layout
* Simplify layout compute for notes
* use smart color choice for notes
* Switch display note when adding a new note
* clean code
* improve group note bound size calculation
* simplify AI tool nodes and asset handling
* nit
* nit
* improve flow centering
* create group note button
* Improve selection of nodes
* Revert "Improve selection of nodes"
This reverts commit d2c40d82b1.
* refert backend changes
* nit
* improve graph selection
* clean
* make backend work except job runs
* fix notSelectable
---------
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
107 lines
2.6 KiB
TypeScript
107 lines
2.6 KiB
TypeScript
import type { Node } from '@xyflow/svelte'
|
|
|
|
export class SelectionManager {
|
|
#selectedNodes = $state<Node[] | { id: string }[]>([])
|
|
#selectionMode = $state<'normal' | 'rect-select'>('normal')
|
|
#clearGraphSelection: () => void = () => {}
|
|
|
|
constructor() {}
|
|
|
|
setClearGraphSelection(clearGraphSelection: () => void) {
|
|
this.#clearGraphSelection = clearGraphSelection
|
|
}
|
|
|
|
selectId(id: string) {
|
|
if (this.#selectedNodes.length === 1 && this.#selectedNodes[0].id === id) {
|
|
return
|
|
}
|
|
this.#clearGraphSelection()
|
|
this.#selectedNodes = [{ id }]
|
|
}
|
|
|
|
getSelectedId(): string {
|
|
if (this.#selectedNodes.length === 0) {
|
|
return 'settings'
|
|
}
|
|
const selectedNode = this.#selectedNodes[0]
|
|
|
|
if (selectedNode['type'] === 'branchOneEnd') {
|
|
const id = selectedNode.id.replace(/-end$/, '')
|
|
if (id !== '') {
|
|
return id
|
|
}
|
|
} else if (selectedNode['type'] === 'branchAllEnd') {
|
|
const id = selectedNode.id.replace(/-end$/, '')
|
|
if (id !== '') {
|
|
return id
|
|
}
|
|
} else if (selectedNode['type'] === 'forLoopStart') {
|
|
const id = selectedNode.id.replace(/-start$/, '')
|
|
if (id !== '') {
|
|
return id
|
|
}
|
|
} else if (selectedNode['type'] === 'forLoopEnd') {
|
|
const id = selectedNode.id.replace(/-end$/, '')
|
|
if (id !== '') {
|
|
return id
|
|
}
|
|
} else if (selectedNode['type'] === 'subflowBound') {
|
|
const id = selectedNode.id.replace(/-subflow-end$/, '')
|
|
if (id !== '') {
|
|
return id
|
|
}
|
|
}
|
|
return selectedNode.id
|
|
}
|
|
|
|
get mode() {
|
|
return this.#selectionMode
|
|
}
|
|
|
|
set mode(mode: 'normal' | 'rect-select') {
|
|
this.#selectionMode = mode
|
|
}
|
|
|
|
get selectedIds() {
|
|
if (this.#selectedNodes.length === 0) {
|
|
return ['settings']
|
|
}
|
|
return [...this.#selectedNodes.map((node) => node.id)]
|
|
}
|
|
|
|
// Select nodes with optional hierarchical selection
|
|
selectNodes(nodes: Node[]) {
|
|
// Guard against empty nodeIds or uninitialized state
|
|
if (!nodes || nodes.length === 0) {
|
|
this.clearSelection()
|
|
return
|
|
}
|
|
|
|
// If the new selection is the same as the current selection, do nothing
|
|
if (JSON.stringify(nodes) === JSON.stringify($state.snapshot(this.#selectedNodes))) {
|
|
return
|
|
}
|
|
|
|
this.#selectedNodes = nodes
|
|
}
|
|
|
|
// Clear all selections
|
|
clearSelection() {
|
|
this.#selectedNodes = [{ id: 'settings' }]
|
|
}
|
|
|
|
// Check if a node is selected
|
|
isNodeSelected(nodeId: string): boolean {
|
|
return this.#selectedNodes.some((node) => node.id === nodeId)
|
|
}
|
|
|
|
// Handle keyboard shortcuts
|
|
handleKeyDown(event: KeyboardEvent) {
|
|
if (event.key === 'Escape') {
|
|
// Escape key clears selection regardless of mode
|
|
this.clearSelection()
|
|
this.#clearGraphSelection()
|
|
}
|
|
}
|
|
}
|