UNPKG

@craftercms/studio-ui

Version:

Services, components, models & utils to build CrafterCMS authoring extensions.

240 lines (238 loc) 10.8 kB
/* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ import Link from '@mui/material/Link'; import { FormattedMessage } from 'react-intl'; import React, { useMemo, useState } from 'react'; import { asLocalizedDateTime } from '../../utils/datetime'; import moment from 'moment'; import { messages } from '../ItemTypeIcon/translations'; import { isPage } from '../SiteDashboard/utils'; export function renderActivity(activity, dependencies) { const { formatMessage, onItemClick, onPackageClick } = dependencies; let item = activity.item; let systemType = activity.item?.systemType; if (messages[systemType]) { systemType = formatMessage(messages[systemType]).toLowerCase(); } const anchor = (chunks) => { const [label, systemType, previewUrl, path] = chunks; return !isPage(systemType) ? React.createElement('em', { title: path }, label) : React.createElement( Link, { title: path, sx: { cursor: 'pointer' }, onClick: (e) => onItemClick(previewUrl, e) }, label ); }; const render_package_link = (message) => { return React.createElement( Link, { sx: { cursor: 'pointer' }, onClick: (e) => onPackageClick(activity.package, e) }, message ); }; switch (activity.actionType) { case 'CREATE': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemCreateActivityMessage', defaultMessage: 'Created an item that no longer exists' }) : React.createElement(FormattedMessage, { id: 'activityDashlet.createActivityMessage', defaultMessage: 'Created <anchor>{item}</anchor> {systemType}', values: { item: [item.label, item.systemType, item.previewUrl, item.path], systemType, anchor } }); case 'UPDATE': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemUpdateActivityMessage', defaultMessage: 'Updated a an item that no longer exists' }) : React.createElement(FormattedMessage, { id: 'activityDashlet.updateActivityMessage', defaultMessage: 'Updated <anchor>{item}</anchor> {systemType}', values: { item: [item.label, item.systemType, item.previewUrl, item.path], systemType, anchor } }); case 'DELETE': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemDeleteActivityMessage', defaultMessage: 'Deleted an item' }) : React.createElement(FormattedMessage, { id: 'activityDashlet.deleteActivityMessage', defaultMessage: 'Deleted {label} {systemType}', values: { label: item.label, systemType } }); case 'MOVE': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemMoveActivityMessage', defaultMessage: 'Moved an item that no longer exists' }) : React.createElement(FormattedMessage, { id: 'activityDashlet.moveActivityMessage', defaultMessage: 'Moved <anchor>{item}</anchor> {systemType}', values: { item: [item.label, item.systemType, item.previewUrl, item.path], anchor, systemType } }); case 'REQUEST_PUBLISH': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemRequestPublishActivityMessage', defaultMessage: 'Requested publishing for an item that no longer exists' }) : React.createElement(FormattedMessage, { id: 'activityDashlet.requestPublishActivityMessage', defaultMessage: 'Requested publishing for <anchor>{item}</anchor> {systemType}', values: { item: [item.label, item.systemType, item.previewUrl, item.path], anchor, systemType } }); case 'PUBLISH': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemApproveActivityMessage', defaultMessage: 'Approved an item that no longer exists as part of <render_package_link>a package</render_package_link>', values: { render_package_link } }) : React.createElement(FormattedMessage, { id: 'activityDashlet.approveActivityMessage', defaultMessage: 'Approved <anchor>{item}</anchor> {systemType} as part of <render_package_link>a package</render_package_link>', values: { item: [item.label, item.systemType, item.previewUrl, item.path], anchor, render_package_link, systemType } }); case 'REJECT': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemRejectActivityMessage', defaultMessage: 'Rejected an item that no longer exists' }) : React.createElement(FormattedMessage, { id: 'activityDashlet.rejectActivityMessage', defaultMessage: 'Rejected <anchor>{item}</anchor> {systemType}', values: { item: [item.label, item.systemType, item.previewUrl, item.path], anchor, systemType } }); case 'REVERT': return item.label === null ? React.createElement(FormattedMessage, { id: 'activityDashlet.deletedItemRevertActivityMessage', defaultMessage: 'Reverted an item that no longer exists' }) : React.createElement(FormattedMessage, { id: 'activityDashlet.revertActivityMessage', defaultMessage: 'Reverted <anchor>{item}</anchor> {systemType}', values: { item: [item.label, item.systemType, item.previewUrl, item.path], anchor, systemType } }); case 'PUBLISHED': return React.createElement(FormattedMessage, { id: 'activityDashlet.publishedActivityMessage', defaultMessage: 'Published <render_package_link>a package</render_package_link>', values: { render_package_link } }); case 'INITIAL_PUBLISH': return React.createElement(FormattedMessage, { id: 'activityDashlet.initialPublishActivityMessage', defaultMessage: "Performed the project's initial publish" }); case 'PUBLISH_ALL': return React.createElement(FormattedMessage, { defaultMessage: 'Published entire project' }); default: console.log('[INFO] An unknown activity was received from the server.', activity); return React.createElement(FormattedMessage, { defaultMessage: 'Unlabelled activity' }); } } export function renderActivityTimestamp(timestamp, locale) { const now = Date.now(); const date = new Date(timestamp).getTime(); return now - date < 3.6e7 ? moment(date).fromNow() : asLocalizedDateTime(timestamp, locale.localeCode, locale.dateTimeFormatOptions); } export const activityNameLookup = { ALL: React.createElement(FormattedMessage, { id: 'activityDashlet.showActivityByEveryone', defaultMessage: 'All activities' }), CREATE: React.createElement(FormattedMessage, { id: 'words.create', defaultMessage: 'Create' }), DELETE: React.createElement(FormattedMessage, { id: 'words.delete', defaultMessage: 'Delete' }), INITIAL_PUBLISH: React.createElement(FormattedMessage, { id: 'operations.initialPublish', defaultMessage: 'Initial Publish' }), MOVE: React.createElement(FormattedMessage, { id: 'words.move', defaultMessage: 'Move' }), PUBLISH: React.createElement(FormattedMessage, { id: 'words.approve', defaultMessage: 'Approve' }), PUBLISHED: React.createElement(FormattedMessage, { id: 'words.publish', defaultMessage: 'Publish' }), REJECT: React.createElement(FormattedMessage, { id: 'words.reject', defaultMessage: 'Reject' }), REQUEST_PUBLISH: React.createElement(FormattedMessage, { id: 'operations.requestPublish', defaultMessage: 'Request Publish' }), REVERT: React.createElement(FormattedMessage, { id: 'words.revert', defaultMessage: 'Revert' }), UPDATE: React.createElement(FormattedMessage, { id: 'words.update', defaultMessage: 'Update' }), PUBLISH_ALL: React.createElement(FormattedMessage, { defaultMessage: 'Publish All' }) }; function getSelectedKeys(selection) { return Object.entries(selection) .filter(([key, value]) => value) .map(([key]) => key); } export function useSelectionLookupState(initialState = {}, resetSelectionKey = 'ALL') { const [selected, setSelected] = useState(initialState); const [selectedList, setSelectedList] = useState(getSelectedKeys(selected)); const fn = useMemo( () => (id) => { let selection; if (id === resetSelectionKey) { selection = { [resetSelectionKey]: true }; setSelected(selection); } else { const isSelecting = !selected[id]; selection = isSelecting || Object.entries(selected).filter(([key, value]) => key !== resetSelectionKey && key !== id && value).length ? { ...selected, [resetSelectionKey]: false, [id]: isSelecting } : { [resetSelectionKey]: true }; setSelected(selection); } setSelectedList(getSelectedKeys(selection)); }, [resetSelectionKey, selected] ); return [selected, fn, selectedList]; }