keystone icon indicating copy to clipboard operation
keystone copied to clipboard

`document` filed not support rich text using `text` type in database?

Open toknT opened this issue 2 years ago • 1 comments

I am using text type store rich text in db,This is the exist prisma.schema in another project(Article.body is the column to store rich text)

model Category {
  id       Int       @id @default(autoincrement())
  title    String
  articles Article[]
}

model Article {
  id         Int      @id @default(autoincrement())
  category   Category @relation(fields: [categoryId], references: [id])
  categoryId Int
  createdAt  DateTime @default(now())
  updatedAt  DateTime @default(now())
  isDeleted  Boolean  @default(false)
  orgLink    String   @default("")
  thumbnail  String
  title      String
  body       String   @db.Text
  overview   String   @default("")
}

And this is generate by prisma.ts in keystone

model Category {
  id       Int       @id @default(autoincrement())
  title    String    @default("")
  articles Article[] @relation("Article_category")
}

model Article {
  id         Int       @id @default(autoincrement())
  category   Category? @relation("Article_category", fields: [categoryId], references: [id])
  categoryId Int?      @map("category")
  createdAt  DateTime? @default(now())
  updatedAt  DateTime? @default(now())
  isDeleted  Boolean   @default(false)
  orgLink    String    @default("")
  thumbnail  String    @default("")
  title      String    @default("")
  body       Json      @default("[{\"type\":\"paragraph\",\"children\":[{\"text\":\"\"}]}]")
  overview   String    @default("")

  @@index([categoryId])
}

and the schema.ts

export const lists: Lists = {
  Category: list({
    access: allowAll,
    fields: {
      title: text(),
      articles: relationship({
        ref: "Article.category",
        many: true,
      }),
    },
  }),
  Article: list({
    access: allowAll,
    fields: {
      category: relationship({
        ref: "Category.articles",
        many: false,
      }),
      createdAt: timestamp({
        defaultValue: { kind: "now" },
      }),
      updatedAt: timestamp({
        defaultValue: { kind: "now" },
      }),
      isDeleted: checkbox({ defaultValue: false }),
      orgLink: text({ defaultValue: "" }),
      thumbnail: text(),
      title: text(),
      body: document(),
      overview: text(),
    },
  }),
  Admin: list({
    access: allowAll,
    fields: {
      name: text({ validation: { isRequired: true } }),
      email: text({
        validation: { isRequired: true },
        isIndexed: "unique",
      }),
      password: password({ validation: { isRequired: true } }),
      createdAt: timestamp({
        defaultValue: { kind: "now" },
      }),
    },
  }),
};

toknT avatar Aug 14 '23 06:08 toknT

Current I create a custom field like this(read the code and keystone 5 's doc) to solve it, But it has a bug rich text body is empty when creating it only work when updating

import React from 'react';
import { FieldProps } from '@keystone-6/core/types';
import { FieldContainer, FieldLabel } from '@keystone-ui/fields';
import { controller } from '@keystone-6/core/fields/types/json/views';
import { useState } from 'react';
import { Editor } from '@tinymce/tinymce-react';
import { TINYMCE_API_KEY } from './config';

export const Field = ({ field, value, onChange, autoFocus }: FieldProps<typeof controller>) => {

  const onEditorChange = (html: string) => {
    if (onChange) {
      let keystonOnChangeValue = value;
      keystonOnChangeValue.inner.value = html;
      onChange(keystonOnChangeValue);
      setHtmlValue(html);
    }
  };
  const apiKey = TINYMCE_API_KEY;

  const [htmlValue, setHtmlValue] = useState(value.inner.value);
  return (
    <FieldContainer>
      <FieldLabel>{field.label}</FieldLabel>
      <Editor
        apiKey={apiKey}
        plugins="wordcount image link"
        value={htmlValue}
        onEditorChange={(html) => {
          onEditorChange(html);
        }}
      />
    </FieldContainer>
  );
};

toknT avatar Sep 12 '23 08:09 toknT