forked from UKSOURCE/cms.lams
style(cms): improve editor ui and implement collapsible item cards
Enhance the CMS administration interface by introducing a more refined design system for content editors. This update replaces generic Bootstrap utility classes with dedicated CMS styling to improve visual hierarchy and usability. Key changes: - Introduce `cms-editor-group` and `cms-item-card` classes for consistent grouping and item styling. - Implement collapsible functionality for item cards to manage long lists of content more effectively. - Standardize editor buttons, including new styles for drag handles, remove buttons, and add buttons. - Update the fixed bottom action bar with improved backdrop filters, shadows, and spacing. - Refactor editor scripts across Accreditation, Admissions, History, Partnerships, and Policies to utilize the new UI components and collapse logic. - Add comprehensive CSS to `main.ejs` to support the new CMS design tokens and layout behaviors.
This commit is contained in:
@@ -111,26 +111,17 @@
|
||||
|
||||
const col = createCol(schema.colClass || "col-12");
|
||||
const card = document.createElement("div");
|
||||
card.className = "border rounded-3 bg-light-subtle p-3";
|
||||
card.className = "cms-editor-group";
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "d-flex justify-content-between align-items-center mb-3 gap-3";
|
||||
header.className = "mb-3";
|
||||
header.innerHTML = `
|
||||
<div>
|
||||
<label class="form-label fw-semibold mb-1">${escapeHtml(schema.label)}</label>
|
||||
${schema.helpText ? `<div class="form-text mt-0">${escapeHtml(schema.helpText)}</div>` : ""}
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm">
|
||||
<i class="fas fa-plus me-1"></i>${escapeHtml(schema.addLabel || `Add ${schema.itemLabel || "Item"}`)}
|
||||
</button>
|
||||
`;
|
||||
|
||||
header.querySelector("button").addEventListener("click", function () {
|
||||
parent[key].push(createDefaultValue(schema.itemSchema));
|
||||
applyAutoSequenceToArray(schema, parent[key]);
|
||||
renderSection(tabKey);
|
||||
});
|
||||
|
||||
card.appendChild(header);
|
||||
|
||||
if (parent[key].length === 0) {
|
||||
@@ -145,11 +136,11 @@
|
||||
|
||||
parent[key].forEach((item, index) => {
|
||||
const itemCard = document.createElement("div");
|
||||
itemCard.className = "card shadow-sm border-0 mb-3";
|
||||
itemCard.className = "card cms-item-card mb-3";
|
||||
itemCard.dataset.index = String(index);
|
||||
|
||||
const itemHeader = document.createElement("div");
|
||||
itemHeader.className = "bg-white border-bottom px-3 py-3 d-flex justify-content-between align-items-center gap-2 flex-wrap";
|
||||
itemHeader.className = "card-header d-flex justify-content-between align-items-center gap-2 flex-wrap";
|
||||
|
||||
const title = getArrayItemTitle(schema, item, index);
|
||||
const subtitle = getArrayItemSubtitle(schema, item);
|
||||
@@ -157,7 +148,7 @@
|
||||
<div class="d-flex align-items-center gap-2 flex-grow-1">
|
||||
${
|
||||
schema.sortable
|
||||
? '<button type="button" class="btn btn-light btn-sm border drag-handle" title="Drag to reorder"><i class="fas fa-grip-vertical"></i></button>'
|
||||
? '<button type="button" class="drag-handle" title="Drag to reorder"><i class="fas fa-grip-vertical"></i></button>'
|
||||
: ""
|
||||
}
|
||||
<div>
|
||||
@@ -166,13 +157,22 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2 flex-wrap">
|
||||
<button type="button" class="cms-collapse-toggle" data-toggle-item="true" title="Collapse section">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
${renderItemActions(schema.itemActions, item)}
|
||||
<button type="button" class="btn btn-outline-danger btn-sm" data-remove-item="true">
|
||||
<i class="fas fa-trash-alt me-1"></i>Remove
|
||||
<button type="button" class="cms-remove-button" data-remove-item="true" title="Remove item">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
itemHeader
|
||||
.querySelector('[data-toggle-item="true"]')
|
||||
.addEventListener("click", function () {
|
||||
itemCard.classList.toggle("is-collapsed");
|
||||
});
|
||||
|
||||
itemHeader
|
||||
.querySelector('[data-remove-item="true"]')
|
||||
.addEventListener("click", function () {
|
||||
@@ -224,6 +224,17 @@
|
||||
list.appendChild(itemCard);
|
||||
});
|
||||
|
||||
const addButton = document.createElement("button");
|
||||
addButton.type = "button";
|
||||
addButton.className = "cms-add-button mt-2";
|
||||
addButton.innerHTML = `<i class="fas fa-plus me-2"></i>${escapeHtml(schema.addLabel || `Add ${schema.itemLabel || "Item"}`)}`;
|
||||
addButton.addEventListener("click", function () {
|
||||
parent[key].push(createDefaultValue(schema.itemSchema));
|
||||
applyAutoSequenceToArray(schema, parent[key]);
|
||||
renderSection(tabKey);
|
||||
});
|
||||
card.appendChild(addButton);
|
||||
|
||||
if (schema.sortable && window.Sortable) {
|
||||
window.Sortable.create(list, {
|
||||
animation: 150,
|
||||
@@ -598,7 +609,7 @@
|
||||
|
||||
function appendHelp(col, schema, value, extraHint) {
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.className = "d-flex justify-content-between gap-3";
|
||||
wrapper.className = "field-meta-row";
|
||||
|
||||
const help = document.createElement("div");
|
||||
help.className = "form-text";
|
||||
@@ -608,7 +619,7 @@
|
||||
let counter = null;
|
||||
if (schema.maxLength) {
|
||||
counter = document.createElement("div");
|
||||
counter.className = "form-text text-end ms-auto";
|
||||
counter.className = "field-char-count";
|
||||
updateCounter(counter, String(value || "").length, schema.maxLength);
|
||||
wrapper.appendChild(counter);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user