Skip to content

Commit

Permalink
chore: share data record
Browse files Browse the repository at this point in the history
  • Loading branch information
nichenqin committed Aug 15, 2024
1 parent 17701d7 commit 0dc8699
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,29 @@
import Button from "$lib/components/ui/button/button.svelte"
import RecordDetail from "./record-detail.svelte"
import { queryParam, ssp } from "sveltekit-search-params"
import { getTable, viewId } from "$lib/store/table.store"
import { trpc } from "$lib/trpc/client"
import { createQuery, useIsMutating, useQueryClient } from "@tanstack/svelte-query"
import { getTable } from "$lib/store/table.store"
import { useIsMutating, useQueryClient } from "@tanstack/svelte-query"
import { RecordDO } from "@undb/table"
import { derived } from "svelte/store"
import Skeleton from "$lib/components/ui/skeleton/skeleton.svelte"
import { cn } from "$lib/utils"
import AuditList from "../audit/audit-list.svelte"
import { HistoryIcon, LoaderCircleIcon } from "lucide-svelte"
import { LoaderCircleIcon } from "lucide-svelte"
import { preferences } from "$lib/store/persisted.store"
import { ScrollArea } from "$lib/components/ui/scroll-area"
export let readonly = false
export let recordDo: RecordDO | undefined
export let isLoading: boolean
const r = queryParam("r", ssp.string(), { pushHistory: false })
const table = getTable()
const record = createQuery(
derived([table, r, preferences], ([$table, $recordId, $preferences]) => ({
queryKey: [$recordId, "get", $preferences.showHiddenFields],
queryFn: () => {
return trpc.record.get.query({
tableId: $table?.id.value,
id: $recordId!,
select: $preferences.showHiddenFields
? undefined
: $table?.getOrderedVisibleFields($viewId).map((f) => f.id.value),
})
},
enabled: !!$recordId,
})),
)
const isUpdatingRecord = useIsMutating({
mutationKey: ["updateRecord"],
})
const client = useQueryClient()
$: recordDo = $record.data?.record ? RecordDO.fromJSON($table, $record.data?.record) : undefined
let disabled = false
</script>

Expand Down Expand Up @@ -73,7 +54,7 @@
</Sheet.Header>

<div class="flex-1 overflow-hidden">
{#if $record.isLoading}
{#if isLoading}
<div class="space-y-4 px-6 py-4">
<Skeleton class="h-10 w-full" />
<Skeleton class="h-10 w-full" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script lang="ts">
import { queryParam, ssp } from "sveltekit-search-params"
import { getTable, viewId } from "$lib/store/table.store"
import { trpc } from "$lib/trpc/client"
import { createQuery } from "@tanstack/svelte-query"
import { RecordDO } from "@undb/table"
import { derived } from "svelte/store"
import { preferences } from "$lib/store/persisted.store"
import RecordDetailSheet from "./record-detail-sheet.svelte"
import { page } from "$app/stores"
export let readonly = false
const r = queryParam("r", ssp.string(), { pushHistory: false })
const table = getTable()
const record = createQuery(
derived([table, r, page], ([$table, $recordId, $page]) => ({
queryKey: [$recordId, "get", $preferences.showHiddenFields],
queryFn: () => {
return trpc.shareData.record.query({
shareId: $page.params.shareId,
recordId: $recordId!,
})
},
enabled: !!$recordId,
})),
)
$: recordDo = $record.data?.record ? RecordDO.fromJSON($table, $record.data?.record) : undefined
</script>

<RecordDetailSheet {readonly} {recordDo} isLoading={$record.isLoading} />
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts">
import { queryParam, ssp } from "sveltekit-search-params"
import { getTable, viewId } from "$lib/store/table.store"
import { trpc } from "$lib/trpc/client"
import { createQuery } from "@tanstack/svelte-query"
import { RecordDO } from "@undb/table"
import { derived } from "svelte/store"
import { preferences } from "$lib/store/persisted.store"
import RecordDetailSheet from "./record-detail-sheet.svelte"
export let readonly = false
const r = queryParam("r", ssp.string(), { pushHistory: false })
const table = getTable()
const record = createQuery(
derived([table, r, preferences], ([$table, $recordId, $preferences]) => ({
queryKey: [$recordId, "get", $preferences.showHiddenFields],
queryFn: () => {
return trpc.record.get.query({
tableId: $table?.id.value,
id: $recordId!,
select: $preferences.showHiddenFields
? undefined
: $table?.getOrderedVisibleFields($viewId).map((f) => f.id.value),
})
},
enabled: !!$recordId,
})),
)
$: recordDo = $record.data?.record ? RecordDO.fromJSON($table, $record.data?.record) : undefined
</script>

<RecordDetailSheet {readonly} {recordDo} isLoading={$record.isLoading} />
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import { derived } from "svelte/store"
import UpdateTableDialog from "$lib/components/blocks/update-table/update-table-dialog.svelte"
import DeleteTableDialog from "$lib/components/blocks/delete-table/delete-table-dialog.svelte"
import TableRecordDetailSheet from "$lib/components/blocks/record-detail/table-record-detail-sheet.svelte"
function handleR() {
toggleModal(CREATE_RECORD_MODAL)
Expand Down Expand Up @@ -47,7 +48,7 @@
</main>

<CreateRecordSheet />
<RecordDetailSheet />
<TableRecordDetailSheet />
<ConfirmDeleteRecord />
<ConfirmDuplicateRecord />
<UpdateViewDialog />
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/routes/s/v/[shareId]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
let RecordDetailSheet: ComponentType
onMount(async () => {
RecordDetailSheet = (await import("$lib/components/blocks/record-detail/record-detail-sheet.svelte")).default
RecordDetailSheet = (await import("$lib/components/blocks/record-detail/share-record-detail-sheet.svelte")).default
})
const viewId = derived([shareStore, page], ([$shareStore, $page]) => {
Expand Down
6 changes: 5 additions & 1 deletion packages/queries/src/get-record-by-id.query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ export const getRecordByIdOutput = z.object({
export type IGetRecordByIdOutput = z.infer<typeof getRecordByIdOutput>

export class GetRecordByIdQuery extends Query implements IGetRecordByIdQuery {
public readonly tableId: string
public readonly tableId?: string
public readonly baseName?: string
public readonly tableName?: string
public readonly id: string
public readonly select?: string[]

constructor(props: QueryProps<IGetRecordByIdQuery>) {
super()
this.tableId = props.tableId
this.baseName = props.baseName
this.tableName = props.tableName
this.id = props.id
this.select = props.select
}
Expand Down
28 changes: 28 additions & 0 deletions packages/queries/src/get-share-record-by-id.query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Query, type QueryProps } from "@undb/domain"
import { shareIdSchema } from "@undb/share"
import { recordDTO, recordId } from "@undb/table"
import { z } from "@undb/zod"

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

export type IGetShareRecordByIdQuery = z.infer<typeof getShareRecordByIdQuery>

export const getShareRecordByIdOutput = z.object({
record: recordDTO.nullable(),
})

export type IGetShareRecordByIdOutput = z.infer<typeof getShareRecordByIdOutput>

export class GetShareRecordByIdQuery extends Query implements IGetShareRecordByIdQuery {
public readonly shareId: string
public readonly recordId: string

constructor(props: QueryProps<IGetShareRecordByIdQuery>) {
super()
this.shareId = props.shareId
this.recordId = props.recordId
}
}
1 change: 1 addition & 0 deletions packages/queries/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * from "./get-record-audits.query"
export * from "./get-record-by-id.query"
export * from "./get-records.query"
export * from "./get-rollup-foreign-tables.query"
export * from "./get-share-record-by-id.query"
export * from "./get-share-records.query"
export * from "./get-share.query"
export * from "./get-space-by-id.query"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { setContextValue } from "@undb/context/server"
import { queryHandler } from "@undb/cqrs"
import { singleton } from "@undb/di"
import type { IQueryHandler } from "@undb/domain"
import { GetShareRecordByIdQuery, type IGetShareRecordByIdOutput, type IGetShareRecordByIdQuery } from "@undb/queries"
import { injectShareService, type IShareService } from "@undb/share"
import { injectSpaceService, type ISpaceService } from "@undb/space"

@queryHandler(GetShareRecordByIdQuery)
@singleton()
export class GetShareRecordByIdQueryHandler
implements IQueryHandler<IGetShareRecordByIdQuery, IGetShareRecordByIdOutput>
{
constructor(
@injectShareService()
private readonly svc: IShareService,
@injectSpaceService()
private readonly spaceService: ISpaceService,
) {}

async execute(query: IGetShareRecordByIdQuery): Promise<IGetShareRecordByIdOutput> {
const { shareId, recordId } = query
await this.spaceService.setSpaceContext(setContextValue, { shareId })
const record = await this.svc.getShareRecordById(shareId, recordId)

return {
record: record.into(null),
}
}
}
2 changes: 2 additions & 0 deletions packages/query-handlers/src/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { GetRecordAuditsQueryHandler } from "./get-record-audits.query-handler"
import { GetRecordByIdQueryHandler } from "./get-record-by-id.query-handler"
import { GetRecordsQueryHandler } from "./get-records.query-handler"
import { GetRollupForeignTablesTablesQueryHandler } from "./get-rollup-foreign-tables.query-handler"
import { GetShareRecordByIdQueryHandler } from "./get-share-record-by-id.query-handler"
import { GetShareRecordsQueryHandler } from "./get-share-records.query-handler"
import { GetShareQueryHandler } from "./get-share.query-handler"
import { GetSpaceByIdQueryHandler } from "./get-space-by-id.query-handler"
Expand All @@ -30,6 +31,7 @@ export const queryHandlers = [
GetTableQueryHandler,
GetRecordsQueryHandler,
GetShareRecordsQueryHandler,
GetShareRecordByIdQueryHandler,
GetRecordByIdQueryHandler,
GetReadableRecordsHandler,
GetAggregatesQueryHandler,
Expand Down
27 changes: 26 additions & 1 deletion packages/share/src/services/share.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { inject, singleton } from "@undb/di"
import { Option, Some, type PaginatedDTO } from "@undb/domain"
import { None, Option, Some, type PaginatedDTO } from "@undb/domain"
import {
RecordIdVO,
TableComositeSpecification,
ViewIdVo,
WithFormIdSpecification,
Expand Down Expand Up @@ -36,6 +37,7 @@ export interface IShareService {
getShareByTarget(target: IShareTarget): Promise<Option<IShareDTO>>
getTableByShare(id: string): Promise<ITableDTO>
getShareRecords(id: string): Promise<PaginatedDTO<IRecordDTO>>
getShareRecordById(id: string, recordId: string): Promise<Option<IRecordDTO>>
}

export const SHARE_SERVICE = Symbol.for("SHARE_SERVICE")
Expand Down Expand Up @@ -135,4 +137,27 @@ export class ShareService implements IShareService {
values: await this.recordsService.populateAttachments({ viewId }, table, records.values),
}
}

async getShareRecordById(id: string, recordId: string): Promise<Option<IRecordDTO>> {
const share = (await this.repo.findOneById(id)).expect("share not found")
const spec = match(share.target.type)
.returnType<TableComositeSpecification>()
.with("form", () => new WithFormIdSpecification(share.target.id))
.with("view", () => new WithViewIdSpecification(share.target.id))
.exhaustive()

const table = (await this.tableRepo.findOne(Some(spec))).expect("table not found")

const record = await this.recordRepo.findOneById(table, new RecordIdVO(recordId), None)
if (record.isNone()) {
return None
}

const r = record.unwrap()
const values = await this.recordsService.populateAttachment({}, table, r.values)
return Some({
...r,
values,
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface IRecordsQueryService {
getReadableRecordById(query: IGetRecordByIdDTO): Promise<Option<IRecordReadableValueDTO>>
getAggregates(query: IGetAggregatesDTO): Promise<Record<string, AggregateResult>>
populateAttachments(dto: IGetRecordsDTO, table: TableDo, records: IRecordDTO[]): Promise<IRecordDTO[]>
populateAttachment(dto: IGetRecordsDTO, table: TableDo, value: IRecordDTO["values"]): Promise<IRecordDTO["values"]>
}

@singleton()
Expand Down
5 changes: 5 additions & 0 deletions packages/trpc/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import {
GetMemberSpacesQuery,
GetRecordByIdQuery,
GetRecordsQuery,
GetShareRecordByIdQuery,
GetShareRecordsQuery,
GetTableQuery,
GetTablesQuery,
Expand All @@ -105,6 +106,7 @@ import {
getMemberSpacesQuery,
getRecordByIdQuery,
getRecordsQuery,
getShareRecordByIdQuery,
getShareRecordsQuery,
getTableQuery,
getWebhooksQuery,
Expand Down Expand Up @@ -318,6 +320,9 @@ const shareDataRouter = t.router({
records: publicProcedure
.input(getShareRecordsQuery)
.query(({ input }) => queryBus.execute(new GetShareRecordsQuery(input))),
record: publicProcedure
.input(getShareRecordByIdQuery)
.query(({ input }) => queryBus.execute(new GetShareRecordByIdQuery(input))),
})

const authzRouter = t.router({
Expand Down

0 comments on commit 0dc8699

Please sign in to comment.