Files
cms.techvanguard.vn/utils/contentEditors/sharedFields.js
T
Tống Thành Đạt 5d0fae6d51 feat(cms): enhance content editors and implement automatic ID generation
Improve the CMS administration interface across multiple pages (Accreditation, Admissions, History, Partnerships, and Policies) with a focus on usability and data integrity.
Key changes include:
- Implement `ensureUniqueIds` utility to automatically generate and maintain unique slugs for content items, removing the need for manual ID entry in the UI.
- Refactor the Admissions calculator to support detailed per-option editing via a new dedicated view and routes.
- Replace basic datalists with a custom, searchable icon combobox component for better visual selection.
- Update `_renderSingletonPageView` to handle active tab persistence via query parameters.
- Streamline editor configurations by removing redundant fields and improving help text.
- Enhance the Admissions "Key Dates" editor with a dynamic table interface for managing columns and rows.
- Normalize data payloads in controllers to ensure consistent API responses and internal linking.
2026-04-21 12:37:19 +07:00

186 lines
3.3 KiB
JavaScript

const ICON_OPTIONS = [
"fa-scale-balanced",
"fa-shield-check",
"fa-magnifying-glass",
"fa-graduation-cap",
"fa-check-double",
"fa-building-columns",
"fa-award",
"fa-trophy",
"fa-arrow-down",
"fa-arrow-right",
"fa-check-circle",
"fa-exchange-alt",
"fa-bolt",
"fa-book-open",
"fa-credit-card",
"fa-calendar-days",
"fa-envelope",
"fa-file-lines",
"fa-globe",
"fa-briefcase",
"fa-handshake",
"fa-circle-info",
"fa-star",
"fa-list-check",
];
const text = (key, label, options = {}) => ({
key,
label,
type: "text",
...options,
});
const hidden = (key, options = {}) => ({
key,
type: "hidden",
...options,
});
const textarea = (key, label, options = {}) => ({
key,
label,
type: "textarea",
rows: options.rows || 4,
...options,
});
const image = (key, label, options = {}) => ({
key,
label,
type: "image",
...options,
});
const icon = (key, label, options = {}) => ({
key,
label,
type: "icon",
options: options.options || ICON_OPTIONS,
...options,
});
const checkbox = (key, label, options = {}) => ({
key,
label,
type: "checkbox",
...options,
});
const url = (key, label, options = {}) => ({
key,
label,
type: "url",
...options,
});
const select = (key, label, options = [], extra = {}) => ({
key,
label,
type: "select",
options,
...extra,
});
const combobox = (key, label, options = {}) => ({
key,
label,
type: "combobox",
...options,
});
const object = (key, label, fields, options = {}) => ({
key,
label,
type: "object",
fields,
...options,
});
const stringList = (key, label, options = {}) => ({
key,
label,
type: "array",
itemLabel: options.itemLabel || "Item",
sortable: options.sortable,
addLabel: options.addLabel,
helpText: options.helpText,
emptyText: options.emptyText,
itemSchema: {
type: "primitive",
fieldType: options.fieldType || "text",
label: options.itemLabel || "Item",
maxLength: options.maxLength,
min: options.min,
max: options.max,
step: options.step,
placeholder: options.placeholder,
helpText: options.itemHelpText,
},
...options,
});
const objectList = (key, label, fields, options = {}) => ({
key,
label,
type: "array",
itemLabel: options.itemLabel || "Item",
sortable: options.sortable,
addLabel: options.addLabel,
helpText: options.helpText,
emptyText: options.emptyText,
itemTitleKey: options.itemTitleKey,
itemSubtitleKey: options.itemSubtitleKey,
itemActions: options.itemActions,
itemSchema: {
type: "object",
fields,
},
...options,
});
const variantList = (key, label, variants, options = {}) => ({
key,
label,
type: "array",
itemLabel: options.itemLabel || "Item",
sortable: options.sortable,
addLabel: options.addLabel,
helpText: options.helpText,
emptyText: options.emptyText,
itemSchema: {
type: "variant",
discriminator: "type",
options: Object.keys(variants).map((value) => ({
value,
label: variants[value].label,
})),
variants,
},
...options,
});
const linkFields = (prefix = "Link") => [
text("label", `${prefix} label`, { maxLength: 60 }),
url("href", `${prefix} URL`, { maxLength: 255 }),
];
module.exports = {
ICON_OPTIONS,
text,
hidden,
textarea,
image,
icon,
checkbox,
url,
select,
combobox,
object,
stringList,
objectList,
variantList,
linkFields,
};