Introduce capapbility object

This commit is contained in:
Paulo Gustavo Veiga 2022-10-08 10:12:07 -07:00
parent 54ed067288
commit de4c6f3f0a
19 changed files with 314 additions and 150 deletions

View File

@ -56,7 +56,7 @@ interface ActionConfig {
*/
useClickToClose?: boolean;
/**
* if false the nmenu entry or button is not visible. Also custom render will be ignored.
* if false the menu entry or button is not visible. Also custom render will be ignored.
*/
visible?: boolean;
}

View File

@ -0,0 +1,34 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
type ActionType =
| 'undo-changes'
| 'redo-changes'
| 'history'
| 'save'
| 'print'
| 'export'
| 'publish'
| 'share'
| 'info'
| 'account'
| 'edition-toolbar'
| 'sign-up'
| 'keyboard-shortcuts';
export default ActionType;

View File

@ -0,0 +1,170 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EditorRenderMode } from '../../..';
import ActionType from '../action-type';
class Capability {
readonly mode: EditorRenderMode;
readonly isLocked: boolean;
readonly isMobile: boolean;
constructor(mode: EditorRenderMode, isLocked: boolean) {
this.mode = mode;
this.isMobile = this.parseMobile();
this.isLocked = isLocked;
}
private parseMobile = () => {
const result =
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(
navigator.userAgent.toLowerCase(),
) ||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
navigator.userAgent.toLowerCase().substring(0, 4),
);
return result;
};
isHidden(action: ActionType): boolean {
const mapping = ActionConfigByRenderMode[action];
let result: boolean = false;
if (mapping) {
// Has been marked in desktop ...
const desktopCapability: EditorRenderMode[] = mapping.desktop?.hidden;
result = desktopCapability?.includes(this.mode);
// Had been overwrited for mobile ...
if (!result && this.isMobile) {
const mobileCapability: EditorRenderMode[] = mapping.desktop?.hidden;
result = mobileCapability?.includes(this.mode);
}
}
// Todo: Needs to be moved to more declarative ...
if (
this.isLocked &&
(action === 'save' ||
action === 'keyboard-shortcuts' ||
action === 'edition-toolbar' ||
action === 'publish' ||
action === 'redo-changes' ||
action === 'undo-changes')
) {
result = true;
}
console.log(`action: ${action}->${Boolean(result)}`);
return Boolean(result);
}
isDisabled(action: ActionType): boolean {
let result: boolean = this.isHidden(action);
// If it was not marked as hidden, it might be marked as disabled ...
if (!result) {
const mapping = ActionConfigByRenderMode[action];
if (!mapping) {
// Has been marked in desktop ...
const desktopCapability: EditorRenderMode[] = mapping.desktop?.hidden;
result = desktopCapability?.includes(this.mode);
// Had been overwrited for mobile ...
if (!result && this.isMobile) {
const mobileCapability: EditorRenderMode[] = mapping.desktop?.hidden;
result = mobileCapability?.includes(this.mode);
}
}
}
return Boolean(result);
}
}
interface CapabilitySupport {
mobile?: {
hidden?: EditorRenderMode[];
disabled?: EditorRenderMode[];
};
desktop?: {
hidden?: EditorRenderMode[];
disabled?: EditorRenderMode[];
};
}
const ActionConfigByRenderMode: Record<ActionType, CapabilitySupport> = {
'redo-changes': {
desktop: {
hidden: ['viewonly', 'edition-viewer'],
},
},
'undo-changes': {
desktop: {
hidden: ['viewonly', 'edition-viewer'],
},
},
save: {
desktop: {
hidden: ['showcase', 'viewonly', 'edition-viewer'],
},
},
print: undefined,
publish: {
desktop: {
hidden: ['showcase', 'viewonly', 'edition-viewer', 'edition-editor'],
},
},
share: {
desktop: {
hidden: ['showcase', 'viewonly', 'edition-viewer', 'edition-editor'],
},
},
info: {
desktop: {
hidden: ['showcase'],
},
},
account: {
desktop: {
hidden: ['showcase'],
},
},
'edition-toolbar': {
desktop: {
hidden: ['viewonly', 'edition-viewer'],
},
},
'keyboard-shortcuts': {
mobile: {
hidden: ['viewonly', 'showcase', 'edition-viewer', 'edition-editor', 'edition-owner'],
},
},
history: {
desktop: {
hidden: ['viewonly', 'edition-viewer', 'showcase'],
},
},
export: undefined,
'sign-up': {
desktop: {
hidden: ['viewonly', 'edition-viewer', 'edition-editor', 'edition-owner'],
},
},
};
export default Capability;

View File

@ -16,7 +16,7 @@
* limitations under the License.
*/
import React, { useEffect, useState } from 'react';
import ActionConfig from '../../../../classes/action-config';
import ActionConfig from '../../../../classes/action/action-config';
import { ToolbarMenuItem } from '../../../toolbar/Toolbar';
const UndoAndRedo = (props: {

View File

@ -18,7 +18,7 @@
import { $msg } from '@wisemapping/mindplot';
import React from 'react';
export const KeyboardShorcutsHelp = () => {
const KeyboardShorcutsHelp = () => {
return (
<div id="keyboardTable" style={{ position: 'relative', zIndex: '2' }}>
<table>
@ -142,3 +142,4 @@ export const KeyboardShorcutsHelp = () => {
</div>
);
};
export default KeyboardShorcutsHelp;

View File

@ -16,10 +16,10 @@
* limitations under the License.
*/
import React from 'react';
import ActionConfig from '../../classes/action-config';
import MaterialToolbar from '@mui/material/Toolbar';
import MaterialAppBar from '@mui/material/AppBar';
import { ToolbarMenuItem } from '../toolbar/Toolbar';
import ActionConfig from '../../classes/action/action-config';
/**
* App bar

View File

@ -31,11 +31,12 @@ import Toolbar, { horizontalPosition, configurationBuilder } from './toolbar';
import { theme as defaultEditorTheme } from '../theme';
import ThemeProvider from '@mui/material/styles/ThemeProvider';
import { Theme } from '@mui/material/styles';
import { Notifier } from './footer/styled';
import Footer from './footer';
import { Notifier } from './warning-dialog/styled';
import WarningDialog from './warning-dialog';
import DefaultWidgetManager from '../classes/default-widget-manager';
import AppBar from './app-bar';
import { EditorOptions, EditorProps } from '..';
import Capability from '../classes/action/capability';
const Editor = ({
mapId,
@ -46,22 +47,16 @@ const Editor = ({
theme,
accountConfiguration,
}: EditorProps) => {
const [isMobile, setIsMobile] = useState(undefined);
const [mindplotComponent, setMindplotComponent]: [MindplotWebComponent | undefined, Function] =
useState();
const {
editMode,
showOnlyCommonActions,
showAccessChangeActions,
showMapEntityActions,
showMindMapNodesActions,
showPersistenceActions,
} = getToolsVisibilityConfiguration(options, isMobile);
const editorTheme: Theme = theme ? theme : defaultEditorTheme;
const [toolbarsRerenderSwitch, setToolbarsRerenderSwitch] = useState(0);
const toolbarConfiguration = useRef([]);
// Load mindmap ...
const capability = new Capability(options.mode, options.locked);
const mindplotRef = useCallback((node: MindplotWebComponent) => {
setMindplotComponent(node);
}, []);
@ -78,23 +73,23 @@ const Editor = ({
};
useEffect(() => {
if (mindplotComponent === undefined) return;
if (mindplotComponent === undefined) {
return;
}
// Change page title ...
document.title = `${options.mapTitle} | WiseMapping `;
// Load mindmap ...
const designer = onLoadDesigner(mapId, options, persistenceManager);
// Register events ...
designer.addEvent('onblur', onNodeBlurHandler);
designer.addEvent('onfocus', onNodeFocusHandler);
designer.addEvent('modelUpdate', onNodeFocusHandler);
designer.getWorkSpace().getScreenManager().addEvent('update', onNodeFocusHandler);
if (editMode) {
// Is the save action enabled ... ?
if (!capability.isHidden('save')) {
// Register unload save ...
window.addEventListener('beforeunload', () => {
mindplotComponent.save(false);
@ -115,8 +110,6 @@ const Editor = ({
mindplotComponent.loadMap(mapId);
setIsMobile(checkMobile());
if (options.locked) {
$notify(options.lockedMsg, false);
}
@ -130,17 +123,6 @@ const Editor = ({
}
}, [options.enableKeyboardEvents]);
const checkMobile = () => {
const check =
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(
navigator.userAgent.toLowerCase(),
) ||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
navigator.userAgent.toLowerCase().substring(0, 4),
);
return check;
};
const onLoadDesigner = (
_mapId: string,
_options: EditorOptions,
@ -153,20 +135,18 @@ const Editor = ({
const locale = options.locale;
const msg = I18nMsg.loadLocaleData(locale);
const menubarConfiguration = configurationBuilder.buildEditorAppBarConfiguration(
mindplotComponent?.getDesigner(),
options.mapTitle,
capability,
onAction,
() => {
mindplotComponent.save(true);
},
showOnlyCommonActions,
showAccessChangeActions,
showMapEntityActions,
showMindMapNodesActions,
showPersistenceActions,
);
if (options.mode !== 'showcase') {
if (capability && !capability.isHidden('account')) {
menubarConfiguration.push({
render: () => accountConfiguration,
});
@ -197,7 +177,7 @@ const Editor = ({
>
{widgetManager.getEditorContent()}
</Popover>
{showMindMapNodesActions && (
{!capability.isHidden('edition-toolbar') && (
<Toolbar
configurations={toolbarConfiguration.current}
rerender={toolbarsRerenderSwitch}
@ -205,7 +185,7 @@ const Editor = ({
)}
<Toolbar
configurations={configurationBuilder.buildZoomToolbarConfiguration(
isMobile,
capability,
mindplotComponent?.getDesigner(),
)}
position={horizontalPosition}
@ -218,28 +198,9 @@ const Editor = ({
locale={options.locale}
></mindplot-component>
<Notifier id="headerNotifier"></Notifier>
<Footer editorMode={options.mode} isMobile={isMobile}></Footer>
<WarningDialog capability={capability}></WarningDialog>
</IntlProvider>
</ThemeProvider>
);
};
export default Editor;
function getToolsVisibilityConfiguration(options: EditorOptions, isMobile: any) {
const editMode = options.mode === 'edition-owner' || options.mode === 'edition-editor';
const showcaseMode = options.mode === 'showcase';
const showMindMapNodesActions = (editMode || showcaseMode) && !isMobile && !options.locked;
const showMapEntityActions = editMode && !isMobile;
const showAccessChangeActions = options.mode === 'edition-owner' && !isMobile;
const showPersistenceActions = editMode && !isMobile && !options.locked;
const showOnlyCommonActions = options.mode === 'viewonly' || isMobile;
return {
editMode,
showOnlyCommonActions,
showAccessChangeActions,
showMapEntityActions,
showMindMapNodesActions,
showPersistenceActions,
};
}

View File

@ -23,8 +23,8 @@ import Popover, { PopoverOrigin } from '@mui/material/Popover';
import Tooltip from '@mui/material/Tooltip';
import '../app-bar/styles.css';
import Box from '@mui/material/Box';
import ActionConfig from '../../classes/action-config';
import ToolbarPosition, { defaultPosition } from './ToolbarPositionInterface';
import ActionConfig from '../../classes/action/action-config';
/**
* Common button
@ -122,7 +122,9 @@ export const ToolbarSubmenu = (props: {
>
<div style={{ display: 'flex' }} onScroll={(e) => e.stopPropagation()}>
{props.configuration.options?.map((o, i) => {
if (o?.visible === false) return null;
if (o?.visible === false) {
return null;
}
if (!o?.render) {
return (
<ToolbarMenuItem

View File

@ -1,20 +1,3 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import BrushOutlinedIcon from '@mui/icons-material/BrushOutlined';
import FontDownloadOutlinedIcon from '@mui/icons-material/FontDownloadOutlined';
@ -51,20 +34,21 @@ import LogoTextBlackSvg from '../../../images/logo-text-black.svg';
import Palette from '@mui/icons-material/Square';
import SquareOutlined from '@mui/icons-material/SquareOutlined';
import { $msg, Designer } from '@wisemapping/mindplot';
import ActionConfig from '../../classes/action-config';
import ActionConfig from '../../classes/action/action-config';
import { SwitchValueDirection } from './ToolbarValueModelBuilder';
import NodePropertyBuilder from '../../classes/model/node-property-builder';
import NodePropertyValueModelBuilder from '../../classes/model/node-property-builder';
import Typography from '@mui/material/Typography';
import { ToolbarActionType } from '.';
import KeyboardOutlined from '@mui/icons-material/KeyboardOutlined';
import Tooltip from '@mui/material/Tooltip';
import ColorPicker from '../action-widget/pane/color-picker';
import { KeyboardShorcutsHelp } from '../action-widget/pane/keyboard-shortcut-help';
import KeyboardShorcutsHelp from '../action-widget/pane/keyboard-shortcut-help';
import UndoAndRedo from '../action-widget/button/undo-and-redo';
import TopicLink from '../action-widget/pane/topic-link';
import TopicNote from '../action-widget/pane/topic-note';
import IconPicker from '../action-widget/pane/icon-picker';
import FontFamilySelector from '../action-widget/button/font-family-selector';
import Capability from '../../classes/action/capability';
/**
*
@ -77,7 +61,7 @@ export function buildToolbarCongiruation(designer: Designer): ActionConfig[] {
/**
* model builder
*/
const toolbarValueModelBuilder = new NodePropertyBuilder(designer);
const toolbarValueModelBuilder = new NodePropertyValueModelBuilder(designer);
// <div id="rectagle" model="rectagle"><img src="${RectangleImage}" alt="Rectangle"></div>
// <div id="rounded_rectagle" model="rounded rectagle" ><img src="${RectangleRoundImage}" alt="Rounded Rectangle"></div>
@ -318,14 +302,17 @@ export function buildToolbarCongiruation(designer: Designer): ActionConfig[] {
];
}
export function buildZoomToolbarConfiguration(isMobile: boolean, designer: Designer) {
export function buildZoomToolbarConfiguration(
capability: Capability,
designer: Designer,
): ActionConfig[] {
if (!designer) return [];
return [
{
icon: <KeyboardOutlined />,
tooltip: $msg('KEYBOARD_SHOTCUTS'),
visible: !isMobile,
visible: !capability.isHidden('keyboard-shortcuts'),
options: [
{
render: () => <KeyboardShorcutsHelp />,
@ -345,21 +332,21 @@ export function buildZoomToolbarConfiguration(isMobile: boolean, designer: Desig
{
icon: <ZoomInOutlinedIcon />,
tooltip: $msg('ZOOM_IN'),
onClick: (e) => {
onClick: () => {
designer.zoomIn();
},
},
{
icon: <ZoomOutOutlinedIcon />,
tooltip: $msg('ZOOM_OUT'),
onClick: (e) => {
onClick: () => {
designer.zoomOut();
},
},
{
icon: <CenterFocusStrongOutlinedIcon />,
tooltip: $msg('CENTER_POSITION'),
onClick: (e) => {
onClick: () => {
designer.zoomToFit();
},
},
@ -369,17 +356,15 @@ export function buildZoomToolbarConfiguration(isMobile: boolean, designer: Desig
export function buildEditorAppBarConfiguration(
designer: Designer,
mapTitle: string,
capability: Capability,
onAction: (type: ToolbarActionType) => void,
save: () => void,
showOnlyCommonActions: boolean,
showAccessChangeActions: boolean,
showMapEntityActions: boolean,
showMindMapNodesActions: boolean,
showPersistenceActions: boolean,
): ActionConfig[] {
if (!designer) return [];
if (!designer) {
return [];
}
let commonConfiguration = [
let commonConfiguration: ActionConfig[] = [
{
icon: <ArrowBackIosNewOutlinedIcon />,
tooltip: $msg('BACK_TO_MAP_LIST'),
@ -404,26 +389,10 @@ export function buildEditorAppBarConfiguration(
},
];
const exportConfiguration: ActionConfig = {
icon: <FileDownloadOutlinedIcon />,
tooltip: $msg('EXPORT'),
onClick: () => onAction('export'),
};
const helpConfiguration: ActionConfig = {
icon: <HelpOutlineOutlinedIcon />,
onClick: () => onAction('info'),
tooltip: $msg('MAP_INFO'),
};
const appBarDivisor = {
render: () => <Typography component="div" sx={{ flexGrow: 1 }} />,
};
if (showOnlyCommonActions) {
return [...commonConfiguration, appBarDivisor, exportConfiguration];
}
return [
...commonConfiguration,
null,
@ -438,7 +407,7 @@ export function buildEditorAppBarConfiguration(
disabledCondition={(event) => event.undoSteps > 0}
></UndoAndRedo>
),
visible: showMindMapNodesActions,
visible: !capability.isHidden('undo-changes'),
},
{
render: () => (
@ -451,46 +420,61 @@ export function buildEditorAppBarConfiguration(
disabledCondition={(event) => event.redoSteps > 0}
></UndoAndRedo>
),
visible: showMindMapNodesActions,
visible: !capability.isHidden('redo-changes'),
},
null,
{
icon: <RestoreOutlinedIcon />,
tooltip: $msg('HISTORY'),
onClick: () => onAction('history'),
visible: showPersistenceActions,
visible: !capability.isHidden('history'),
},
{
icon: <SaveOutlinedIcon />,
tooltip: $msg('SAVE') + ' (' + $msg('CTRL') + ' + S)',
onClick: save,
visible: showPersistenceActions,
visible: !capability.isHidden('save'),
},
appBarDivisor,
{
icon: <PrintOutlinedIcon />,
tooltip: $msg('PRINT'),
onClick: () => onAction('print'),
visible: showMapEntityActions,
visible: !capability.isHidden('print'),
},
{
icon: <FileDownloadOutlinedIcon />,
tooltip: $msg('EXPORT'),
onClick: () => onAction('export'),
visible: !capability.isHidden('export'),
},
exportConfiguration,
{
icon: <CloudUploadOutlinedIcon />,
onClick: () => onAction('publish'),
tooltip: $msg('PUBLISH'),
disabled: () => !showAccessChangeActions,
visible: !capability.isHidden('publish'),
},
{
render: () => (
<Button
variant="contained"
onClick={() => onAction('share')}
disabled={!showAccessChangeActions}
>
<Button variant="contained" onClick={() => onAction('share')}>
{$msg('COLLABORATE')}
</Button>
),
visible: !capability.isHidden('share'),
},
{
render: () => (
<Button variant="contained" onClick={() => (window.location.href = '/c/registration')}>
{$msg('SIGN_UP')}
</Button>
),
visible: !capability.isHidden('sign-up'),
},
{
icon: <HelpOutlineOutlinedIcon />,
onClick: () => onAction('info'),
tooltip: $msg('MAP_INFO'),
visible: !capability.isHidden('info'),
},
helpConfiguration,
];
}

View File

@ -20,36 +20,30 @@ import { Notifier } from './styled';
import { useIntl } from 'react-intl';
import CloseDialogSvg from '../../../images/close-dialog-icon.svg';
import { EditorRenderMode } from '@wisemapping/mindplot';
import { Button } from '@mui/material';
import Capability from '../../classes/action/capability';
export type FooterPropsType = {
editorMode: EditorRenderMode;
isMobile: boolean;
capability: Capability;
};
const Footer = ({ editorMode, isMobile }: FooterPropsType): React.ReactElement => {
const WarningDialog = ({ capability }: FooterPropsType): React.ReactElement => {
const intl = useIntl();
const [dialogClass, setDialogClass] = useState('tryInfoPanel');
var titleKey = undefined;
var descriptionKey = undefined;
var showSignupButton = undefined;
if (editorMode !== 'viewonly' && editorMode !== 'showcase' && isMobile) {
if (capability.mode !== 'viewonly' && capability.mode !== 'showcase' && capability.isMobile) {
titleKey = 'editor.edit-mobile';
descriptionKey = 'editor.edit-description-mobile';
showSignupButton = false;
}
if (editorMode === 'showcase' && isMobile) {
if (capability.mode === 'showcase' && capability.isMobile) {
titleKey = 'editor.try-welcome-mobile';
descriptionKey = 'editor.edit-description-mobile';
showSignupButton = true;
}
if (editorMode === 'showcase' && !isMobile) {
if (capability.mode === 'showcase' && !capability.isMobile) {
titleKey = 'editor.try-welcome';
descriptionKey = 'editor.try-welcome-description';
showSignupButton = true;
}
// if the toolbar is present, the alert must not overlap
@ -75,13 +69,6 @@ const Footer = ({ editorMode, isMobile }: FooterPropsType): React.ReactElement =
<p>
{intl.formatMessage({ id: titleKey })} {intl.formatMessage({ id: descriptionKey })}
</p>
{showSignupButton && (
<a href="/c/registration">
<Button>
{intl.formatMessage({ id: 'login.signup', defaultMessage: 'Sign Up' })}
</Button>
</a>
)}
</div>
</div>
)}
@ -89,4 +76,4 @@ const Footer = ({ editorMode, isMobile }: FooterPropsType): React.ReactElement =
);
};
export default Footer;
export default WarningDialog;

View File

@ -9,8 +9,8 @@ import Toolbar, {
ToolbarMenuItem,
ToolbarSubmenu,
} from '../../../src/components/toolbar/Toolbar';
import ActionConfig from '../../../src/classes/action-config';
import AppBar from '../../../src/components/app-bar';
import ActionConfig from '../../../src/classes/action/action-config';
require('babel-polyfill');
jest.mock('../../../src/components/app-bar/styles.css', () => '');

View File

@ -1,7 +1,26 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
type EditorRenderMode =
| 'viewonly'
| 'edition-owner'
| 'edition-editor'
| 'edition-viewer'
| 'showcase';
| 'showcase'
| 'edition-locked';
export default EditorRenderMode;

View File

@ -95,6 +95,7 @@ const DE = {
FONT_FORMAT: 'Schriftformat',
FONT_INCREASE: 'Schriftgröße erhöhen',
FONT_DECREASE: 'Schriftgröße verringern',
SIGN_UP: 'Anmelden',
};
export default DE;

View File

@ -95,6 +95,7 @@ const EN = {
FONT_FORMAT: 'Font Format',
FONT_INCREASE: 'Font Size Increase',
FONT_DECREASE: 'Font Size Decrease',
SIGN_UP: 'Sign Up',
};
export default EN;

View File

@ -95,6 +95,7 @@ const ES = {
FONT_FORMAT: 'Formato de Fuente',
FONT_INCREASE: 'Incrementar Tamaño de Fuente',
FONT_DECREASE: 'Decrementar Tamaño de Fuente',
SIGN_UP: 'Registrarse',
};
export default ES;

View File

@ -95,6 +95,7 @@ const FR = {
FONT_FORMAT: 'Format de la police',
FONT_INCREASE: 'Augmentation de la taille de la police',
FONT_DECREASE: 'Diminution de la taille de la police',
SIGN_UP: 'S\'inscrire',
};
export default FR;

View File

@ -95,6 +95,7 @@ const EN = {
FONT_FORMAT: 'Формат шрифта',
FONT_INCREASE: 'Увеличение размера шрифта',
FONT_DECREASE: 'Уменьшение размера шрифта',
SIGN_UP: 'зарегистрироваться',
};
export default EN;

View File

@ -95,6 +95,7 @@ const ZH = {
FONT_FORMAT: '字体格​​式',
FONT_INCREASE: '字体大小增加',
FONT_DECREASE: '字体大小减小',
SIGN_UP: '报名',
};
export default ZH;