Move collection description rendering to JSON (#6944)
* First pass, moving collection description rendering to JSON * tsc * docs * refactor * test
This commit is contained in:
@@ -32,7 +32,7 @@ import {
|
||||
BeforeDestroy,
|
||||
} from "sequelize-typescript";
|
||||
import isUUID from "validator/lib/isUUID";
|
||||
import type { CollectionSort } from "@shared/types";
|
||||
import type { CollectionSort, ProsemirrorData } from "@shared/types";
|
||||
import { CollectionPermission, NavigationNode } from "@shared/types";
|
||||
import { UrlHelper } from "@shared/utils/UrlHelper";
|
||||
import { sortNavigationNodes } from "@shared/utils/collections";
|
||||
@@ -49,6 +49,7 @@ import User from "./User";
|
||||
import UserMembership from "./UserMembership";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
import { DocumentHelper } from "./helpers/DocumentHelper";
|
||||
import IsHexColor from "./validators/IsHexColor";
|
||||
import Length from "./validators/Length";
|
||||
import NotContainsUrl from "./validators/NotContainsUrl";
|
||||
@@ -163,6 +164,12 @@ class Collection extends ParanoidModel<
|
||||
@Column
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* The content of the collection as Markdown.
|
||||
*
|
||||
* @deprecated Use `content` instead, or `DocumentHelper.toMarkdown` if exporting lossy markdown.
|
||||
* This column will be removed in a future migration.
|
||||
*/
|
||||
@Length({
|
||||
max: CollectionValidation.maxDescriptionLength,
|
||||
msg: `description must be ${CollectionValidation.maxDescriptionLength} characters or less`,
|
||||
@@ -170,6 +177,12 @@ class Collection extends ParanoidModel<
|
||||
@Column
|
||||
description: string | null;
|
||||
|
||||
/**
|
||||
* The content of the collection as JSON, this is a snapshot at the last time the state was saved.
|
||||
*/
|
||||
@Column(DataType.JSONB)
|
||||
content: ProsemirrorData | null;
|
||||
|
||||
@Length({
|
||||
max: 50,
|
||||
msg: `icon must be 50 characters or less`,
|
||||
@@ -260,6 +273,10 @@ class Collection extends ParanoidModel<
|
||||
if (model.icon === "collection") {
|
||||
model.icon = null;
|
||||
}
|
||||
|
||||
if (!model.content) {
|
||||
model.content = await DocumentHelper.toJSON(model);
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeDestroy
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ProsemirrorData } from "@shared/types";
|
||||
import { parser, serializer, schema } from "@server/editor";
|
||||
import { addTags } from "@server/logging/tracer";
|
||||
import { trace } from "@server/logging/tracing";
|
||||
import { Document, Revision } from "@server/models";
|
||||
import { Collection, Document, Revision } from "@server/models";
|
||||
import diff from "@server/utils/diff";
|
||||
import { ProsemirrorHelper } from "./ProsemirrorHelper";
|
||||
import { TextHelper } from "./TextHelper";
|
||||
@@ -43,7 +43,7 @@ export class DocumentHelper {
|
||||
* @param document The document or revision to convert
|
||||
* @returns The document content as a Prosemirror Node
|
||||
*/
|
||||
static toProsemirror(document: Document | Revision) {
|
||||
static toProsemirror(document: Document | Revision | Collection) {
|
||||
if ("content" in document && document.content) {
|
||||
return Node.fromJSON(schema, document.content);
|
||||
}
|
||||
@@ -52,7 +52,10 @@ export class DocumentHelper {
|
||||
Y.applyUpdate(ydoc, document.state);
|
||||
return Node.fromJSON(schema, yDocToProsemirrorJSON(ydoc, "default"));
|
||||
}
|
||||
return parser.parse(document.text) || Node.fromJSON(schema, {});
|
||||
|
||||
const text =
|
||||
document instanceof Collection ? document.description : document.text;
|
||||
return parser.parse(text ?? "") || Node.fromJSON(schema, {});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +67,7 @@ export class DocumentHelper {
|
||||
* @returns The document content as a plain JSON object
|
||||
*/
|
||||
static async toJSON(
|
||||
document: Document | Revision,
|
||||
document: Document | Revision | Collection,
|
||||
options?: {
|
||||
/** The team context */
|
||||
teamId: string;
|
||||
@@ -83,6 +86,8 @@ export class DocumentHelper {
|
||||
const ydoc = new Y.Doc();
|
||||
Y.applyUpdate(ydoc, document.state);
|
||||
doc = Node.fromJSON(schema, yDocToProsemirrorJSON(ydoc, "default"));
|
||||
} else if (document instanceof Collection) {
|
||||
doc = parser.parse(document.description ?? "");
|
||||
} else {
|
||||
doc = parser.parse(document.text);
|
||||
}
|
||||
@@ -123,12 +128,12 @@ export class DocumentHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the document as Markdown. This is a lossy conversion and should nly be used for export.
|
||||
* Returns the document as Markdown. This is a lossy conversion and should only be used for export.
|
||||
*
|
||||
* @param document The document or revision to convert
|
||||
* @returns The document title and content as a Markdown string
|
||||
*/
|
||||
static toMarkdown(document: Document | Revision) {
|
||||
static toMarkdown(document: Document | Revision | Collection) {
|
||||
const text = serializer
|
||||
.serialize(DocumentHelper.toProsemirror(document))
|
||||
.replace(/\n\\(\n|$)/g, "\n\n")
|
||||
@@ -138,6 +143,10 @@ export class DocumentHelper {
|
||||
.replace(/’/g, "'")
|
||||
.trim();
|
||||
|
||||
if (document instanceof Collection) {
|
||||
return text;
|
||||
}
|
||||
|
||||
const title = `${document.emoji ? document.emoji + " " : ""}${
|
||||
document.title
|
||||
}`;
|
||||
|
||||
Reference in New Issue
Block a user