Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create from form badge #1510

Merged
merged 1 commit into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions apps/backend/src/share/adapters/share-sqlite.query-model.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { EntityManager } from '@mikro-orm/better-sqlite'
import type { EntityManager } from '@mikro-orm/better-sqlite'
import { MikroORM, UseRequestContext } from '@mikro-orm/core'
import { Inject, Injectable } from '@nestjs/common'
import { IQueryShare, type ShareSpecification } from '@undb/integrations'
import type { IQueryShare } from '@undb/integrations'
import { type ShareSpecification } from '@undb/integrations'
import { ShareSqliteQueryModel } from '@undb/sqlite'
import { Option } from 'oxide.ts'
import type { Option } from 'oxide.ts'

export const SHARE_QUERY_MODEL = Symbol('SHARE_QUERY_MODEL')
export const InjectShareQueryModel = () => Inject(SHARE_QUERY_MODEL)
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/src/share/adapters/share-sqlite.repository.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { EntityManager } from '@mikro-orm/better-sqlite'
import type { EntityManager } from '@mikro-orm/better-sqlite'
import { MikroORM, UseRequestContext } from '@mikro-orm/core'
import { Inject, Injectable } from '@nestjs/common'
import { type Share, type ShareSpecification } from '@undb/integrations'
import { ShareSqliteRepository } from '@undb/sqlite'
import { Option } from 'oxide.ts'
import type { Option } from 'oxide.ts'

export const SHARE_REPOSITORY = Symbol('SHARE_REPOSITORY')
export const InjectShareRepository = () => Inject(SHARE_REPOSITORY)
Expand Down
19 changes: 7 additions & 12 deletions apps/frontend/src/lib/components/ui/badge/badge.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
<script lang="ts">
import { cn } from "$lib/utils";
import { badgeVariants, type Variant } from ".";
import { cn } from '$lib/utils'
import { badgeVariants, type Variant } from '.'

let className: string | undefined | null = undefined;
export let href: string | undefined = undefined;
export let variant: Variant = "default";
export { className as class };
let className: string | undefined | null = undefined
export let href: string | undefined = undefined
export let variant: Variant = 'default'
export { className as class }
</script>

<svelte:element
this={href ? "a" : "span"}
{href}
class={cn(badgeVariants({ variant, className }))}
{...$$restProps}
>
<svelte:element this={href ? 'a' : 'span'} {href} class={cn(badgeVariants({ variant, className }))} {...$$restProps}>
<slot />
</svelte:element>
26 changes: 23 additions & 3 deletions apps/frontend/src/lib/record/CreateRecord.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,30 @@
import { superForm } from 'sveltekit-superforms/client'
import type { Validation } from 'sveltekit-superforms'
import FieldIcon from '$lib/field/FieldIcon.svelte'
import { slide } from 'svelte/transition'
import { t } from '$lib/i18n'
import { keys } from 'lodash-es'
import { pick } from 'lodash-es'
import * as Dialog from '$lib/components/ui/dialog'
import { Button } from '$lib/components/ui/button'
import { createRecordForm } from '$lib/store/table'
import { Label } from '$components/ui/label'
import Toast from '$components/ui/toast/toast.svelte'
import type { Field } from '@undb/core'
import Badge from '$components/ui/badge/badge.svelte'

const table = getTable()
const view = getView()

export let data: Validation<any>
$: fields = $view.getOrderedFields($table.schema.nonSystemFields)
let fields: Field[] = []

$: {
if ($createRecordForm) {
fields = $createRecordForm.getNotHiddenFields($table.schema)
} else {
fields = $view.getOrderedFields($table.schema.nonSystemFields)
}
}

const createRecord = trpc().record.create.mutation({
async onSuccess(data, variables, context) {
Expand Down Expand Up @@ -57,7 +67,17 @@
<Dialog.Root bind:open={$createRecordModal.open}>
<Dialog.Content class="!w-3/4 max-w-none h-[calc(100vh-64px)] overflow-y-hidden flex flex-col p-0">
<Dialog.Header class="border-b p-6">
<Dialog.Title>{$t('Create New Record')}</Dialog.Title>
<Dialog.Title class="gap-2 items-center flex">
<span>
{$t('Create New Record')}
</span>

{#if $createRecordForm}
<Badge variant="secondary">
{$t('create record by form', { form: ` ${$createRecordForm.name.value} ` })}
</Badge>
{/if}
</Dialog.Title>
</Dialog.Header>

<div class="flex-1 overflow-y-auto p-6">
Expand Down
6 changes: 6 additions & 0 deletions apps/frontend/src/lib/store/modal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { ICreateFieldSchema, RecordValueJSON } from '@undb/core'
import { derived, writable } from 'svelte/store'
import { createRecordFormId } from './table'

export const createRecordInitial = writable<RecordValueJSON | undefined>()
export const createFieldInitial = writable<Partial<ICreateFieldSchema> | undefined>()
Expand Down Expand Up @@ -44,6 +45,11 @@ const createModal = (id: symbol) => {
const CREATE_RECORD = Symbol('CREATE_RECORD')
export const createRecordModal = createModal(CREATE_RECORD)
export const createRecordCallback = derived(createRecordModal, ($modal) => $modal.callback)
createRecordModal.subscribe(({ open }) => {
if (!open) {
createRecordFormId.set(undefined)
}
})

const CREATE_TABLE = Symbol('CREATE_TABLE')
export const createTableModal = createModal(CREATE_TABLE)
Expand Down
5 changes: 5 additions & 0 deletions apps/frontend/src/lib/store/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ export const createRecordStore = (inputs: Records = []) => {

export const recordsStore = createRecordStore()

export const createRecordFormId = writable<string | undefined>(undefined)
export const createRecordForm = derived([currentTable, createRecordFormId], ([$table, $formId]) =>
$formId ? $table.forms.getById($formId).into() : undefined,
)

export const sorts = derived(currentView, (view) => view.sorts?.sorts ?? [])
// TODO: nested should be IFilters
export const filters = derived(currentView, (view) => (view.filter?.group.children ?? []) as IFilters)
Expand Down
63 changes: 57 additions & 6 deletions apps/frontend/src/lib/table/CreateRecordButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,64 @@
import { hasPermission } from '$lib/store/authz'
import { createRecordModal } from '$lib/store/modal'
import { Button } from '$components/ui/button'
import { createRecordFormId, getTable } from '$lib/store/table'
import { cn } from '$lib/utils'
import * as DropdownMenu from '$lib/components/ui/dropdown-menu'

const table = getTable()

$: forms = $table.forms.forms
$: formCount = forms.length
$: hasForm = formCount > 0
</script>

{#if $hasPermission('record:create')}
<Button on:click={() => createRecordModal.open()} size="sm" class="inline-flex items-center whitespace-nowrap">
<i class="ti ti-row-insert-bottom text-sm lg:mr-2" />
<span class="hidden lg:block">
{$t('Create New Record')}
</span>
</Button>
<div class="flex items-center">
<Button
on:click={() => createRecordModal.open()}
size="sm"
class={cn('inline-flex items-center whitespace-nowrap', hasForm && 'rounded-r-none')}
>
<i class="ti ti-row-insert-bottom text-sm lg:mr-2" />
<span class="hidden lg:block">
{$t('Create New Record')}
</span>
</Button>
{#if hasForm}
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild let:builder>
<Button size="sm" class="rounded-l-none items-center justify-center" builders={[builder]}>
<i class="ti ti-chevron-down font-semibold text-[14px]"></i>
</Button>
</DropdownMenu.Trigger>

<DropdownMenu.Content class="z-[9999999999] w-56">
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger class="font-semibold text-xs gap-2">
<i class="ti ti-row-insert-bottom text-sm" />
<span>
{$t('create record by form', { form: '' })}
</span>
</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent class="w-56">
{#each forms as form}
<DropdownMenu.Item
class="font-semibold text-xs gap-2"
on:click={() => {
$createRecordFormId = form.id.value
createRecordModal.open()
}}
>
<i class="ti ti-row-insert-bottom text-sm" />
<span>
{$t('create record by form', { form: ` ${form.name.value} ` })}
</span>
</DropdownMenu.Item>
{/each}
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
</DropdownMenu.Content>
</DropdownMenu.Root>
{/if}
</div>
{/if}
2 changes: 1 addition & 1 deletion apps/frontend/src/routes/(share)/s/f/[formId]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
})
},
})
const { form, enhance, constraints, delayed, submitting, tainted } = superFrm
const { form, enhance, delayed, submitting, tainted } = superFrm

onMount(() => {
$tainted = undefined
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ export const config: InitOptions = {
'field type filter value': 'input {{field}} filter value',
'Search Foreign Records': 'search foreign table records',
'insert refenrence looking field': 'insert looking field',
'create record by form': 'create record by{{form}}',
},
webhook: {
Webhook: 'Webhook',
Expand Down Expand Up @@ -819,6 +820,7 @@ export const config: InitOptions = {
'field type filter value': '输入{{field}}筛选值',
'Search Foreign Records': '搜索关联表记录',
'insert refenrence looking field': '插入关联查看列',
'create record by form': '通过表单{{form}}创建',
},
webhook: {
Webhook: 'Webhook',
Expand Down