Skip to content

Commit

Permalink
feat: update space
Browse files Browse the repository at this point in the history
  • Loading branch information
nichenqin committed Aug 8, 2024
1 parent c6053bf commit 7acd2d7
Show file tree
Hide file tree
Showing 22 changed files with 290 additions and 79 deletions.
4 changes: 2 additions & 2 deletions apps/backend/src/modules/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ export class Auth {
})
.execute()

const space = await this.spaceService.createPersonalSpace()
const space = await this.spaceService.createPersonalSpace(username!)
await this.spaceMemberService.createMember(userId, space.id.value, "owner")

spaceId = space.id.value
Expand Down Expand Up @@ -296,7 +296,7 @@ export class Auth {
let space = await this.spaceService.getSpace({ userId: user.id })
if (space.isSome()) {
} else {
space = Some(await this.spaceService.createPersonalSpace())
space = Some(await this.spaceService.createPersonalSpace(user.username))
await this.spaceMemberService.createMember(user.id, space.unwrap().id.value, "owner")
}
const session = await this.lucia.createSession(user.id, { space_id: space.unwrap().id.value })
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/modules/web/web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class Web {
.get("/s/*", () => index)
.get("/bases/*", () => index)
.get("/account/*", () => index)
.get("/members", () => index)
.get("/settings", () => index)
.get("/login", () => index)
.get("/signup", () => index)
}
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ enum ShareTargetType {
}

type Space {
avatar: String
id: ID!
isPersonal: Boolean!
member: SpaceMember
Expand Down
24 changes: 13 additions & 11 deletions apps/frontend/src/lib/components/blocks/nav/nav-tools.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { Button } from "$lib/components/ui/button"
import { PlusIcon, SearchIcon, Users2Icon } from "lucide-svelte"
import { PlusIcon, SearchIcon, SettingsIcon } from "lucide-svelte"
import { commandOpen } from "../command/command.store"
import { CREATE_BASE_MODAL, toggleModal } from "$lib/store/modal.store"
import { page } from "$app/stores"
Expand Down Expand Up @@ -38,16 +38,18 @@
</span>
</Button>

{#if !space?.isPersonal}
<a
href={`/members`}
data-active={$page.route.id === "/(authed)/members"}
class="hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring data-[active=true]:bg-primary data-[active=true]:text-primary-foreground flex h-8 items-center justify-start gap-2 whitespace-nowrap rounded-md px-3 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50"
>
<Users2Icon class="h-4 w-4" />
Members
</a>
{/if}
<a
href={`/settings`}
data-active={$page.route.id === "/(authed)/settings"}
class="hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring data-[active=true]:bg-primary data-[active=true]:text-primary-foreground flex h-8 items-center justify-start gap-2 whitespace-nowrap rounded-md px-3 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50"
>
<SettingsIcon class="h-4 w-4" />
{#if space?.isPersonal}
Settings
{:else}
Settings & Members
{/if}
</a>

{#if $hasPermission("base:create")}
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
<DropdownMenu.Trigger asChild let:builder>
<button class={$$restProps.class} use:builderActions={{ builders: [builder] }} {...getAttrs([builder])}>
<img src={Logo} alt="" class="h-4 w-4 rounded-full" />
{#if space.isPersonal}
{#if space.isPersonal && !space.name}
{me.username}'s Personal Space
{:else}
{space.name}
Expand Down Expand Up @@ -96,7 +96,7 @@
>
<div class="flex items-center gap-2">
<img src={Logo} alt="" class="h-4 w-4 rounded-full" />
{#if space.isPersonal}
{#if space.isPersonal && !space.name}
{me.username}'s Personal Space
{:else}
{space.name}
Expand Down
64 changes: 64 additions & 0 deletions apps/frontend/src/lib/components/blocks/space/space-setting.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script lang="ts">
import { trpc } from "$lib/trpc/client"
import { createMutation } from "@tanstack/svelte-query"
import { updateSpaceCommand } from "@undb/commands"
import { zodClient } from "sveltekit-superforms/adapters"
import SuperDebug, { defaults, superForm } from "sveltekit-superforms"
import { browser } from "$app/environment"
import * as Form from "$lib/components/ui/form/index.js"
import { Input } from "$lib/components/ui/input/index.js"
import type { ISpaceDTO } from "@undb/space"
import { toast } from "svelte-sonner"
export let space: ISpaceDTO
const form = superForm(
defaults(
{
name: space.name,
},
zodClient(updateSpaceCommand),
),
{
SPA: true,
dataType: "json",
validators: zodClient(updateSpaceCommand),
resetForm: false,
invalidateAll: true,
onUpdate(event) {
if (!event.form.valid) {
return
}
$updateSpaceMutation.mutate(event.form.data)
},
},
)
const updateSpaceMutation = createMutation({
mutationFn: trpc.space.update.mutate,
onSuccess() {
toast.success("Space updated successfully")
},
})
const { form: formData, enhance } = form
</script>

<section class="mx-auto">
<form method="POST" class="w-2/3 space-y-4" use:enhance>
<Form.Field {form} name="name">
<Form.Control let:attrs>
<Form.Label>Space name</Form.Label>
<Input {...attrs} placeholder="Set space display name..." bind:value={$formData.name} />
</Form.Control>
<Form.Description>Change space display name.</Form.Description>
<Form.FieldErrors />
</Form.Field>

<Form.Button>Update</Form.Button>
{#if browser}
<!-- <SuperDebug data={$formData} /> -->
{/if}
</form>
</section>
1 change: 1 addition & 0 deletions apps/frontend/src/routes/(authed)/+layout.gql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ query GetIndexQuery {
id
name
isPersonal
avatar
}

tables {
Expand Down
54 changes: 0 additions & 54 deletions apps/frontend/src/routes/(authed)/members/+page.svelte

This file was deleted.

79 changes: 79 additions & 0 deletions apps/frontend/src/routes/(authed)/settings/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<script lang="ts">
import * as Tabs from "$lib/components/ui/tabs"
import InviteButton from "$lib/components/blocks/invite/invite-button.svelte"
import MembersTable from "$lib/components/blocks/member/members-table.svelte"
import { Input } from "$lib/components/ui/input"
import { SettingsIcon, Users, UsersIcon } from "lucide-svelte"
import type { LayoutData } from "./$types"
import { queryParam } from "sveltekit-search-params"
import InvitationsListButton from "$lib/components/blocks/invitations/invitations-list-button.svelte"
import { hasPermission } from "$lib/store/workspace-member.store"
import { onMount } from "svelte"
import { goto } from "$app/navigation"
import SpaceSetting from "$lib/components/blocks/space/space-setting.svelte"
const mq = queryParam("mq")
export let data: LayoutData
$: getMembersStore = data.getMembersStore
$: members = $getMembersStore.data?.members ?? []
function fetchMembers() {
getMembersStore.fetch({ variables: { q: $mq } })
}
$: store = data.indexDataStore
$: space = $store.data?.space
onMount(async () => {
if ($store.data?.space?.isPersonal) {
await goto("/", { replaceState: true })
}
})
</script>

<main class="space-y-2 p-6">
<div class="space-y-2">
<h3 class="flex items-center text-xl">
<SettingsIcon class="mr-2 h-4 w-4" />
Settings
</h3>
</div>

<Tabs.Root value="members" class="w-full">
<Tabs.List>
<Tabs.Trigger value="members">
<UsersIcon class="mr-2 h-4 w-4" />
Members
</Tabs.Trigger>
<Tabs.Trigger value="settings">
<SettingsIcon class="mr-2 h-4 w-4" />
Settings
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="members" class="space-y-2">
<div class="flex justify-between">
<h4 class="flex items-center">
<Users class="mr-2 h-4 w-4" />
Members
</h4>
<div class="flex items-center gap-2">
{#if $hasPermission("authz:invite")}
<InviteButton />
{/if}
{#if $hasPermission("authz:listInvitation")}
<InvitationsListButton />
{/if}
</div>
</div>

<Input bind:value={$mq} on:change={fetchMembers} placeholder="Search Members..." class="max-w-xs" />
<MembersTable {members} />
</Tabs.Content>
<Tabs.Content value="settings">
{#if space}
<SpaceSetting {space} />
{/if}
</Tabs.Content>
</Tabs.Root>
</main>
2 changes: 2 additions & 0 deletions packages/command-handlers/src/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { SetViewSortCommandHandler } from "./set-view-sort.command-handler"
import { UpdateAccountCommandHandler } from "./update-account.command-handler"
import { UpdateBaseCommandHandler } from "./update-base.command-handler"
import { UpdateRecordCommandHandler } from "./update-record.command-handler"
import { UpdateSpaceCommandHandler } from "./update-space.command-handler"
import { UpdateTableFieldCommandHandler } from "./update-table-field.command-handler"
import { UpdateTableCommandHandler } from "./update-table.command-handler"
import { UpdateViewCommandHandler } from "./update-view.command-handler"
Expand Down Expand Up @@ -82,4 +83,5 @@ export const commandHandlers = [
DeleteTableCommandHandler,
CreateApiTokenCommandHandler,
CreateSpaceCommandHandler,
UpdateSpaceCommandHandler,
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { UpdateSpaceCommand } 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 { injectSpaceRepository, type ISpaceRepository } from "@undb/space"

@commandHandler(UpdateSpaceCommand)
@singleton()
export class UpdateSpaceCommandHandler implements ICommandHandler<UpdateSpaceCommand, any> {
constructor(
@injectSpaceRepository()
private readonly repository: ISpaceRepository,
) {}

async execute(command: UpdateSpaceCommand): Promise<any> {
const spaceId = mustGetCurrentSpaceId()
const space = (await this.repository.findOneById(spaceId)).expect("Space not found")

const spec = space.$update(command)

if (spec.isSome()) {
await this.repository.updateOneById(space, spec.unwrap())
}

return space.id.value
}
}
1 change: 1 addition & 0 deletions packages/commands/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export * from "./set-view-sort.command"
export * from "./update-account.command"
export * from "./update-base.command"
export * from "./update-record.command"
export * from "./update-space.command"
export * from "./update-table-field.command"
export * from "./update-table.command"
export * from "./update-view.command"
Expand Down
16 changes: 16 additions & 0 deletions packages/commands/src/update-space.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Command, type CommandProps } from "@undb/domain"
import { updateSpaceDTO } from "@undb/space"
import { z } from "@undb/zod"

export const updateSpaceCommand = updateSpaceDTO

export type IUpdateSpaceCommand = z.infer<typeof updateSpaceCommand>

export class UpdateSpaceCommand extends Command implements IUpdateSpaceCommand {
public readonly name: string

constructor(props: CommandProps<IUpdateSpaceCommand>) {
super(props)
this.name = props.name
}
}
2 changes: 2 additions & 0 deletions packages/graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export class Graphql {
id: ID!
name: String!
isPersonal: Boolean!
avatar: String
member: SpaceMember
}
Expand Down Expand Up @@ -293,6 +294,7 @@ export class Graphql {
}

const space = (await this.queryBus.execute(new GetSpaceByIdQuery({ id: spaceId }))) as Option<ISpaceDTO>

if (space.isNone()) {
return null
}
Expand Down
Loading

0 comments on commit 7acd2d7

Please sign in to comment.