diff --git a/QualityControl/public/layout/view/header.js b/QualityControl/public/layout/view/header.js index 25a69d272..20ce69121 100644 --- a/QualityControl/public/layout/view/header.js +++ b/QualityControl/public/layout/view/header.js @@ -18,6 +18,7 @@ import { iconPencil, iconTrash, iconPlus, iconBadge, iconLayers, iconCheck, iconBan, iconShareBoxed, } from '/js/src/icons.js'; import { filterPanelToggleButton } from '../../common/filters/filterViews.js'; +import { layoutListBadge } from './../../pages/layoutListView/components/LayoutListCard.js'; /** * Shows header of page showing one layout with edit button, and other buttons in edit mode. (center and right) @@ -44,7 +45,17 @@ const toolbarViewMode = (layout, filterModel) => { const { isOfficial, owner_id, name } = layoutItem; return { - centerCol: h('b.f4.items-center.flex-grow.text-center', [isOfficial ? iconBadge() : '', layoutItem.name]), + centerCol: h('.f4.flex-row.flex-grow.justify-center.items-center.g2', [ + h('.g1', [ + isOfficial ? h('span', iconBadge()) : '', + h('b', layoutItem.name), + ]), + h('.f6.flex-row', [ + '(', + layoutListBadge(layoutItem.labels), + ')', + ]), + ]), rightCol: h('.w-25.text-right.g2.flex-row.justify-end.flex-wrap', [ ' ', filterPanelToggleButton(filterModel), diff --git a/QualityControl/public/pages/layoutListView/components/LayoutListCard.js b/QualityControl/public/pages/layoutListView/components/LayoutListCard.js index 024190a0e..d20f61fe1 100644 --- a/QualityControl/public/pages/layoutListView/components/LayoutListCard.js +++ b/QualityControl/public/pages/layoutListView/components/LayoutListCard.js @@ -17,18 +17,21 @@ import { iconBadge } from '/js/src/icons.js'; /** * Main layout card component - * @param {object} layoutCardModel - The model handeling the state of this singular view + * @param {object} layoutCardModel - The model handling the state of this singular view * @returns {vnode} Complete layout card virtual DOM node */ export default function (layoutCardModel) { - const { description, owner_name, id, name, isOfficial } = layoutCardModel; + const { description, owner_name, id, name, isOfficial, labels } = layoutCardModel; const { router } = layoutCardModel.model; const isMinimumGlobal = layoutCardModel.sufficientAuthority(); const toggleOfficialFunction = () => layoutCardModel.toggleOfficial(); + const textColor = isOfficial ? 'white' : 'black'; + const bgColor = isOfficial ? 'bg-primary' : 'bg-gray'; + return h('.card', [ - cardHeader(isOfficial, id, name, isMinimumGlobal, toggleOfficialFunction, router), - cardBody(owner_name, description), + cardHeader(isOfficial, id, name, isMinimumGlobal, toggleOfficialFunction, router, { textColor, bgColor }), + cardBody(owner_name, description, labels, { textColor, bgColor }), ]); } @@ -38,13 +41,14 @@ export default function (layoutCardModel) { * @param {string} id - Unique identifier for the layout * @param {string} name - Display name of the layout * @param {boolean} isMinimumGlobal - Flag for user's global permissions - * @param {Function} toggleOfficialFunction - Callback for official status toggle - * @param {Function} router - router from the rout model + * @param {onclick} toggleOfficialFunction - Callback for official status toggle + * @param {redirectFunction} router - router from the rout model + * @param {object} colors - Object containing text and background colors. + * @param {string} colors.textColor - The text color based on official status. + * @param {string} colors.bgColor - The background color based on official status. * @returns {vnode} Virtual DOM node representing the layout card header */ -function cardHeader(isOfficial, id, name, isMinimumGlobal, toggleOfficialFunction, router) { - const bgColor = isOfficial ? 'bg-primary' : 'bg-gray'; - const textColor = isOfficial ? 'white' : 'black'; +function cardHeader(isOfficial, id, name, isMinimumGlobal, toggleOfficialFunction, router, { textColor, bgColor }) { const href = `?page=layoutShow&layoutId=${id}`; const clickHandler = (e) => router.handleLinkEvent(e); @@ -78,17 +82,40 @@ function headerButton(isOfficial, toggleOfficialFunction) { * Generates the body content for a layout card. * @param {string} owner_name - The name of the layout owner. * @param {string} description - The description of the layout. + * @param {string[]} labels - The labels associated with the layout. + * @param {object} colors - Object containing text and background colors. + * @param {string} colors.textColor - The text color based on official status. + * @param {string} colors.bgColor - The background color based on official status. * @returns {vnode} - A virtual DOM node for the layout's body content. */ -function cardBody(owner_name, description) { - return h('.cardBody.p2', [ - h('p', [ - h('strong', 'Owner: '), - owner_name, - ]), - h('p', [ - h('strong', 'Description: '), - description || '-', +function cardBody(owner_name, description, labels = [], { textColor, bgColor }) { + return h('.cardBody.ph2.flex-row.g2.p2', [ + h('.flex-column', { + style: 'flex-grow:1;', + }, [ + h('', [ + h('strong', 'Owner: '), + owner_name, + ]), + h('', [ + h('strong', 'Description: '), + description || '-', + ]), ]), + layoutListBadge(labels, { textColor, bgColor }), ]); } + +/** + * Generate a list of badges for layout labels. + * @param {string[]} labels - Array of label strings. + * @param {object} colors - Object containing text and background colors. + * @param {string} colors.textColor - The text color based on official status. + * @param {string} colors.bgColor - The background color based on official status. + * @returns {vnode} - A virtual DOM node containing the badges. + */ +export const layoutListBadge = (labels, { textColor = 'black', bgColor = 'bg-gray' } = {}) => h('.flex-row.g2', [ + labels?.length > 0 + ? labels.map((label) => h('', h(`span.badge.${bgColor}.${textColor}`, label))) + : h('', h('span', 'Contains no objects')), +]); diff --git a/QualityControl/public/pages/layoutListView/model/LayoutCardModel.js b/QualityControl/public/pages/layoutListView/model/LayoutCardModel.js index f875d08c2..2f70db22e 100644 --- a/QualityControl/public/pages/layoutListView/model/LayoutCardModel.js +++ b/QualityControl/public/pages/layoutListView/model/LayoutCardModel.js @@ -39,6 +39,7 @@ export default class LayoutCardModel extends Observable { this.owner_name = layout.owner_name; this.isOfficial = layout.isOfficial; this.name = layout.name; + this.labels = layout.labels || []; this.notify(); }