Skip to content

Commit bdeed5d

Browse files
authored
Merge pull request #2104 from undb-io/release/v1.0.0-106
Release version v1.0.0-106
2 parents 4809ee8 + f416d33 commit bdeed5d

File tree

26 files changed

+396
-23
lines changed

26 files changed

+396
-23
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## v1.0.0-106
4+
5+
6+
### 🩹 Fixes
7+
8+
- Fix dropping table ([f2bf79b](https://github.com/undb-io/undb/commit/f2bf79b))
9+
10+
### ❤️ Contributors
11+
12+
- Nichenqin ([@nichenqin](http://github.com/nichenqin))
13+
314
## v1.0.0-105
415

516

apps/frontend/src/lib/components/blocks/grid-view/grid-view-data-table.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@
210210
hasFilter && "bg-orange-50",
211211
)}
212212
use:props.resize
213+
data-field-id={cell.id}
213214
>
214215
{#if cell.id === "$select" && !$hasRecord}
215216
<Checkbox checked={false} disabled />

apps/frontend/src/lib/components/blocks/widget/widget.svelte

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
import * as AlertDialog from "$lib/components/ui/alert-dialog"
1515
import { invalidate } from "$app/navigation"
1616
import { toast } from "svelte-sonner"
17-
import { getDashboard, getIsDashboard } from "$lib/store/dashboard.store"
17+
import { getDashboard, getDashboardWidgetItemsStore, getIsDashboard } from "$lib/store/dashboard.store"
1818
import { cn } from "$lib/utils"
19-
import { GripVerticalIcon, ChevronRightIcon } from "lucide-svelte"
19+
import { GripVerticalIcon, ChevronRightIcon, CopyIcon } from "lucide-svelte"
20+
import { COLS } from "$lib/store/widget.store"
21+
import { DashboardLayouts } from "@undb/dashboard"
2022
2123
export let tableId: string | undefined
2224
export let table: TableDo | undefined
@@ -61,6 +63,34 @@
6163
toast.error(error.message)
6264
},
6365
})
66+
67+
const dashboardWidgets = getDashboardWidgetItemsStore()
68+
69+
let confirmDuplicate = false
70+
const duplicateDashboardWidgetMutation = createMutation({
71+
mutationFn: trpc.dashboard.widget.duplicate.mutate,
72+
onSuccess: async () => {
73+
if ($isDashboard) {
74+
await invalidate(`dashboard:${$dashboard.id.value}`)
75+
}
76+
},
77+
onError(error, variables, context) {
78+
toast.error(error.message)
79+
},
80+
})
81+
82+
const duplicateViewWidgetMutation = createMutation({
83+
mutationFn: trpc.table.view.widget.duplicate.mutate,
84+
onSuccess: async () => {
85+
confirmDuplicate = false
86+
if (table) {
87+
await invalidate(`table:${tableId}`)
88+
}
89+
},
90+
onError(error, variables, context) {
91+
toast.error(error.message)
92+
},
93+
})
6494
</script>
6595

6696
<div class={cn("group flex h-full w-full flex-col rounded-sm border", $$restProps.class)}>
@@ -150,6 +180,10 @@
150180
<PencilIcon class="mr-2 size-3" />
151181
Edit Name
152182
</DropdownMenu.Item>
183+
<DropdownMenu.Item class="text-xs" on:click={() => (confirmDuplicate = true)}>
184+
<CopyIcon class="mr-2 size-3" />
185+
Duplicate
186+
</DropdownMenu.Item>
153187
<DropdownMenu.Item class="text-xs" on:click={() => (confirmDelete = true)}>
154188
<TrashIcon class="mr-2 size-3" />
155189
Delete
@@ -202,3 +236,39 @@
202236
</AlertDialog.Footer>
203237
</AlertDialog.Content>
204238
</AlertDialog.Root>
239+
240+
<AlertDialog.Root bind:open={confirmDuplicate}>
241+
<AlertDialog.Content>
242+
<AlertDialog.Header>
243+
<AlertDialog.Title>Duplicate Widget {widget.name}?</AlertDialog.Title>
244+
</AlertDialog.Header>
245+
<AlertDialog.Footer>
246+
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
247+
<AlertDialog.Action asChild>
248+
<Button
249+
on:click={() => {
250+
if ($isDashboard) {
251+
const added = dashboardWidgets.add(widget.item.type)
252+
const layout = added[COLS]
253+
const defaultLayout = DashboardLayouts.default()
254+
$duplicateDashboardWidgetMutation.mutate({
255+
dashboardId: $dashboard.id.value,
256+
widgetId: widget.id,
257+
layout: {
258+
x: layout.x ?? defaultLayout.x,
259+
y: layout.y ?? defaultLayout.y,
260+
w: layout.w ?? defaultLayout.w,
261+
h: layout.h ?? defaultLayout.h,
262+
},
263+
})
264+
} else if (viewId && tableId) {
265+
$duplicateViewWidgetMutation.mutate({ tableId, viewId, widgetId: widget.id })
266+
}
267+
}}
268+
>
269+
Duplicate
270+
</Button>
271+
</AlertDialog.Action>
272+
</AlertDialog.Footer>
273+
</AlertDialog.Content>
274+
</AlertDialog.Root>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "undb",
3-
"version": "1.0.0-105",
3+
"version": "1.0.0-106",
44
"private": true,
55
"scripts": {
66
"build": "NODE_ENV=production bun --bun turbo build",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { DuplicateDashboardWidgetCommand } from "@undb/commands"
2+
import { commandHandler } from "@undb/cqrs"
3+
import { injectDashboardService, type IDashboarService } from "@undb/dashboard"
4+
import { singleton } from "@undb/di"
5+
import { type ICommandHandler } from "@undb/domain"
6+
import { createLogger } from "@undb/logger"
7+
8+
@commandHandler(DuplicateDashboardWidgetCommand)
9+
@singleton()
10+
export class DuplicateDashboardWidgetCommandHandler implements ICommandHandler<DuplicateDashboardWidgetCommand, any> {
11+
private readonly logger = createLogger(DuplicateDashboardWidgetCommandHandler.name)
12+
13+
constructor(
14+
@injectDashboardService()
15+
private readonly service: IDashboarService,
16+
) {}
17+
18+
async execute(command: DuplicateDashboardWidgetCommand): Promise<any> {
19+
this.logger.debug(command)
20+
21+
await this.service.duplicateWidget({
22+
dashboardId: command.dashboardId,
23+
widgetId: command.widgetId,
24+
layout: command.layout,
25+
})
26+
}
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { DuplicateViewWidgetCommand } from "@undb/commands"
2+
import { commandHandler } from "@undb/cqrs"
3+
import { singleton } from "@undb/di"
4+
import type { ICommandHandler } from "@undb/domain"
5+
import { injectTableRepository, TableIdVo, type ITableRepository } from "@undb/table"
6+
7+
@commandHandler(DuplicateViewWidgetCommand)
8+
@singleton()
9+
export class DuplicateViewWidgetCommandHandler implements ICommandHandler<DuplicateViewWidgetCommand, void> {
10+
constructor(
11+
@injectTableRepository()
12+
private readonly repo: ITableRepository,
13+
) {}
14+
15+
async execute(command: DuplicateViewWidgetCommand): Promise<void> {
16+
const table = (await this.repo.findOneById(new TableIdVo(command.tableId))).expect("table not found")
17+
18+
const spec = table.views.$duplicateWidget(table, command)
19+
20+
await this.repo.updateOneById(table, spec)
21+
}
22+
}

packages/command-handlers/src/handlers/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ import { DeleteViewCommandHandler } from "./delete-view.command-handler"
3131
import { DeleteWebhookCommandHandler } from "./delete-webhook.command-handler"
3232
import { DisableShareCommandHandler } from "./disable-share.command-handler"
3333
import { DuplicateBaseCommandHandler } from "./duplicate-base.command-handler"
34+
import { DuplicateDashboardWidgetCommandHandler } from "./duplicate-dashboard-widget.command-handler"
3435
import { DuplicateDashboardCommandHandler } from "./duplicate-dashboard.command-handler"
3536
import { DuplicateRecordCommandHandler } from "./duplicate-record.command-handler"
3637
import { DuplicateTableFieldCommandHandler } from "./duplicate-table-field.command-handler"
3738
import { DuplicateTableFormCommandHandler } from "./duplicate-table-form.command-handler"
3839
import { DuplicateTableCommandHandler } from "./duplicate-table.command-handler"
40+
import { DuplicateViewWidgetCommandHandler } from "./duplicate-view-widget.command-handler"
3941
import { DuplicateViewCommandHandler } from "./duplicate-view.command-handler"
4042
import { EnableShareCommandHandler } from "./enable-share.command-handler"
4143
import { ExportViewCommandHandler } from "./export-view.command-handler"
@@ -132,4 +134,6 @@ export const commandHandlers = [
132134
DeleteDashboardCommandHandler,
133135
UpdateDashboardCommandHandler,
134136
DuplicateDashboardCommandHandler,
137+
DuplicateDashboardWidgetCommandHandler,
138+
DuplicateViewWidgetCommandHandler,
135139
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { duplicateDashboardWidgetDTO, type IDashboardLayout } from "@undb/dashboard"
2+
import { Command, type CommandProps } from "@undb/domain"
3+
import { z } from "@undb/zod"
4+
5+
export const duplicateDashboardWidgetCommand = duplicateDashboardWidgetDTO
6+
7+
export type IDuplicateDashboardWidgetCommand = z.infer<typeof duplicateDashboardWidgetCommand>
8+
9+
export class DuplicateDashboardWidgetCommand extends Command implements IDuplicateDashboardWidgetCommand {
10+
public readonly dashboardId: string
11+
public readonly widgetId: string
12+
public readonly layout: IDashboardLayout
13+
14+
constructor(props: CommandProps<IDuplicateDashboardWidgetCommand>) {
15+
super(props)
16+
this.dashboardId = props.dashboardId
17+
this.widgetId = props.widgetId
18+
this.layout = props.layout
19+
}
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Command, type CommandProps } from "@undb/domain"
2+
import { duplicateViewWidgetDTO, tableId } from "@undb/table"
3+
import { z } from "@undb/zod"
4+
5+
export const duplicateViewWidgetCommand = duplicateViewWidgetDTO.extend({
6+
tableId,
7+
})
8+
9+
export type IDuplicateViewWidgetCommand = z.infer<typeof duplicateViewWidgetCommand>
10+
11+
export class DuplicateViewWidgetCommand extends Command implements IDuplicateViewWidgetCommand {
12+
public readonly tableId: string
13+
public readonly viewId: string
14+
public readonly widgetId: string
15+
16+
constructor(props: CommandProps<IDuplicateViewWidgetCommand>) {
17+
super(props)
18+
this.tableId = props.tableId
19+
this.viewId = props.viewId
20+
this.widgetId = props.widgetId
21+
}
22+
}

packages/commands/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ export * from "./delete-view.command"
3131
export * from "./delete-webhook.command"
3232
export * from "./disable-share.command"
3333
export * from "./duplicate-base.command"
34+
export * from "./duplicate-dashboard-widget.command"
3435
export * from "./duplicate-dashboard.command"
3536
export * from "./duplicate-record.command"
3637
export * from "./duplicate-table-field.command"
3738
export * from "./duplicate-table-form.command"
3839
export * from "./duplicate-table.command"
40+
export * from "./duplicate-view-widget.command"
3941
export * from "./duplicate-view.command"
4042
export * from "./enable-share.command"
4143
export * from "./export-view.command"

0 commit comments

Comments
 (0)