Add icon column to document (#7066)
* Add icon column to document * Backfill columns --------- Co-authored-by: Tom Moor <tom.moor@gmail.com>
This commit is contained in:
@@ -97,6 +97,8 @@ export default async function documentCreator({
|
|||||||
sourceMetadata,
|
sourceMetadata,
|
||||||
fullWidth: templateDocument ? templateDocument.fullWidth : fullWidth,
|
fullWidth: templateDocument ? templateDocument.fullWidth : fullWidth,
|
||||||
emoji: templateDocument ? templateDocument.emoji : emoji,
|
emoji: templateDocument ? templateDocument.emoji : emoji,
|
||||||
|
icon: templateDocument ? templateDocument.emoji : emoji,
|
||||||
|
color: templateDocument ? templateDocument.color : null,
|
||||||
title: TextHelper.replaceTemplateVariables(
|
title: TextHelper.replaceTemplateVariables(
|
||||||
templateDocument ? templateDocument.title : title,
|
templateDocument ? templateDocument.title : title,
|
||||||
user
|
user
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ describe("documentDuplicator", () => {
|
|||||||
expect(response[0].title).toEqual(original.title);
|
expect(response[0].title).toEqual(original.title);
|
||||||
expect(response[0].text).toEqual(original.text);
|
expect(response[0].text).toEqual(original.text);
|
||||||
expect(response[0].emoji).toEqual(original.emoji);
|
expect(response[0].emoji).toEqual(original.emoji);
|
||||||
|
expect(response[0].icon).toEqual(original.emoji);
|
||||||
expect(response[0].publishedAt).toBeInstanceOf(Date);
|
expect(response[0].publishedAt).toBeInstanceOf(Date);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ describe("documentDuplicator", () => {
|
|||||||
expect(response[0].title).toEqual("New title");
|
expect(response[0].title).toEqual("New title");
|
||||||
expect(response[0].text).toEqual(original.text);
|
expect(response[0].text).toEqual(original.text);
|
||||||
expect(response[0].emoji).toEqual(original.emoji);
|
expect(response[0].emoji).toEqual(original.emoji);
|
||||||
|
expect(response[0].icon).toEqual(original.emoji);
|
||||||
expect(response[0].publishedAt).toBeInstanceOf(Date);
|
expect(response[0].publishedAt).toBeInstanceOf(Date);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -106,6 +108,7 @@ describe("documentDuplicator", () => {
|
|||||||
expect(response[0].title).toEqual(original.title);
|
expect(response[0].title).toEqual(original.title);
|
||||||
expect(response[0].text).toEqual(original.text);
|
expect(response[0].text).toEqual(original.text);
|
||||||
expect(response[0].emoji).toEqual(original.emoji);
|
expect(response[0].emoji).toEqual(original.emoji);
|
||||||
|
expect(response[0].icon).toEqual(original.emoji);
|
||||||
expect(response[0].publishedAt).toBeNull();
|
expect(response[0].publishedAt).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export default async function documentUpdater({
|
|||||||
}
|
}
|
||||||
if (emoji !== undefined) {
|
if (emoji !== undefined) {
|
||||||
document.emoji = emoji;
|
document.emoji = emoji;
|
||||||
|
document.icon = emoji;
|
||||||
}
|
}
|
||||||
if (editorVersion) {
|
if (editorVersion) {
|
||||||
document.editorVersion = editorVersion;
|
document.editorVersion = editorVersion;
|
||||||
|
|||||||
79
server/migrations/20240617151506-add-icon-to-document.js
Normal file
79
server/migrations/20240617151506-add-icon-to-document.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
/** @type {import('sequelize-cli').Migration} */
|
||||||
|
module.exports = {
|
||||||
|
async up(queryInterface, Sequelize) {
|
||||||
|
await queryInterface.sequelize.transaction(async transaction => {
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
"documents",
|
||||||
|
"icon",
|
||||||
|
{
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transaction,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
"revisions",
|
||||||
|
"icon",
|
||||||
|
{
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transaction,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
"documents",
|
||||||
|
"color",
|
||||||
|
{
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
{ transaction }
|
||||||
|
);
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
"revisions",
|
||||||
|
"color",
|
||||||
|
{
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
{ transaction }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process.env.DEPLOYMENT === "hosted") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryInterface.sequelize.transaction(async (transaction) => {
|
||||||
|
await queryInterface.sequelize.query(
|
||||||
|
`UPDATE documents SET icon = emoji`,
|
||||||
|
{
|
||||||
|
transaction,
|
||||||
|
type: queryInterface.sequelize.QueryTypes.UPDATE,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await queryInterface.sequelize.query(
|
||||||
|
`UPDATE revisions SET icon = emoji`,
|
||||||
|
{
|
||||||
|
transaction,
|
||||||
|
type: queryInterface.sequelize.QueryTypes.UPDATE,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async down(queryInterface, Sequelize) {
|
||||||
|
await queryInterface.sequelize.transaction(async transaction => {
|
||||||
|
await queryInterface.removeColumn("documents", "icon", { transaction });
|
||||||
|
await queryInterface.removeColumn("revisions", "icon", { transaction });
|
||||||
|
await queryInterface.removeColumn("documents", "color", { transaction });
|
||||||
|
await queryInterface.removeColumn("revisions", "color", { transaction });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -64,6 +64,7 @@ import View from "./View";
|
|||||||
import ParanoidModel from "./base/ParanoidModel";
|
import ParanoidModel from "./base/ParanoidModel";
|
||||||
import Fix from "./decorators/Fix";
|
import Fix from "./decorators/Fix";
|
||||||
import { DocumentHelper } from "./helpers/DocumentHelper";
|
import { DocumentHelper } from "./helpers/DocumentHelper";
|
||||||
|
import IsHexColor from "./validators/IsHexColor";
|
||||||
import Length from "./validators/Length";
|
import Length from "./validators/Length";
|
||||||
|
|
||||||
export const DOCUMENT_VERSION = 2;
|
export const DOCUMENT_VERSION = 2;
|
||||||
@@ -262,6 +263,18 @@ class Document extends ParanoidModel<
|
|||||||
@Column
|
@Column
|
||||||
emoji: string | null;
|
emoji: string | null;
|
||||||
|
|
||||||
|
@Length({
|
||||||
|
max: 50,
|
||||||
|
msg: `icon must be 50 characters or less`,
|
||||||
|
})
|
||||||
|
@Column
|
||||||
|
icon: string | null;
|
||||||
|
|
||||||
|
/** The color of the icon. */
|
||||||
|
@IsHexColor
|
||||||
|
@Column
|
||||||
|
color: string | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The content of the document as Markdown.
|
* The content of the document as Markdown.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import Document from "./Document";
|
|||||||
import User from "./User";
|
import User from "./User";
|
||||||
import IdModel from "./base/IdModel";
|
import IdModel from "./base/IdModel";
|
||||||
import Fix from "./decorators/Fix";
|
import Fix from "./decorators/Fix";
|
||||||
|
import IsHexColor from "./validators/IsHexColor";
|
||||||
import Length from "./validators/Length";
|
import Length from "./validators/Length";
|
||||||
|
|
||||||
@DefaultScope(() => ({
|
@DefaultScope(() => ({
|
||||||
@@ -77,6 +78,18 @@ class Revision extends IdModel<
|
|||||||
@Column
|
@Column
|
||||||
emoji: string | null;
|
emoji: string | null;
|
||||||
|
|
||||||
|
@Length({
|
||||||
|
max: 50,
|
||||||
|
msg: `icon must be 50 characters or less`,
|
||||||
|
})
|
||||||
|
@Column
|
||||||
|
icon: string | null;
|
||||||
|
|
||||||
|
/** The color of the icon. */
|
||||||
|
@IsHexColor
|
||||||
|
@Column
|
||||||
|
color: string | null;
|
||||||
|
|
||||||
// associations
|
// associations
|
||||||
|
|
||||||
@BelongsTo(() => Document, "documentId")
|
@BelongsTo(() => Document, "documentId")
|
||||||
@@ -121,6 +134,8 @@ class Revision extends IdModel<
|
|||||||
title: document.title,
|
title: document.title,
|
||||||
text: document.text,
|
text: document.text,
|
||||||
emoji: document.emoji,
|
emoji: document.emoji,
|
||||||
|
icon: document.emoji,
|
||||||
|
color: document.color,
|
||||||
content: document.content,
|
content: document.content,
|
||||||
userId: document.lastModifiedById,
|
userId: document.lastModifiedById,
|
||||||
editorVersion: document.editorVersion,
|
editorVersion: document.editorVersion,
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ export default class ImportJSONTask extends ImportTask {
|
|||||||
// structure directly in the future.
|
// structure directly in the future.
|
||||||
text: serializer.serialize(Node.fromJSON(schema, node.data)),
|
text: serializer.serialize(Node.fromJSON(schema, node.data)),
|
||||||
emoji: node.emoji,
|
emoji: node.emoji,
|
||||||
|
icon: node.emoji,
|
||||||
|
color: null,
|
||||||
createdAt: node.createdAt ? new Date(node.createdAt) : undefined,
|
createdAt: node.createdAt ? new Date(node.createdAt) : undefined,
|
||||||
updatedAt: node.updatedAt ? new Date(node.updatedAt) : undefined,
|
updatedAt: node.updatedAt ? new Date(node.updatedAt) : undefined,
|
||||||
publishedAt: node.publishedAt ? new Date(node.publishedAt) : null,
|
publishedAt: node.publishedAt ? new Date(node.publishedAt) : null,
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ export default class ImportMarkdownZipTask extends ImportTask {
|
|||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
emoji,
|
emoji,
|
||||||
|
icon: emoji,
|
||||||
text,
|
text,
|
||||||
collectionId,
|
collectionId,
|
||||||
parentDocumentId,
|
parentDocumentId,
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ export default class ImportNotionTask extends ImportTask {
|
|||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
emoji,
|
emoji,
|
||||||
|
icon: emoji,
|
||||||
text,
|
text,
|
||||||
collectionId,
|
collectionId,
|
||||||
parentDocumentId,
|
parentDocumentId,
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ export type StructuredImportData = {
|
|||||||
urlId?: string;
|
urlId?: string;
|
||||||
title: string;
|
title: string;
|
||||||
emoji?: string | null;
|
emoji?: string | null;
|
||||||
|
icon?: string | null;
|
||||||
|
color?: string | null;
|
||||||
/**
|
/**
|
||||||
* The document text. To reference an attachment or image use the special
|
* The document text. To reference an attachment or image use the special
|
||||||
* formatting <<attachmentId>>. It will be replaced with a reference to the
|
* formatting <<attachmentId>>. It will be replaced with a reference to the
|
||||||
|
|||||||
Reference in New Issue
Block a user