Skip to content

Commit

Permalink
feat: share dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
nichenqin committed Oct 22, 2024
1 parent 7b25d15 commit 38917da
Show file tree
Hide file tree
Showing 19 changed files with 323 additions and 17 deletions.
2 changes: 2 additions & 0 deletions apps/frontend/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ type Query {
baseByShare(shareId: ID!): Base
bases: [Base]
dashboard(id: ID!): Dashboard
dashboardByShare(shareId: ID!): Dashboard
dashboards(baseId: ID): [Dashboard]!
invitations(status: InvitationStatus): [Invitation!]!
member: SpaceMember
Expand All @@ -150,6 +151,7 @@ type Query {
table(id: ID!): Table
tableByShare(shareId: ID!): Table
tableByShareBase(shareId: ID!, tableId: ID!): Table
tableByShareDashboard(shareId: ID!, tableId: ID!): Table
tableForeignTables(tableId: ID!): [Table!]!
tables(baseId: ID): [Table]!
template(shareId: ID!): Template
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
query GetDashboardWidgetShareTable($shareId: ID!, $tableId: ID!) {
tableByShareDashboard(shareId: $shareId, tableId: $tableId) {
id
name

base {
id
name
}

schema {
id
name
type
defaultValue
display
constraint
option
}

views {
id
name
type
filter
color
sort
aggregate
fields
}
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
<script lang="ts">
import { TableFactory, type IWidgetDTO } from "@undb/table"
import { GetDashboardWidgetTableStore } from "$houdini"
import { onMount } from "svelte"
import { GetDashboardWidgetShareTableStore, GetDashboardWidgetTableStore } from "$houdini"
import Widget from "../widget/widget.svelte"
import { setTable } from "$lib/store/table.store"
import { writable } from "svelte/store"
export let tableId: string | undefined
export let shareId: string | undefined = undefined
export let widget: IWidgetDTO
export let movePointerDown: ((e: Event) => void) | undefined = undefined
export let resizePointerDown: ((e: Event) => void) | undefined = undefined
const store = new GetDashboardWidgetTableStore()
const shareStore = new GetDashboardWidgetShareTableStore()
$: if (tableId) {
store.fetch({ variables: { tableId } })
if (shareId) {
shareStore.fetch({ variables: { shareId, tableId } })
} else {
store.fetch({ variables: { tableId } })
}
}
$: table = $store.data?.table
$: table = shareId ? $shareStore.data?.tableByShareDashboard : $store.data?.table
$: tableDo = table ? new TableFactory().fromJSON(table) : undefined
$: if (tableDo) {
setTable(writable(tableDo))
}
</script>

<Widget table={tableDo} {widget} {tableId} {movePointerDown} {resizePointerDown} />
<Widget table={tableDo} {widget} {tableId} {shareId} {movePointerDown} {resizePointerDown} />
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import { trpc } from "$lib/trpc/client"
import type { IDashboardLayouts } from "@undb/dashboard"
export let shareId: string | undefined = undefined
const dashboard = getDashboard()
const widgetItems = getDashboardWidgetItemsStore()
Expand Down Expand Up @@ -49,7 +51,13 @@
on:pointerup={onPointeup}
>
{#if dataItem.widget}
<DashboardWidget widget={dataItem.widget} tableId={dataItem.tableId} {movePointerDown} {resizePointerDown} />
<DashboardWidget
widget={dataItem.widget}
{shareId}
tableId={dataItem.tableId}
{movePointerDown}
{resizePointerDown}
/>
{/if}
</Grid>
</div>
Expand Down
8 changes: 6 additions & 2 deletions apps/frontend/src/lib/components/blocks/widget/widget.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
const deleteViewWidgetMutation = createMutation({
mutationFn: trpc.table.view.widget.delete.mutate,
enabled: !shareId,
onSuccess: async () => {
confirmDelete = false
if (table) {
Expand All @@ -53,6 +54,7 @@
const deleteDashboardWidgetMutation = createMutation({
mutationFn: trpc.dashboard.widget.delete.mutate,
enabled: !shareId,
onSuccess: async () => {
confirmDelete = false
if ($isDashboard) {
Expand All @@ -69,6 +71,7 @@
let confirmDuplicate = false
const duplicateDashboardWidgetMutation = createMutation({
mutationFn: trpc.dashboard.widget.duplicate.mutate,
enabled: !shareId,
onSuccess: async () => {
if ($isDashboard) {
await invalidate(`dashboard:${$dashboard.id.value}`)
Expand All @@ -81,6 +84,7 @@
const duplicateViewWidgetMutation = createMutation({
mutationFn: trpc.table.view.widget.duplicate.mutate,
enabled: !shareId,
onSuccess: async () => {
confirmDuplicate = false
if (table) {
Expand All @@ -96,7 +100,7 @@
<div class={cn("group flex h-full w-full flex-col rounded-sm border", $$restProps.class)}>
<div class="flex items-center justify-between p-2">
<div class="flex items-center gap-0.5">
{#if movePointerDown}
{#if movePointerDown && !shareId}
<button on:pointerdown={movePointerDown}>
<GripVerticalIcon
class="text-muted-foreground size-4 cursor-grab opacity-0 group-hover:block group-hover:opacity-100 dark:text-gray-200"
Expand Down Expand Up @@ -197,7 +201,7 @@
<Aggregate {table} {tableId} {ignoreView} {widget} {viewId} {shareId} aggregate={widget.item.aggregate} />
{/if}

{#if resizePointerDown}
{#if resizePointerDown && !shareId}
<button on:pointerdown={resizePointerDown}>
<ChevronRightIcon
class="text-muted-foreground absolute bottom-0 right-0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import Button from "$lib/components/ui/button/button.svelte"
import { trpc } from "$lib/trpc/client"
import { createMutation } from "@tanstack/svelte-query"
import { goto, invalidateAll } from "$app/navigation"
import { goto, invalidate, invalidateAll } from "$app/navigation"
import * as Dialog from "$lib/components/ui/dialog"
import * as Form from "$lib/components/ui/form"
import { Input } from "$lib/components/ui/input"
Expand All @@ -21,6 +21,7 @@
import { Textarea } from "$lib/components/ui/textarea"
import { Loader2Icon } from "lucide-svelte"
import { toast } from "svelte-sonner"
import ShareButton from "$lib/components/blocks/share/share-button.svelte"
const dashboard = getDashboard()
Expand Down Expand Up @@ -128,13 +129,13 @@
</DropdownMenu.Root>
</h1>
<div class="flex items-center gap-2">
<!-- <ShareButton
<ShareButton
type="dashboard"
id={$dashboard.id.value}
onSuccess={() => {
invalidate(`undb:dashboard:${$dashboard.id.value}`)
}}
/> -->
/>

<AddDashboardWidgetButton variant="outline" size="sm" />
</div>
Expand Down
24 changes: 24 additions & 0 deletions apps/frontend/src/routes/(share)/s/[d]/[shareId]/+layout.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
query GetDashboardByShare($shareId: ID!) {
dashboardByShare(shareId: $shareId) {
id
name
description
baseId
spaceId
layout
share {
enabled
id
}
widgets {
table {
id
}
widget {
id
name
item
}
}
}
}
35 changes: 35 additions & 0 deletions apps/frontend/src/routes/(share)/s/[d]/[shareId]/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script lang="ts">
import { DashboardFactory } from "@undb/dashboard"
import type { LayoutData } from "./$types"
import { setDashboard } from "$lib/store/dashboard.store"
import { writable } from "svelte/store"
import { shareStore } from "$lib/store/share.store"
export let data: LayoutData
$: dashboardStore = data.dashboardStore
$: dashboard = $dashboardStore.data?.dashboardByShare
$: share = dashboard?.share
$: if (dashboard) {
const dashboardDo = DashboardFactory.fromJSON(dashboard)
setDashboard(writable(dashboardDo))
}
$: if (share && dashboard) {
shareStore.set(dashboard.id, {
enabled: share.enabled,
id: share.id,
target: { type: "dashboard", id: dashboard.id },
})
}
</script>

<svelte:head>
<title>{dashboard?.name || "undb"} - undb</title>
</svelte:head>

<main>
{#if dashboard}
<slot />
{/if}
</main>
23 changes: 23 additions & 0 deletions apps/frontend/src/routes/(share)/s/[d]/[shareId]/+layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { GetDashboardByShareStore } from "$houdini"
import { redirect } from "@sveltejs/kit"
import type { LayoutLoad } from "./$types"

export const prerender = "auto"

export const load: LayoutLoad = async (event) => {
const { shareId } = event.params

event.depends(`undb:dashboard:${shareId}`)

const store = new GetDashboardByShareStore()

const data = await store.fetch({ event, variables: { shareId }, policy: "NetworkOnly" })

if (data.errors?.length) {
throw redirect(302, "/")
}

return {
dashboardStore: store,
}
}
22 changes: 22 additions & 0 deletions apps/frontend/src/routes/(share)/s/[d]/[shareId]/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script lang="ts">
import { page } from "$app/stores"
import DashboardWidgets from "$lib/components/blocks/dashboard/dashboard-widgets.svelte"
import { getDashboard } from "$lib/store/dashboard.store"
import { GaugeIcon } from "lucide-svelte"
const dashboard = getDashboard()
const shareId = $page.params.shareId
</script>

<div class="flex h-full flex-col">
<header class="flex items-center justify-between border-b px-4 py-2">
<h1 class="flex items-center text-lg font-medium">
<GaugeIcon class="mr-2 size-5" />
{$dashboard.name.value}
</h1>
</header>
<main class="px-4 py-4">
<DashboardWidgets {shareId} />
</main>
</div>
15 changes: 15 additions & 0 deletions packages/graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
GetBaseShareQuery,
GetBasesQuery,
GetDashboardByIdQuery,
GetDashboardByShareQuery,
GetDashboardsQuery,
GetInivitationsQuery,
GetMemberByIdQuery,
Expand All @@ -27,6 +28,7 @@ import {
GetSpaceByIdQuery,
GetSpaceMemberQuery,
GetTableByShareBaseQuery,
GetTableByShareDashboardQuery,
GetTableByShareQuery,
GetTableForeignTablesQuery,
GetTableQuery,
Expand Down Expand Up @@ -376,6 +378,9 @@ export class Graphql {
dashboards(baseId: ID): [Dashboard]!
dashboard(id: ID!): Dashboard
dashboardByShare(shareId: ID!): Dashboard
tableByShareDashboard(shareId: ID!, tableId: ID!): Table
bases: [Base]
base(id: ID!): Base!
Expand Down Expand Up @@ -476,12 +481,22 @@ export class Graphql {
const base = await this.queryBus.execute(new GetBaseByShareQuery({ shareId: args.shareId }))
return base
},
dashboardByShare: async (_, args) => {
const dashboard = await this.queryBus.execute(new GetDashboardByShareQuery({ shareId: args.shareId }))
return dashboard
},
tableByShareBase: async (_, args) => {
const table = await this.queryBus.execute(
new GetTableByShareBaseQuery({ shareId: args.shareId, tableId: args.tableId }),
)
return table
},
tableByShareDashboard: async (_, args) => {
const table = await this.queryBus.execute(
new GetTableByShareDashboardQuery({ shareId: args.shareId, tableId: args.tableId }),
)
return table
},
tables: async (_, args) => {
return this.queryBus.execute(new GetTablesQuery({ baseId: args?.baseId }))
},
Expand Down
18 changes: 18 additions & 0 deletions packages/queries/src/get-dashboard-by-share.query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Query, type QueryProps } from "@undb/domain"
import { shareIdSchema } from "@undb/share"
import { z } from "@undb/zod"

export const getDashboardByShareQuery = z.object({
shareId: shareIdSchema,
})

export type IGetDashboardByShareQuery = z.infer<typeof getDashboardByShareQuery>

export class GetDashboardByShareQuery extends Query implements IGetDashboardByShareQuery {
public readonly shareId: string

constructor(query: QueryProps<IGetDashboardByShareQuery>) {
super()
this.shareId = query.shareId
}
}
22 changes: 22 additions & 0 deletions packages/queries/src/get-table-by-share-dashboard.query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Query, type QueryProps } from "@undb/domain"
import { shareIdSchema } from "@undb/share"
import { tableId } from "@undb/table"
import { z } from "@undb/zod"

export const getTableByShareDashboardQuery = z.object({
shareId: shareIdSchema,
tableId: tableId,
})

export type IGetTableByShareDashboardQuery = z.infer<typeof getTableByShareDashboardQuery>

export class GetTableByShareDashboardQuery extends Query implements IGetTableByShareDashboardQuery {
public readonly shareId: string
public readonly tableId: string

constructor(props: QueryProps<IGetTableByShareDashboardQuery>) {
super()
this.shareId = props.shareId
this.tableId = props.tableId
}
}
Loading

0 comments on commit 38917da

Please sign in to comment.