Skip to content

Commit

Permalink
feat: long text field
Browse files Browse the repository at this point in the history
  • Loading branch information
nichenqin committed Aug 21, 2024
1 parent e84d77c commit 6e41355
Show file tree
Hide file tree
Showing 41 changed files with 450 additions and 3 deletions.
1 change: 1 addition & 0 deletions apps/frontend/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum FieldType {
email
id
json
longText
number
rating
reference
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import CheckboxControl from "./checkbox-control.svelte"
import UrlControl from "./url-control.svelte"
import RollupField from "../field-value/rollup-field.svelte"
import LongTextControl from "./long-text-control.svelte"
export let readonly = false
export let field: NoneSystemField
Expand All @@ -34,6 +35,7 @@
const map: Record<NoneSystemFieldType, ComponentType> = {
string: StringControl,
longText: LongTextControl,
number: NumberControl,
reference: ReferenceControl,
rollup: RollupField,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script lang="ts">
import Textarea from "$lib/components/ui/textarea/textarea.svelte"
export let value: string
export let readonly = false
</script>

<Textarea rows={5} bind:value {...$$restProps} on:change disabled={readonly} />
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
ListChecksIcon,
ListTodoIcon,
LinkIcon,
FolderIcon,
} from "lucide-svelte"
export let type: FieldType
export let field: Field | undefined = undefined
const map: Record<FieldType, ComponentType> = {
id: KeyRoundIcon,
longText: FileTextIcon,
string: StringIcon,
number: NumberIcon,
autoIncrement: ArrowDown01Icon,
Expand All @@ -43,7 +45,7 @@
rating: StarIcon,
email: MailIcon,
url: LinkIcon,
attachment: FileTextIcon,
attachment: FolderIcon,
date: CalendarIcon,
json: FileJsonIcon,
checkbox: SquareCheckIcon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import JsonFieldOption from "./json-field-option.svelte"
import DateFieldOption from "./date-field-option.svelte"
import UrlFieldOption from "./url-field-option.svelte"
import LongTextFieldOption from "./long-text-field-option.svelte"
export let constraint: IFieldConstraint | undefined
export let option: any | undefined
Expand All @@ -24,6 +25,7 @@
const map: Record<NoneSystemFieldType, ComponentType> = {
string: StringFieldOption,
longText: LongTextFieldOption,
number: NumberFieldOption,
reference: ReferenceFieldOption,
rollup: RollupFieldOption,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<script lang="ts">
import Checkbox from "$lib/components/ui/checkbox/checkbox.svelte"
import Input from "$lib/components/ui/input/input.svelte"
import { Label } from "$lib/components/ui/label/index.js"
import Separator from "$lib/components/ui/separator/separator.svelte"
import * as Alert from "$lib/components/ui/alert/index.js"
import { StringFieldConstraint, type ILongTextFieldConstraint, type IStringFieldConstraint } from "@undb/table"
export let constraint: ILongTextFieldConstraint | undefined
export let defaultValue: string | undefined
$: c = constraint ? new StringFieldConstraint(constraint) : undefined
$: isDefaultValueValid = c && defaultValue ? c.schema.safeParse(defaultValue).success : true
</script>

<div class="space-y-2">
<div class="space-y-1">
<Label for="defaultValue" class="text-xs font-normal">Default value</Label>
<Input
id="defaultValue"
class="bg-background flex-1 text-xs"
placeholder="Default value..."
bind:value={defaultValue}
/>
</div>
{#if !isDefaultValueValid}
<Alert.Root class="mt-2 border-yellow-500 bg-yellow-50">
<Alert.Title>Invalid default value</Alert.Title>
<Alert.Description>Your default value is invalid. Default value will not be saved.</Alert.Description>
</Alert.Root>
{/if}
{#if constraint}
<div class="pt-2">
<Separator />
</div>
<div class="flex items-center space-x-2">
<Checkbox id="required" bind:checked={constraint.required} />
<Label for="required" class="text-xs font-normal">Mark as required field.</Label>
</div>
{/if}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import JsonField from "./json-field.svelte"
import CheckboxField from "./checkbox-field.svelte"
import UrlField from "./url-field.svelte"
import LongTextField from "./long-text-field.svelte"
export let type: FieldType
export let value: any
Expand All @@ -26,6 +27,7 @@
const map: Record<FieldType, ComponentType> = {
id: IdField,
string: StringField,
longText: LongTextField,
number: NumberField,
createdAt: DateField,
updatedAt: DateField,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts">
export let value: string | undefined = undefined
export let placeholder: string | undefined = undefined
</script>

{#if !value}
<div>
{placeholder || ""}
</div>
{:else}
<div class={$$restProps.class}>{value}</div>
{/if}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script lang="ts">
import { trpc } from "$lib/trpc/client"
import { cn } from "$lib/utils"
import { createMutation } from "@tanstack/svelte-query"
import type { LongTextField, StringField } from "@undb/table"
import { toast } from "svelte-sonner"
import { gridViewStore } from "../grid-view.store"
export let tableId: string
export let field: LongTextField
export let value: string
export let recordId: string
export let isEditing: boolean
export let readonly: boolean
export let onValueChange: (value: string) => void
const updateCell = createMutation({
mutationKey: ["record", tableId, field.id.value, recordId],
mutationFn: trpc.record.update.mutate,
onSuccess(data, variables, context) {
el?.blur()
gridViewStore.exitEditing()
onValueChange(value)
},
onError(error: Error) {
toast.error(error.message)
},
})
let el: HTMLTextAreaElement
$: if (isEditing) {
if (el) {
el.focus()
}
}
</script>

{#if isEditing}
<div class="absolute -bottom-10 left-0 right-0 top-0">
<textarea
rows={3}
bind:this={el}
bind:value
on:blur={() => {
gridViewStore.exitEditing()
}}
class={cn(
$$restProps.class,
"focus-visible:ring-ring h-full w-full rounded-none border px-2 text-xs outline-none focus:bg-white",
)}
on:change={() => {
$updateCell.mutate({
tableId,
id: recordId,
values: { [field.id.value]: value },
})
}}
/>
</div>
{:else}
<div class={cn("truncate", $$restProps.class)}>
{#if value}
{value}
{/if}
</div>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import { recordsStore } from "$lib/store/records.store"
import UrlCell from "./editable-cell/url-cell.svelte"
import RollupCell from "./editable-cell/rollup-cell.svelte"
import LongTextCell from "./editable-cell/long-text-cell.svelte"
const table = getTable()
Expand All @@ -38,6 +39,7 @@
const map: Record<FieldType, ComponentType> = {
string: StringCell,
longText: LongTextCell,
number: NumberCell,
id: IdField,
createdAt: DateField,
Expand Down Expand Up @@ -71,7 +73,7 @@
readonly={field.isSystem || readonly}
tableId={$table.id.value}
class={cn(
"flex h-8 items-center border border-transparent px-2 py-1 text-xs",
"relative flex h-8 items-center border border-transparent px-2 py-1 text-xs",
(isSelected || isEditing) && "border-primary",
)}
onValueChange={(v) => {
Expand Down
1 change: 1 addition & 0 deletions packages/graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export class Graphql {
enum FieldType {
string
longText
number
rating
email
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/i18n/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const ops: Record<IOpType, string> = {

const fieldTypes: Record<FieldType, string> = {
string: "String",
longText: "Long Text",
number: "Number",
date: "Date",
id: "ID",
Expand Down
8 changes: 8 additions & 0 deletions packages/i18n/src/i18n/i18n-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ type RootTranslation = {
* S​t​r​i​n​g
*/
string: string
/**
* L​o​n​g​ ​T​e​x​t
*/
longText: string
/**
* N​u​m​b​e​r
*/
Expand Down Expand Up @@ -516,6 +520,10 @@ export type TranslationFunctions = {
* String
*/
string: () => LocalizedString
/**
* Long Text
*/
longText: () => LocalizedString
/**
* Number
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
DateField,
ID_TYPE,
JsonField,
LongTextField,
UrlField,
UserField,
type AttachmentField,
Expand Down Expand Up @@ -76,6 +77,7 @@ export class RecordQueryCreatorVisitor implements IFieldVisitor {
date(field: DateField): void {}
attachment(field: AttachmentField): void {}
json(field: JsonField): void {}
longText(field: LongTextField): void {}
user(field: UserField): void {
if (field.isMultiple) {
const usersTable = getTableName(users)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
ID_TYPE,
JsonContains,
LongTextEqual,
UrlEqual,
type AttachmentEmpty,
type AttachmentEqual,
Expand Down Expand Up @@ -61,6 +62,7 @@ export class RecordQuerySpecCreatorVisitor implements IRecordVisitor {
return this.#creator || this.qb
}

longTextEqual(s: LongTextEqual): void {}
stringEqual(spec: StringEqual): void {}
stringContains(spec: StringContains): void {}
stringStartsWith(spec: StringStartsWith): void {}
Expand Down
4 changes: 4 additions & 0 deletions packages/persistence/src/record/record-reference-visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
DateField,
ID_TYPE,
JsonField,
LongTextField,
RatingField,
SelectField,
UrlField,
Expand Down Expand Up @@ -63,6 +64,9 @@ export class RecordReferenceVisitor implements IFieldVisitor {
string(field: StringField): void {
throw new Error("Method not implemented.")
}
longText(field: LongTextField): void {
throw new Error("Method not implemented.")
}
number(field: NumberField): void {
throw new Error("Method not implemented.")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
DateField,
ID_TYPE,
JsonField,
LongTextField,
RatingField,
SelectField,
UrlField,
Expand Down Expand Up @@ -82,6 +83,10 @@ export class RecordSelectFieldVisitor implements IFieldVisitor {
this.addSelect(this.getField(field.id.value))
}

longText(field: LongTextField): void {
this.addSelect(this.getField(field.id.value))
}

id(field: IdField): void {
// this.addSelect(this.getField(field.id.value))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
JsonContains,
JsonEmpty,
JsonEqual,
LongTextEqual,
NumberEmpty,
NumberEqual,
NumberGT,
Expand Down Expand Up @@ -53,6 +54,7 @@ export class RecordSpecReferenceVisitor implements IRecordVisitor {
}

stringEqual(spec: StringEqual): void {}
longTextEqual(spec: LongTextEqual): void {}
stringContains(spec: StringContains): void {}
stringStartsWith(spec: StringStartsWith): void {}
stringEndsWith(spec: StringEndsWith): void {}
Expand Down
5 changes: 5 additions & 0 deletions packages/persistence/src/record/record.filter-visitor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NotImplementException } from "@undb/domain"
import {
JsonContains,
LongTextEqual,
SelectField,
UrlEqual,
type AttachmentEmpty,
Expand Down Expand Up @@ -73,6 +74,10 @@ export class RecordFilterVisitor extends AbstractQBVisitor<RecordDO> implements
const cond = this.eb.eb(this.getFieldId(spec), "=", spec.value)
this.addCond(cond)
}
longTextEqual(spec: LongTextEqual): void {
const cond = this.eb.eb(this.getFieldId(spec), "=", spec.value)
this.addCond(cond)
}
jsonEqual(spec: JsonEqual): void {
const json = isString(spec.json) ? spec.json : JSON.stringify(spec.json)
const cond = this.eb.eb(this.getFieldId(spec), "=", json)
Expand Down
4 changes: 4 additions & 0 deletions packages/persistence/src/record/record.mutate-visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { ISpecification, ISpecVisitor } from "@undb/domain"
import {
ID_TYPE,
JsonContains,
LongTextEqual,
SelectContainsAnyOf,
SelectField,
SelectFieldValue,
Expand Down Expand Up @@ -137,6 +138,9 @@ export class RecordMutateVisitor extends AbstractQBMutationVisitor implements IR
}
}
}
longTextEqual(s: LongTextEqual): void {
this.setData(s.fieldId.value, s.value)
}
attachmentEmpty(s: AttachmentEmpty): void {
this.setData(s.fieldId.value, null)
const deleteSql = (this.qb as IQueryBuilder)
Expand Down
Loading

0 comments on commit 6e41355

Please sign in to comment.