Image Node for Tiptap working

pull/10/head
Jens Pelzetter 2021-10-09 21:03:26 +02:00
parent 2169e07ab2
commit 5513dc178e
8 changed files with 478 additions and 87 deletions

View File

@ -6,7 +6,7 @@
xmlns:cc="http://xmlns.jcp.org/jsf/composite" xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
> >
<cc:interface <cc:interface
shortDescription="A editor component for HTML texts using the TipTap editor. To use this component you have also to include the cms-editor.js file into the page." shortDescription="A editor component for HTML texts using the TipTap editor. To use this component you have also to include the cms-editor.js file into the page."
> >
@ -64,6 +64,12 @@
shortDescription="The back URL." shortDescription="The back URL."
type="String" type="String"
/> />
<cc:attribute
name="baseUrl"
required="true"
shortDescription="Base URL for generating URLs of API endpoints."
type="String"
/>
<cc:attribute <cc:attribute
name="canEdit" name="canEdit"
default="true" default="true"
@ -71,6 +77,12 @@
shortDescription="Can the current user edit the text?" shortDescription="Can the current user edit the text?"
type="boolean" type="boolean"
/> />
<cc:attribute
name="contentSection"
required="true"
shortDescription="The name of the current content section. Required for generating URLs of API endpoints."
type="String"
/>
<!-- <cc:attribute <!-- <cc:attribute
name="editButtonLabel" name="editButtonLabel"
default="#{CmsAdminMessages['edit_button.label']}" default="#{CmsAdminMessages['edit_button.label']}"
@ -290,6 +302,8 @@
<cc:implementation> <cc:implementation>
<div <div
class="cms-editor" class="cms-editor"
data-baseUrl="#{cc.attrs.baseUrl}"
data-contentsection="#{cc.attrs.contentSection}"
data-locale="#{cc.attrs.selectedLocale}" data-locale="#{cc.attrs.selectedLocale}"
data-save-url="#{cc.attrs.editMethod}/#{variant.locale}" data-save-url="#{cc.attrs.editMethod}/#{variant.locale}"
data-variant-url="#{cc.attrs.variantUrl}/#{cc.attrs.selectedLocale}" data-variant-url="#{cc.attrs.variantUrl}/#{cc.attrs.selectedLocale}"
@ -655,6 +669,20 @@
</button> </button>
</div> </div>
</div> </div>
<template id="librecms-image-node-view-row">
<tr>
<td class="col-name"></td>
<td class="col-type"></td>
<td class="col-action">
<button class="btn btn-primary"
data-assetuuid=""
data-dismiss="modal"
type="button">
#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.select']}
</button>
</td>
</tr>
</template>
<template id="librecms-image-node-view"> <template id="librecms-image-node-view">
<figure> <figure>
<!--img src="#{request.contextPath}/assets/remixicon/image-line.svg" />--> <!--img src="#{request.contextPath}/assets/remixicon/image-line.svg" />-->
@ -662,10 +690,59 @@
src="" src=""
style="min-height: 4em;" /> style="min-height: 4em;" />
<div class="border-light librecms-image-node-view-buttons"> <div class="border-light librecms-image-node-view-buttons">
<button class="btn btn-outline-dark select-image-button"> <button class="btn btn-outline-dark select-image-button"
data-toggle="modal"
data-target="#librecms-imge-node-select-image-dialog-">
<librecms:remixSvgIcon icon="ri-image-edit-line" /> <librecms:remixSvgIcon icon="ri-image-edit-line" />
<span class="sr-only">#{CmsAdminMessages['cms_editor.image_node_view.select_image.label']}</span> <span class="sr-only">#{CmsAdminMessages['cms_editor.image_node_view.select_image.label']}</span>
</button> </button>
<div aria-hidden="true"
aria-labelledby="librecms-image-node-select-image-dialog-title-"
class="modal fade select-image-dialog ccm-cms-asset-picker"
id="librecms-image-node-select-image-dialog-"
tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title"
id="librecms-image-node-select-image-dialog-title-">
#{CmsAdminMessages['cms_editor.image_node_view.selectimage.dialog.title']}
<button aria-label="#{CmsAdminMessages['cms_editor.image_node_view.selectimage.dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x-circle" />
</button>
</h3>
</div>
<div class="modal-body">
<bootstrap:formGroupText
class="assetpicker-filter"
help="#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.filter.help']}"
inputId="#{cc.attrs.assetPickerId}-filter"
label="#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.filter.label']}"
name="" />
<table>
<thead>
<tr>
<th>#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.name']}</th>
<th>#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.type']}</th>
<th>#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.action']}</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{CmsAdminMessages['cms_editor.image_node_view.selectimage.dialog.close']}
</button>
</div>
</div>
</div>
</div>
<button class="btn btn-outline-dark image-settings-button" <button class="btn btn-outline-dark image-settings-button"
data-toggle="modal" data-toggle="modal"
data-target="#librecms-image-node-view-settings-dialog-"> data-target="#librecms-image-node-view-settings-dialog-">
@ -754,6 +831,10 @@
</form> </form>
</div> </div>
</div> </div>
<!--<button class="btn btn-outline-dark image-remove-button">
<librecms:remixSvgIcon icon="ri-close-line" />
<span class="sr-only">#{CmsAdminMessages['cms_editor.image_node_view.remove.label']}</span>
</button>-->
</div> </div>
<figcaption aria-label="#{CmsAdminMessages['cms_editor.image_node_view.figcaption.label']}" <figcaption aria-label="#{CmsAdminMessages['cms_editor.image_node_view.figcaption.label']}"
contenteditable="true"> contenteditable="true">

View File

@ -20,7 +20,9 @@
<c:if test="#{CmsArticleTextBodyStep.canEdit}"> <c:if test="#{CmsArticleTextBodyStep.canEdit}">
<librecms:cmsEditor <librecms:cmsEditor
backUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-text" backUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-text"
baseUrl="#{mvc.basePath}"
canEdit="#{CmsArticleTextBodyStep.canEdit}" canEdit="#{CmsArticleTextBodyStep.canEdit}"
contentSection="#{ContentSectionModel.sectionName}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-text/edit" editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-text/edit"
editorId="cms-article-text-editor" editorId="cms-article-text-editor"
objectIdentifier="#{CmsSelectedDocumentModel.itemPath}" objectIdentifier="#{CmsSelectedDocumentModel.itemPath}"

View File

@ -890,3 +890,6 @@ cms_editor.image_node_view.settings.dialog.fullsizeoverlay.help=Enables a fullsi
cms_editor.image_node_view.settings.dialog.save=Submit cms_editor.image_node_view.settings.dialog.save=Submit
cms_editor.image_node_view.figcaption.label=Caption cms_editor.image_node_view.figcaption.label=Caption
cms_editor.image_node_view.figcaption.placeholder=Caption cms_editor.image_node_view.figcaption.placeholder=Caption
cms_editor.image_node_view.selectimage.dialog.title=Select image
cms_editor.image_node_view.selectimage.dialog.close=Cancel
cms_editor.image_node_view.remove.label=Remove image

View File

@ -891,3 +891,6 @@ cms_editor.image_node_view.settings.dialog.fullsizeoverlay.help=Aktiviert ein Gr
cms_editor.image_node_view.settings.dialog.save=\u00dcbernehmen cms_editor.image_node_view.settings.dialog.save=\u00dcbernehmen
cms_editor.image_node_view.figcaption.label=Bildunterschrift cms_editor.image_node_view.figcaption.label=Bildunterschrift
cms_editor.image_node_view.figcaption.placeholder=Bildunterschrift cms_editor.image_node_view.figcaption.placeholder=Bildunterschrift
cms_editor.image_node_view.selectimage.dialog.title=Bild ausw\u00e4hlen
cms_editor.image_node_view.selectimage.dialog.close=Abbrechen
cms_editor.image_node_view.remove.label=Bild entfernen

View File

@ -134,6 +134,7 @@ table.wor{
.cms-tiptap-editor-canvas { .cms-tiptap-editor-canvas {
max-height: 75vh; max-height: 75vh;
min-height: 35vh;
overflow: scroll; overflow: scroll;
} }
@ -144,9 +145,76 @@ table.wor{
position: relative; position: relative;
.librecms-image-node-view-buttons { .librecms-image-node-view-buttons {
background-color: rgba(255,255,255,0.5);
position: absolute; position: absolute;
top: 0; top: 0.5rem;
right: 0; right: 0.5rem;
width: 3em;
width: 2.66rem;
& > button {
width: 2.66rem;
}
}
&.librecms-image-node-width-25 {
width: 25%;
}
&.librecms-image-node-width-33 {
width: 33%;
}
&.librecms-image-node-width-50 {
width: 50%;
}
&.librecms-image-node-width-66 {
width: 66%;
}
&.librecms-image-node-width-75 {
width: 75%;
}
&.librecms-image-node-width-100 {
width: 100%;
}
&.librecms-image-node-align-floatleft {
float: left;
}
&.librecms-image-node-align-center {
margin-left: auto;
margin-right: auto;
}
&.librecms-image-node-align-floatright {
float: right;
}
figure img {
max-width: 100%;
}
.select-image-dialog {
table {
border: none;
width: 100%;
thead th {
text-align: center;
}
thead tr, tbody tr:nth-child(even) {
background-color: #ededed;
}
tr, th, td {
border: none
}
}
} }
} }

View File

@ -16,7 +16,7 @@ async function initAssetPicker(assetPickerElem: Element) {
console.log(`assetPickerId = ${assetPickerId}`); console.log(`assetPickerId = ${assetPickerId}`);
const fetchUrl = `${baseUrl}/content-sections/${contentSection}/assets?type=${assetType}`; const fetchUrl = `/content-sections/${contentSection}/assets?type=${assetType}`;
try { try {
const response = await fetch(fetchUrl); const response = await fetch(fetchUrl);

View File

@ -341,9 +341,9 @@ const BUTTONS: CmsEditorButton[] = [
const headerRowInput = dialog.querySelector( const headerRowInput = dialog.querySelector(
"input#headerRow" "input#headerRow"
) as HTMLInputElement; ) as HTMLInputElement;
console.log(`rowsInput = ${rowsInput}`); // console.log(`rowsInput = ${rowsInput}`);
console.log(`colsInput = ${colsInput}`); // console.log(`colsInput = ${colsInput}`);
console.log(`headerRowInput = ${headerRowInput}`); // console.log(`headerRowInput = ${headerRowInput}`);
const rows = parseInt(rowsInput.value, 10); const rows = parseInt(rowsInput.value, 10);
const cols = parseInt(colsInput.value, 10); const cols = parseInt(colsInput.value, 10);
const headerRow = JSON.parse(headerRowInput.value) as Boolean; const headerRow = JSON.parse(headerRowInput.value) as Boolean;
@ -555,6 +555,7 @@ const BUTTONS: CmsEditorButton[] = [
.chain() .chain()
.focus() .focus()
.setLibreCmsImage() .setLibreCmsImage()
.insertContent("<p></p>")
.run(); .run();
}, },
can: (cmsEditor) => { can: (cmsEditor) => {
@ -598,7 +599,7 @@ class CmsEditor {
this.editorElem = editorElem; this.editorElem = editorElem;
this.saveUrl = saveUrl; this.saveUrl = saveUrl;
console.log("initializing editor buttons"); // console.log("initializing editor buttons");
const buttonsElem = editorElem.querySelector( const buttonsElem = editorElem.querySelector(
".cms-tiptap-editor-buttons" ".cms-tiptap-editor-buttons"
); );
@ -620,7 +621,7 @@ class CmsEditor {
} }
editor.on("selectionUpdate", ({ editor }: { editor: Editor }) => { editor.on("selectionUpdate", ({ editor }: { editor: Editor }) => {
console.log(`checkButton - this.editorElem = ${this.editorElem}`); // console.log(`checkButton - this.editorElem = ${this.editorElem}`);
const buttonsElem = editorElem.querySelector( const buttonsElem = editorElem.querySelector(
".cms-tiptap-editor-buttons" ".cms-tiptap-editor-buttons"
); );
@ -642,7 +643,7 @@ class CmsEditor {
} }
}); });
console.log(`editorElem = ${editorElem}`); // console.log(`editorElem = ${editorElem}`);
const saveButton = editorElem.querySelector(".cms-editor-save-button"); const saveButton = editorElem.querySelector(".cms-editor-save-button");
saveButton?.addEventListener("click", (event) => this.save(event)); saveButton?.addEventListener("click", (event) => this.save(event));
@ -716,7 +717,7 @@ class CmsEditorBuilder {
} }
public async buildEditor(): Promise<CmsEditor> { public async buildEditor(): Promise<CmsEditor> {
console.log("Build CMS Editor."); // console.log("Build CMS Editor.");
const canvasElement = this.editorElem.querySelector( const canvasElement = this.editorElem.querySelector(
".cms-tiptap-editor-canvas" ".cms-tiptap-editor-canvas"
); );

View File

@ -1,4 +1,5 @@
import { Node, nodeInputRule, mergeAttributes } from "@tiptap/core"; import { Node, nodeInputRule, mergeAttributes, Range } from "@tiptap/core";
import { Node as ProsemirrorNode } from "prosemirror-model";
declare module "@tiptap/core" { declare module "@tiptap/core" {
interface Commands<ReturnType> { interface Commands<ReturnType> {
@ -64,6 +65,16 @@ export const ImageNode = Node.create({
} }
}, },
}, },
imgSrc: {
parseHTML: (element) => {
const imgElem = element.querySelector("img");
if (imgElem) {
return imgElem.src;
} else {
return "";
}
},
},
size: { size: {
parseHTML: (element) => { parseHTML: (element) => {
if (element.hasAttribute("data-size")) { if (element.hasAttribute("data-size")) {
@ -121,32 +132,101 @@ export const ImageNode = Node.create({
// console.log(`extension = ${extension}`); // console.log(`extension = ${extension}`);
// console.dir(extension); // console.dir(extension);
const dom = document.createElement("div");
dom.classList.add("librecms-image-node-view", "p-2");
if (!node.attrs.size) {
node.attrs.size = "50";
}
dom.classList.add(`librecms-image-node-width-${node.attrs.size}`);
if (!node.attrs.align) {
node.attrs.align = "center";
}
dom.classList.add(`librecms-image-node-align-${node.attrs.align}`);
const template = templateNode as HTMLTemplateElement; const template = templateNode as HTMLTemplateElement;
const nodeView = template.content.cloneNode(true) as HTMLElement; const nodeView = template.content.cloneNode(true) as HTMLElement;
const imgElem = nodeView.querySelector("img");
const dialogIdNr = Math.floor(Math.random() * 1000000000); const dialogIdNr = Math.floor(Math.random() * 1000000000);
const dialogId = `librecms-image-node-view-settings-dialog-${dialogIdNr}`;
const dialogTitleId = `${dialogId}-title`; const selectDialogId = `librecms-image-node-select-image-dialog-title-${dialogIdNr}`;
const selectDialogTitleId = `librecms-image-node-select-image-dialog-title-${dialogIdNr}-title`;
const selectButtonElem = nodeView.querySelector(
".select-image-button"
);
if (selectButtonElem) {
selectButtonElem.setAttribute(
"data-target",
`#${selectDialogId}`
);
}
const selectDialogElem = nodeView.querySelector(
".modal.select-image-dialog"
);
if (selectDialogElem) {
selectDialogElem.id = selectDialogId;
selectDialogElem.setAttribute(
"aria-labelledby",
selectDialogTitleId
);
const selectDialogTitleElem =
selectDialogElem.querySelector(".modal-title");
if (selectDialogTitleElem) {
selectDialogTitleElem.id = selectDialogTitleId;
}
const selectDialogIds =
selectDialogElem.querySelectorAll("*[id]");
selectDialogIds.forEach((elemWithId) => {
elemWithId.id = `${elemWithId.id}-${dialogIdNr}`;
});
const selectDialogLabels =
selectDialogElem.querySelectorAll("*[for]");
selectDialogLabels.forEach((label) => {
label.setAttribute(
"for",
`${label.getAttribute("for")}-${dialogIdNr}`
);
});
const describedElems = selectDialogElem.querySelectorAll(
"*[aria-describedby]"
);
describedElems.forEach((describedElem) => {
describedElem.setAttribute(
"aria-describedby",
`${describedElem.getAttribute(
"aria-describedby"
)}-${dialogIdNr}`
);
});
}
const settingsDialogId = `librecms-image-node-view-settings-dialog-${dialogIdNr}`;
const settingsDialogTitleId = `${settingsDialogId}-title`;
const settingsButtonElem = nodeView.querySelector( const settingsButtonElem = nodeView.querySelector(
".image-settings-button" ".image-settings-button"
); );
if (settingsButtonElem) { if (settingsButtonElem) {
settingsButtonElem.setAttribute("data-target", `#${dialogId}`); settingsButtonElem.setAttribute(
"data-target",
`#${settingsDialogId}`
);
} }
const settingsDialogElem = nodeView.querySelector( const settingsDialogElem = nodeView.querySelector(
".modal.image-settings-dialog" ".modal.image-settings-dialog"
); );
if (settingsDialogElem) { if (settingsDialogElem) {
settingsDialogElem.id = dialogId; settingsDialogElem.id = settingsDialogId;
settingsDialogElem.setAttribute( settingsDialogElem.setAttribute(
"aria-labelledby", "aria-labelledby",
dialogTitleId settingsDialogTitleId
); );
const settingsDialogTitleElem = const settingsDialogTitleElem =
settingsDialogElem.querySelector(".modal-title"); settingsDialogElem.querySelector(".modal-title");
if (settingsDialogTitleElem) { if (settingsDialogTitleElem) {
settingsDialogTitleElem.id = dialogTitleId; settingsDialogTitleElem.id = settingsDialogTitleId;
} }
const settingDialogIds = const settingDialogIds =
@ -245,6 +325,9 @@ export const ImageNode = Node.create({
const inputElem = altTextInput as HTMLInputElement; const inputElem = altTextInput as HTMLInputElement;
if (altTextInput) { if (altTextInput) {
node.attrs.altText = inputElem.value; node.attrs.altText = inputElem.value;
if (imgElem) {
imgElem.alt = inputElem.value;
}
} else { } else {
console.warn("Input for alt text not found."); console.warn("Input for alt text not found.");
} }
@ -253,6 +336,15 @@ export const ImageNode = Node.create({
const selectElem = alignSelect as HTMLSelectElement; const selectElem = alignSelect as HTMLSelectElement;
node.attrs.align = node.attrs.align =
selectElem.selectedOptions.item(0)?.value; selectElem.selectedOptions.item(0)?.value;
["floatleft", "center", "floatright"].forEach(
(align) =>
dom.classList.remove(
`librecms-image-node-align-${align}`
)
);
dom.classList.add(
`librecms-image-node-align-${node.attrs.align}`
);
} else { } else {
console.warn( console.warn(
"Select for image alignment not found." "Select for image alignment not found."
@ -263,6 +355,15 @@ export const ImageNode = Node.create({
const selectElem = sizeSelect as HTMLSelectElement; const selectElem = sizeSelect as HTMLSelectElement;
node.attrs.size = node.attrs.size =
selectElem.selectedOptions.item(0)?.value; selectElem.selectedOptions.item(0)?.value;
["25", "33", "50", "66", "75", "100"].forEach(
(size) =>
dom.classList.remove(
`librecms-image-node-width-${size}`
)
);
dom.classList.add(
`librecms-image-node-width-${node.attrs.size}`
);
} else { } else {
console.warn("Select for image size not found."); console.warn("Select for image size not found.");
} }
@ -282,16 +383,43 @@ export const ImageNode = Node.create({
"Submit button for image settings dialog not found." "Submit button for image settings dialog not found."
); );
} }
// const removeImageButton = nodeView.querySelector(
// ".image-remove-button"
// );
// if (removeImageButton) {
// removeImageButton.addEventListener("click", (event) => {
// if (typeof getPos === "number") {
// const from = getPos as number;
// const range: Range = {
// from,
// to: node.nodeSize,
// };
// editor.chain().focus().deleteRange(range);
// }
// });
// } else {
// console.error("removeImageButton not found.");
// }
} }
const figCaptionElem = nodeView.querySelector("figcaption"); const figCaptionElem = nodeView.querySelector("figcaption");
if (node.attrs.figCaption !== "" && figCaptionElem) { if (node.attrs.figCaption !== "" && figCaptionElem) {
figCaptionElem.innerHTML = node.attrs.figCaption; figCaptionElem.innerHTML = node.attrs.figCaption;
} }
const dom = document.createElement("div");
dom.classList.add("librecms-image-node-view", "p-2");
dom.appendChild(nodeView); dom.appendChild(nodeView);
if (selectButtonElem) {
if (imgElem) {
selectButtonElem.addEventListener("click", (event) =>
loadImages(event, node, imgElem)
);
} else {
console.error("img elem not found.");
}
}
return { return {
dom, dom,
}; };
@ -307,11 +435,11 @@ export const ImageNode = Node.create({
}, },
renderHTML({ node, HTMLAttributes }) { renderHTML({ node, HTMLAttributes }) {
console.log("node = "); // console.log("node = ");
console.dir(node); // console.dir(node);
return [ return [
"figure", "figure",
mergeAttributes(HTMLAttributes, { mergeAttributes({
"data-align": node.attrs.align, "data-align": node.attrs.align,
"data-fullsizeoverlay": node.attrs.fullSizeOverlay, "data-fullsizeoverlay": node.attrs.fullSizeOverlay,
"data-size": node.attrs.size, "data-size": node.attrs.size,
@ -321,10 +449,115 @@ export const ImageNode = Node.create({
"img", "img",
{ {
alt: node.attrs.altText, alt: node.attrs.altText,
src: "/assets/remixicon/image-line.svg", src: node.attrs.imgSrc,
}, },
], ],
["figcaption"], ["figcaption"],
]; ];
}, },
}); });
function loadImages(
event: Event,
node: ProsemirrorNode<any>,
imgElem: HTMLImageElement
) {
console.log("Loading images...");
const eventTarget = event.currentTarget as HTMLElement;
const editorElem = document.querySelector(".cms-editor");
if (!editorElem) {
return;
}
const baseUrl = editorElem.getAttribute("data-baseUrl");
const contentSection = editorElem.getAttribute("data-contentsection");
const dialogId = eventTarget.getAttribute("data-target");
if (!dialogId) {
console.error("data-target attribute is missing.");
return;
}
const dialog = document.querySelector(dialogId);
if (!dialog) {
console.error("dialog element not found is missing.");
return;
}
const rowTemplateResult = document.querySelector(
"#librecms-image-node-view-row"
);
if (!rowTemplateResult) {
console.error("template for result row not found.");
return;
}
const rowTemplate = rowTemplateResult as HTMLTemplateElement;
const table = dialog.querySelector("table");
if (!table) {
console.error("result table not found.");
return;
}
const tableBody = table.querySelector("tbody");
if (!tableBody) {
console.error("table body not found.");
return;
}
tableBody.innerHTML = "";
const fetchUrl = `/content-sections/${contentSection}/assets?type=org.librecms.assets.Image`;
fetch(fetchUrl)
.then((response) => {
if (response.ok) {
response
.json()
.then((data) => {
const images = data as [];
for (const image of images) {
const row = rowTemplate.content.cloneNode(
true
) as Element;
const colName = row.querySelector(".col-name");
const colType = row.querySelector(".col-type");
const selectButton =
row.querySelector(".col-action button");
if (colName) {
colName.textContent = image["name"];
}
if (colType) {
colType.textContent = image["name"];
}
if (selectButton) {
selectButton.setAttribute(
"data-imageuuid",
image["uuid"]
);
selectButton.addEventListener(
"click",
(event) => {
const imgUrl = `/content-sections/info/images/uuid-${image["uuid"]}`;
node.attrs.imgSrc = imgUrl;
if (imgElem) {
imgElem.src = imgUrl;
} else {
console.error(
"img element not found."
);
}
}
);
}
tableBody.appendChild(row);
}
})
.catch((error) => {
console.error(error);
});
} else {
console.error(
`Error. Status: ${response.status}. Status Text: ${response.statusText}`
);
}
})
.catch((error) => {
console.error(error);
});
}