-
-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1891 from undb-io/release/v1.0.0-17
Release version v1.0.0-17
- Loading branch information
Showing
18 changed files
with
364 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
apps/frontend/src/routes/(template)/create-from-template/[spaceId]/[baseId]/+layout.gql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
query GetCreateFromTemplateData($spaceId: ID!, $baseId: ID!) { | ||
space { | ||
id | ||
name | ||
} | ||
|
||
template(spaceId: $spaceId, baseId: $baseId) { | ||
name | ||
} | ||
|
||
spaces { | ||
id | ||
name | ||
isPersonal | ||
member { | ||
role | ||
} | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
apps/frontend/src/routes/(template)/create-from-template/[spaceId]/[baseId]/+layout.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<main class="flex h-screen w-screen items-center justify-center"> | ||
<slot /> | ||
</main> |
20 changes: 20 additions & 0 deletions
20
apps/frontend/src/routes/(template)/create-from-template/[spaceId]/[baseId]/+layout.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { GetCreateFromTemplateDataStore } from "$houdini" | ||
import type { LayoutLoad } from "./$types" | ||
|
||
export const ssr = false | ||
export const prerender = "auto" | ||
|
||
export const load: LayoutLoad = async (event) => { | ||
const { spaceId, baseId } = event.params | ||
|
||
const store = new GetCreateFromTemplateDataStore() | ||
|
||
await store.fetch({ | ||
event, | ||
variables: { spaceId, baseId }, | ||
}) | ||
|
||
return { | ||
store, | ||
} | ||
} |
150 changes: 150 additions & 0 deletions
150
apps/frontend/src/routes/(template)/create-from-template/[spaceId]/[baseId]/+page.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
<script lang="ts"> | ||
import { goto } from "$app/navigation" | ||
import * as Card from "$lib/components/ui/card/index.js" | ||
import { Input } from "$lib/components/ui/input/index.js" | ||
import Logo from "$lib/images/logo.svg" | ||
import { createMutation } from "@tanstack/svelte-query" | ||
import { defaults, superForm } from "sveltekit-superforms" | ||
import { zodClient } from "sveltekit-superforms/adapters" | ||
import * as Form from "$lib/components/ui/form" | ||
import * as Alert from "$lib/components/ui/alert/index.js" | ||
import { LoaderCircleIcon, SirenIcon, Store } from "lucide-svelte" | ||
import { createFromTemplateCommand } from "@undb/commands" | ||
import { Checkbox } from "$lib/components/ui/checkbox" | ||
import { trpc } from "$lib/trpc/client" | ||
import { page } from "$app/stores" | ||
import type { PageData } from "./$types" | ||
import * as Select from "$lib/components/ui/select/index.js" | ||
export let data: PageData | ||
let { spaceId, baseId } = $page.params | ||
let store = data.store | ||
let spaces = $store.data?.spaces ?? [] | ||
let space = $store.data?.space | ||
let template = $store.data?.template | ||
const createFromTemplateMutation = createMutation({ | ||
mutationFn: trpc.base.createFromTemplate.mutate, | ||
async onSuccess(data, variables, context) { | ||
await goto(`/bases/${data}`) | ||
}, | ||
}) | ||
const form = superForm( | ||
defaults( | ||
{ | ||
spaceId, | ||
baseId, | ||
targetSpaceId: space?.id, | ||
name: template?.name, | ||
includeData: true, | ||
}, | ||
zodClient(createFromTemplateCommand), | ||
), | ||
{ | ||
SPA: true, | ||
dataType: "json", | ||
validators: zodClient(createFromTemplateCommand), | ||
resetForm: false, | ||
invalidateAll: false, | ||
async onUpdate(event) { | ||
if (!event.form.valid) { | ||
console.log(event.form.errors) | ||
return | ||
} | ||
await $createFromTemplateMutation.mutateAsync(event.form.data) | ||
}, | ||
}, | ||
) | ||
const { enhance, form: formData } = form | ||
$: selectedSpace = $formData.targetSpaceId | ||
? { | ||
label: spaces.find((space) => space?.id === $formData.targetSpaceId)?.name, | ||
value: $formData.targetSpaceId, | ||
} | ||
: undefined | ||
</script> | ||
|
||
<section class="w-[450px] -translate-y-20 space-y-5"> | ||
<div class="flex justify-center"> | ||
<img src={Logo} alt="undb" class="h-12 w-12" /> | ||
</div> | ||
|
||
<form method="POST" use:enhance> | ||
<Card.Root class="mx-auto"> | ||
<Card.Header> | ||
<Card.Title class="text-2xl">Create from template</Card.Title> | ||
<Card.Description>Create a new base from a template.</Card.Description> | ||
</Card.Header> | ||
<Card.Content> | ||
<div class="grid gap-2"> | ||
<div class="grid gap-2"> | ||
<Form.Field {form} name="name"> | ||
<Form.Control let:attrs> | ||
<Form.Label for="name">Name</Form.Label> | ||
<Input {...attrs} id="name" type="name" placeholder="Enter new base name" bind:value={$formData.name} /> | ||
</Form.Control> | ||
<Form.Description /> | ||
<Form.FieldErrors /> | ||
</Form.Field> | ||
</div> | ||
<Form.Field {form} name="targetSpaceId"> | ||
<Form.Control let:attrs> | ||
<Form.Label>Space</Form.Label> | ||
<Select.Root | ||
selected={selectedSpace} | ||
onSelectedChange={(v) => { | ||
v && ($formData.targetSpaceId = v.value) | ||
}} | ||
> | ||
<Select.Trigger {...attrs}> | ||
<Select.Value placeholder="Select a space" /> | ||
</Select.Trigger> | ||
<Select.Content> | ||
{#each spaces as space} | ||
<Select.Item value={space?.id} label={space?.name} /> | ||
{/each} | ||
</Select.Content> | ||
</Select.Root> | ||
<input hidden bind:value={$formData.targetSpaceId} name={attrs.name} /> | ||
</Form.Control> | ||
<Form.Description>Select a space to create the new base in.</Form.Description> | ||
<Form.FieldErrors /> | ||
</Form.Field> | ||
|
||
<Form.Field | ||
{form} | ||
name="includeData" | ||
class="flex flex-row items-start space-x-3 space-y-0 rounded-md border p-4" | ||
> | ||
<Form.Control let:attrs> | ||
<Checkbox {...attrs} bind:checked={$formData.includeData} /> | ||
<div class="space-y-1 leading-none"> | ||
<Form.Label>Include data</Form.Label> | ||
<Form.Description>Include data in the new base.</Form.Description> | ||
</div> | ||
<input name={attrs.name} value={$formData.includeData} hidden /> | ||
</Form.Control> | ||
</Form.Field> | ||
|
||
<Alert.Root> | ||
<Alert.Description class="flex items-center text-xs"> | ||
<SirenIcon class="mr-2 h-4 w-4" /> | ||
System fields will be updated to the current user and timestamp. | ||
</Alert.Description> | ||
</Alert.Root> | ||
<Form.Button type="submit" class="w-full" disabled={$createFromTemplateMutation.isPending}> | ||
{#if $createFromTemplateMutation.isPending} | ||
<LoaderCircleIcon class="mr-2 h-5 w-5 animate-spin" /> | ||
{/if} | ||
Create | ||
</Form.Button> | ||
</div> | ||
</Card.Content> | ||
</Card.Root> | ||
</form> | ||
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
packages/command-handlers/src/handlers/create-from-template.command-handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { BaseId, injectBaseRepository, WithBaseId, WithBaseSpaceId, type IBaseRepository } from "@undb/base" | ||
import { CreateFromTemplateCommand } from "@undb/commands" | ||
import { mustGetCurrentSpaceId } from "@undb/context/server" | ||
import { commandHandler } from "@undb/cqrs" | ||
import { singleton } from "@undb/di" | ||
import { type ICommandHandler } from "@undb/domain" | ||
import { createLogger } from "@undb/logger" | ||
import { injectTableService, type ITableService } from "@undb/table" | ||
|
||
@commandHandler(CreateFromTemplateCommand) | ||
@singleton() | ||
export class CreateFromTemplateCommandHandler implements ICommandHandler<CreateFromTemplateCommand, any> { | ||
private readonly logger = createLogger(CreateFromTemplateCommandHandler.name) | ||
|
||
constructor( | ||
@injectBaseRepository() | ||
private readonly baseRepository: IBaseRepository, | ||
@injectTableService() | ||
private readonly tableService: ITableService, | ||
) {} | ||
|
||
async execute(command: CreateFromTemplateCommand): Promise<any> { | ||
const spec = new WithBaseId(new BaseId(command.baseId)).and(new WithBaseSpaceId(command.spaceId)) | ||
const base = (await this.baseRepository.findOne(spec)).expect("Base not found") | ||
|
||
const targetSpaceId = command.targetSpaceId ?? mustGetCurrentSpaceId() | ||
const duplicatedBase = await this.tableService.duplicateBase(base, targetSpaceId, { | ||
id: command.baseId, | ||
name: command.name, | ||
includeData: command.includeData, | ||
}) | ||
|
||
return duplicatedBase.id.value | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { baseIdSchema } from "@undb/base" | ||
import { Command, type CommandProps } from "@undb/domain" | ||
import { spaceIdSchema } from "@undb/space" | ||
import { z } from "@undb/zod" | ||
|
||
export const createFromTemplateCommand = z.object({ | ||
spaceId: spaceIdSchema, | ||
baseId: baseIdSchema, | ||
targetSpaceId: spaceIdSchema.optional(), | ||
name: z.string().optional(), | ||
includeData: z.boolean().optional(), | ||
}) | ||
|
||
export type ICreateFromTemplateCommand = z.infer<typeof createFromTemplateCommand> | ||
|
||
export class CreateFromTemplateCommand extends Command implements ICreateFromTemplateCommand { | ||
public readonly spaceId: string | ||
public readonly baseId: string | ||
public readonly targetSpaceId?: string | ||
public readonly name?: string | ||
public readonly includeData?: boolean | ||
|
||
constructor(props: CommandProps<ICreateFromTemplateCommand>) { | ||
super(props) | ||
this.spaceId = props.spaceId | ||
this.baseId = props.baseId | ||
this.targetSpaceId = props.targetSpaceId | ||
this.name = props.name | ||
this.includeData = props.includeData | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.