@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
240 lines (238 loc) • 10.8 kB
JavaScript
/*
* 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];
}