fix(app): improve copy paste of tables with sub-components

This commit is contained in:
Ruben Fiszel
2025-08-12 10:01:13 +00:00
parent 5360171197
commit 5f22180214
4 changed files with 58 additions and 127 deletions

View File

@@ -19,7 +19,7 @@ import {
type TypedComponent
} from './component'
import { gridColumns } from '../gridUtils'
import { allItems } from '../utils'
import { allItems, processSubcomponents } from '../utils'
import type { Output, World } from '../rx'
import type { FilledItem, Size } from '../svelte-grid/types'
import type {
@@ -630,45 +630,11 @@ export function copyComponent(
const newItem = insertNewGridItem(
app,
(id) => {
if (item.data.type === 'tablecomponent') {
return {
...item.data,
id,
actionButtons:
item.data.actionButtons.map((x) => ({
...x,
id: x.id.replace(`${item.id}_`, `${id}_`)
})) ?? []
}
} else if (
item.data.type === 'aggridcomponent' ||
item.data.type === 'aggridcomponentee' ||
item.data.type === 'dbexplorercomponent' ||
item.data.type === 'aggridinfinitecomponent' ||
item.data.type === 'aggridinfinitecomponentee'
) {
return {
...item.data,
id,
actionButtons:
(item.data.actions ?? []).map((x) => ({
...x,
id: x.id.replace(`${item.id}_`, `${id}_`)
})) ?? []
}
} else if (item.data.type === 'menucomponent') {
return {
...item.data,
id,
menuItems:
item.data.menuItems.map((x) => ({
...x,
id: x.id.replace(`${item.id}_`, `${id}_`)
})) ?? []
}
} else {
return { ...item.data, id }
}
let newComponent = { ...item.data, id }
processSubcomponents(newComponent, (c) => {
c.id = c.id.replace(item.id + '_', id + '_')
})
return newComponent
},
parentGrid,
Object.fromEntries(gridColumns.map((column) => [column, item[column]]))
@@ -695,23 +661,9 @@ export function getAllSubgridsAndComponentIds(
): [string[], string[]] {
const subgrids: string[] = []
let components: string[] = [component.id]
if (component.type === 'tablecomponent') {
components.push(...component.actionButtons?.map((x) => x.id))
}
if (
component.type === 'aggridcomponent' ||
component.type === 'aggridcomponentee' ||
component.type === 'dbexplorercomponent' ||
component.type === 'aggridinfinitecomponent' ||
component.type === 'aggridinfinitecomponentee'
) {
components.push(...(component.actions?.map((x) => x.id) ?? []))
}
if (component.type === 'menucomponent') {
components.push(...component.menuItems?.map((x) => x.id))
}
processSubcomponents(component, (c) => {
components.push(c.id)
})
if (app.subgrids && component.numberOfSubgrids) {
for (let i = 0; i < component.numberOfSubgrids; i++) {
@@ -734,21 +686,11 @@ export function getAllGridItems(app: App): GridItem[] {
return app.grid
.concat(Object.values(app.subgrids ?? {}).flat())
.map((x) => {
if (x?.data?.type === 'tablecomponent') {
return [x, ...x?.data?.actionButtons?.map((x) => ({ data: x, id: x.id }))]
} else if (
(x?.data?.type === 'aggridcomponent' ||
x?.data?.type === 'aggridcomponentee' ||
x?.data?.type === 'dbexplorercomponent' ||
x?.data?.type === 'aggridinfinitecomponent' ||
x?.data?.type === 'aggridinfinitecomponentee') &&
Array.isArray(x?.data?.actions)
) {
return [x, ...x?.data?.actions?.map((x) => ({ data: x, id: x.id }))]
} else if (x?.data?.type === 'menucomponent') {
return [x, ...x?.data?.menuItems?.map((x) => ({ data: x, id: x.id }))]
}
return [x]
let r: GridItem[] = []
processSubcomponents(x.data, (c) => {
r.push({ data: c, id: c.id })
})
return [x, ...r]
})
.flat()
}

View File

@@ -12,6 +12,7 @@ import { sendUserToast } from '$lib/toast'
import { gridColumns } from '../../gridUtils'
import { copyToClipboard } from '$lib/utils'
import { get } from 'svelte/store'
import { processSubcomponents } from '../../utils'
// const { app, selectedComponent, focusedGrid, componentControl } =
// getContext<AppViewerContext>('AppViewerContext')
@@ -334,7 +335,13 @@ export async function handlePaste(
const gridItem = tempGridItem
insertNewGridItem(
app,
(id) => ({ ...gridItem.data, id }),
(id) => {
let newComponent = { ...gridItem.data, id }
processSubcomponents(newComponent, (c) => {
c.id = c.id.replace(tempGridItem.id + '_', id + '_')
})
return newComponent
},
focusedGrid,
Object.fromEntries(gridColumns.map((column) => [column, gridItem[column]])),
tempGridItem.id

View File

@@ -2,7 +2,7 @@
import { stopPropagation } from 'svelte/legacy'
import type { AppViewerContext, ContextPanelContext } from '$lib/components/apps/types'
import { allItems } from '$lib/components/apps/utils'
import { allItems, processSubcomponents } from '$lib/components/apps/utils'
import { classNames } from '$lib/utils'
import { ChevronDown, ChevronUp, Pointer } from 'lucide-svelte'
import { getContext } from 'svelte'
@@ -104,35 +104,11 @@
})
}
propagateRename(oldId, newId)
if (item?.data.type == 'tablecomponent') {
for (let c of item.data.actionButtons) {
let old = c.id
c.id = c.id.replace(oldId + '_', newId + '_')
propagateRename(old, c.id)
}
}
if (
item?.data.type == 'aggridcomponent' ||
item?.data.type == 'aggridcomponentee' ||
item?.data.type == 'dbexplorercomponent' ||
item?.data.type == 'aggridinfinitecomponent' ||
item?.data.type == 'aggridinfinitecomponentee'
) {
for (let c of item.data.actions ?? []) {
let old = c.id
c.id = c.id.replace(oldId + '_', newId + '_')
propagateRename(old, c.id)
}
}
if (item?.data.type === 'menucomponent') {
for (let c of item.data.menuItems) {
let old = c.id
c.id = c.id.replace(oldId + '_', newId + '_')
propagateRename(old, c.id)
}
}
processSubcomponents(item.data, (c) => {
let old = c.id
c.id = c.id.replace(oldId + '_', newId + '_')
propagateRename(old, c.id)
})
$app = $app
$selectedComponent = [newId]
@@ -141,30 +117,9 @@
}
function renameComponent(from: string, to: string, data: AppComponent) {
if (data.type == 'tablecomponent') {
for (let c of data.actionButtons) {
renameComponent(from, to, c)
}
}
if (
(data.type == 'aggridcomponent' ||
data.type == 'aggridcomponentee' ||
data.type == 'dbexplorercomponent' ||
data.type == 'aggridinfinitecomponent' ||
data.type == 'aggridinfinitecomponentee') &&
Array.isArray(data.actions)
) {
for (let c of data.actions) {
renameComponent(from, to, c)
}
}
if (data.type === 'menucomponent') {
for (let c of data.menuItems) {
renameComponent(from, to, c)
}
}
processSubcomponents(data, (c) => {
renameComponent(from, to, c)
})
let componentInput = data.componentInput
if (componentInput?.type == 'connected') {

View File

@@ -37,6 +37,33 @@ export function migrateApp(app: App) {
})
}
export function processSubcomponents(data: AppComponent, fn: (data: AppComponent) => void) {
if (data.type == 'tablecomponent' && Array.isArray(data.actionButtons)) {
for (let c of data.actionButtons) {
fn(c)
}
}
if (
(data.type == 'aggridcomponent' ||
data.type == 'aggridcomponentee' ||
data.type == 'dbexplorercomponent' ||
data.type == 'aggridinfinitecomponent' ||
data.type == 'aggridinfinitecomponentee') &&
Array.isArray(data.actions)
) {
for (let c of data.actions ?? []) {
fn(c)
}
}
if (data.type === 'menucomponent' && Array.isArray(data.menuItems)) {
for (let c of data.menuItems) {
fn(c)
}
}
}
export function allItems(
grid: GridItem[],
subgrids: Record<string, GridItem[]> | undefined