From d0fc4e3dc3815395d3fe9756060b423d5d4e17e6 Mon Sep 17 00:00:00 2001 From: Benjamin CHARMES Date: Fri, 5 Sep 2025 15:11:01 +0200 Subject: [PATCH 1/7] add QuillJS editor and keep TinyMCE compatibility Add QuillJS to package.json Add QuillJS to package.json Add data-testid to EditorTransition.vue for cypress Add data-testid to EditorTransition.vue for cypress Add data-testid to EditorTransition.vue for cypress Add data-testid to EditorTransition.vue for cypress Add data-testid to EditorTransition.vue for cypress Add data-testid to EditorTransition.vue for cypress --- webapp/cypress/e2e/batchSampleFeature.cy.js | 18 ++- webapp/cypress/e2e/sampleTablePage.cy.js | 13 +- webapp/package.json | 5 + webapp/src/components/CellInformation.vue | 9 +- .../components/CellPreparationInformation.vue | 7 +- .../src/components/CollectionInformation.vue | 9 +- webapp/src/components/EditorTransition.vue | 92 ++++++++++++ .../src/components/EquipmentInformation.vue | 10 +- webapp/src/components/QuillEditor.vue | 92 ++++++++++++ webapp/src/components/SampleInformation.vue | 10 +- .../StartingMaterialInformation.vue | 10 +- .../src/components/SynthesisInformation.vue | 9 +- .../components/datablocks/DataBlockBase.vue | 10 +- webapp/src/main.js | 3 + webapp/src/views/EditPage.vue | 4 +- webapp/yarn.lock | 132 +++++++++++++++++- 16 files changed, 395 insertions(+), 38 deletions(-) create mode 100644 webapp/src/components/EditorTransition.vue create mode 100644 webapp/src/components/QuillEditor.vue diff --git a/webapp/cypress/e2e/batchSampleFeature.cy.js b/webapp/cypress/e2e/batchSampleFeature.cy.js index 13c2e3183..94e24e483 100644 --- a/webapp/cypress/e2e/batchSampleFeature.cy.js +++ b/webapp/cypress/e2e/batchSampleFeature.cy.js @@ -155,7 +155,8 @@ describe("Batch sample creation", () => { cy.get('[data-testid="search-input"]').type("baseA"); cy.findByText("baseA").click(); cy.expandIfCollapsed("[data-testid=synthesis-block]"); - cy.findByLabelText("Description").type("this is a description of baseA."); + cy.findByLabelText("Description").should("exist"); + cy.get("[data-testid=item-description-input]").type("this is a description of baseA."); cy.findByText("Add a block").click(); cy.findByText("Comment").click(); @@ -169,7 +170,8 @@ describe("Batch sample creation", () => { cy.get('[data-testid="search-input"]').type("baseB"); cy.findByText("baseB").click(); cy.expandIfCollapsed("[data-testid=synthesis-block]"); - cy.findByLabelText("Description").type("this is a description of baseB."); + cy.findByLabelText("Description").should("exist"); + cy.get("[data-testid=item-description-input]").type("this is a description of baseB."); cy.findByText("Add a block").click(); cy.findByLabelText("Add a block").contains("Comment").click(); cy.get(".datablock-content div").first().type("a comment is added here."); @@ -225,6 +227,7 @@ describe("Batch sample creation", () => { cy.findByLabelText("Name").should("have.value", "a copied sample"); cy.findByText("this is a description of baseA."); cy.findByText("a comment is added here."); + cy.get(".fa-save").click(); cy.findByText("Home").click(); cy.contains(/^baseB_copy$/).click(); @@ -238,6 +241,7 @@ describe("Batch sample creation", () => { cy.get("#synthesis-information tbody tr:nth-of-type(2) input") .eq(0) .should("have.value", "100"); + cy.get(".fa-save").click(); cy.findByText("Home").click(); cy.findByText("baseB_copy2").click(); @@ -251,6 +255,7 @@ describe("Batch sample creation", () => { cy.get("#synthesis-information tbody tr:nth-of-type(2) input") .eq(0) .should("have.value", "100"); + cy.get(".fa-save").click(); cy.findByText("Home").click(); }); @@ -326,6 +331,7 @@ describe("Batch sample creation", () => { cy.get("#synthesis-information table").contains("component2"); cy.get("#synthesis-information tbody tr:nth-of-type(1) input").eq(0).should("have.value", ""); cy.get("#synthesis-information tbody tr:nth-of-type(2) input").eq(0).should("have.value", ""); + cy.get(".fa-save").click(); cy.findByText("Home").click(); cy.contains("test102").click(); @@ -339,6 +345,7 @@ describe("Batch sample creation", () => { cy.get("#synthesis-information tbody tr:nth-of-type(1) input").eq(0).should("have.value", ""); cy.get("#synthesis-information tbody tr:nth-of-type(2) input").eq(0).should("have.value", ""); cy.findByText("a comment is added here."); + cy.get(".fa-save").click(); cy.findByText("Home").click(); cy.contains("test103").click(); @@ -372,6 +379,7 @@ describe("Batch sample creation", () => { cy.findByText("a comment is added here."); cy.findByText("a second comment is added here."); + cy.get(".fa-save").click(); cy.findByText("Home").click(); cy.contains("test104").click(); @@ -413,7 +421,7 @@ describe("Batch sample creation", () => { cy.findByText("a description of the synthesis here"); cy.findByText("a comment is added here."); cy.findByText("a second comment is added here."); - + cy.get(".fa-save").click(); cy.findByText("Home").click(); }); @@ -538,6 +546,7 @@ describe("Batch sample creation", () => { cy.findByText("a comment is added here."); cy.findByText("a second comment is added here."); + cy.get(".fa-save").click(); cy.findByText("Home").click(); } @@ -644,6 +653,7 @@ describe("Batch sample creation", () => { cy.findByText("a comment is added here."); cy.findByText("a second comment is added here."); + cy.get(".fa-save").click(); cy.findByText("Home").click(); } @@ -839,7 +849,7 @@ describe("Batch cell creation", () => { cy.get("#electrolyte-table").contains("elyte"); cy.get("#neg-electrode-table").contains("comp2"); - + cy.get(".fa-save").click(); cy.findByText("Home").click(); } diff --git a/webapp/cypress/e2e/sampleTablePage.cy.js b/webapp/cypress/e2e/sampleTablePage.cy.js index 3e635e048..79894445a 100644 --- a/webapp/cypress/e2e/sampleTablePage.cy.js +++ b/webapp/cypress/e2e/sampleTablePage.cy.js @@ -220,7 +220,8 @@ describe.only("Advanced sample creation features", () => { it("modifies some data in the second sample", () => { cy.findByText("testB").click(); - cy.findByLabelText("Description").type("this is a description of testB."); + cy.findByLabelText("Description").should("exist"); + cy.get("[data-testid=item-description-input]").type("this is a description of baseB."); cy.findByText("Add a block").click(); cy.findByText("Comment").click(); @@ -257,7 +258,10 @@ describe.only("Advanced sample creation features", () => { it("checks the edit page of the copied sample", () => { cy.findByText("testBcopy").click(); cy.findByLabelText("Name").should("have.value", "COPY OF the second test sample"); - cy.findByText("this is a description of testB."); + cy.get("[data-testid=item-description-input]").should( + "have.text", + "this is a description of baseB.", + ); cy.findByText("a comment is added here."); cy.findByText("a description of the synthesis here"); cy.findAllByText("component3"); @@ -294,7 +298,10 @@ describe.only("Advanced sample creation features", () => { it("checks the edit page of the copied sample with components", () => { cy.findByText("testBcopy_copy").click(); cy.findByLabelText("Name").should("have.value", "COPY OF COPY OF the second test sample"); - cy.findByText("this is a description of testB."); + cy.get("[data-testid=item-description-input]").should( + "have.text", + "this is a description of baseB.", + ); cy.findByText("a comment is added here."); cy.findByText("a description of the synthesis here"); cy.findAllByText("component3"); diff --git a/webapp/package.json b/webapp/package.json index 784a50d74..0f2145347 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -25,6 +25,7 @@ "@uppy/dashboard": "^4.3.4", "@uppy/webcam": "^4.2.0", "@uppy/xhr-upload": "^4.3.3", + "@vueup/vue-quill": "^1.2.0", "@vueuse/components": "^10.7.2", "bootstrap": "^4.5.3", "buffer": "^6.0.3", @@ -42,6 +43,10 @@ "primevue": "^4.0.0", "process": "^0.11.10", "qrcode-vue3": "^1.6.8", + "quill": "2.0.2", + "quill-better-table": "^1.2.10", + "quill-delta-to-html": "^0.12.1", + "quill-markdown-shortcuts": "^0.0.10", "serve": "^14.2.1", "tinymce": "^5.10.9", "vue": "^3.2.4", diff --git a/webapp/src/components/CellInformation.vue b/webapp/src/components/CellInformation.vue index dc09845be..a681af99c 100644 --- a/webapp/src/components/CellInformation.vue +++ b/webapp/src/components/CellInformation.vue @@ -85,10 +85,11 @@
- + />
@@ -106,7 +107,7 @@ diff --git a/webapp/src/components/EquipmentInformation.vue b/webapp/src/components/EquipmentInformation.vue index 23afc7c84..375dba118 100644 --- a/webapp/src/components/EquipmentInformation.vue +++ b/webapp/src/components/EquipmentInformation.vue @@ -56,7 +56,11 @@ - + import { createComputedSetterForItemField } from "@/field_utils.js"; -import TinyMceInline from "@/components/TinyMceInline"; +import EditorTransition from "@/components/EditorTransition"; import TableOfContents from "@/components/TableOfContents"; import CollectionList from "@/components/CollectionList"; import FormattedRefcode from "@/components/FormattedRefcode"; @@ -76,11 +80,11 @@ import Creators from "@/components/Creators"; export default { components: { - TinyMceInline, CollectionList, TableOfContents, FormattedRefcode, Creators, + EditorTransition, }, props: { item_id: { type: String, required: true }, diff --git a/webapp/src/components/QuillEditor.vue b/webapp/src/components/QuillEditor.vue new file mode 100644 index 000000000..1a9b4ade3 --- /dev/null +++ b/webapp/src/components/QuillEditor.vue @@ -0,0 +1,92 @@ + + + diff --git a/webapp/src/components/SampleInformation.vue b/webapp/src/components/SampleInformation.vue index 25f18135c..a0a787ab3 100644 --- a/webapp/src/components/SampleInformation.vue +++ b/webapp/src/components/SampleInformation.vue @@ -43,7 +43,11 @@
- +
@@ -64,7 +68,7 @@ import ChemFormulaInput from "@/components/ChemFormulaInput"; import FormattedRefcode from "@/components/FormattedRefcode"; import ToggleableCollectionFormGroup from "@/components/ToggleableCollectionFormGroup"; import ToggleableCreatorsFormGroup from "@/components/ToggleableCreatorsFormGroup"; -import TinyMceInline from "@/components/TinyMceInline"; +import EditorTransition from "@/components/EditorTransition"; import SynthesisInformation from "@/components/SynthesisInformation"; import TableOfContents from "@/components/TableOfContents"; import ItemRelationshipVisualization from "@/components/ItemRelationshipVisualization"; @@ -72,13 +76,13 @@ import ItemRelationshipVisualization from "@/components/ItemRelationshipVisualiz export default { components: { ChemFormulaInput, - TinyMceInline, SynthesisInformation, TableOfContents, ItemRelationshipVisualization, FormattedRefcode, ToggleableCollectionFormGroup, ToggleableCreatorsFormGroup, + EditorTransition, }, props: { item_id: { type: String, required: true }, diff --git a/webapp/src/components/StartingMaterialInformation.vue b/webapp/src/components/StartingMaterialInformation.vue index e8a3ca59f..27721d09e 100644 --- a/webapp/src/components/StartingMaterialInformation.vue +++ b/webapp/src/components/StartingMaterialInformation.vue @@ -84,7 +84,11 @@ - + import { createComputedSetterForItemField } from "@/field_utils.js"; -import TinyMceInline from "@/components/TinyMceInline"; +import EditorTransition from "@/components/EditorTransition"; import ChemicalFormula from "@/components/ChemicalFormula"; import ChemFormulaInput from "@/components/ChemFormulaInput"; import TableOfContents from "@/components/TableOfContents"; @@ -118,13 +122,13 @@ export default { ChemicalFormula, ChemFormulaInput, ItemRelationshipVisualization, - TinyMceInline, ToggleableCollectionFormGroup, TableOfContents, FormattedRefcode, FormattedBarCode, SynthesisInformation, GHSHazardInformation, + EditorTransition, }, props: { item_id: { type: String, required: true }, diff --git a/webapp/src/components/SynthesisInformation.vue b/webapp/src/components/SynthesisInformation.vue index 53625b4d1..5a6eef3df 100644 --- a/webapp/src/components/SynthesisInformation.vue +++ b/webapp/src/components/SynthesisInformation.vue @@ -25,23 +25,24 @@ Procedure - + />