mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-12-22 11:43:48 +01:00
Merged in editor-actions-by-mode (pull request #63)
Editor actions by mode * Toolbar configuration for all EditorRenderMode and locked maps * fix unlock
This commit is contained in:
parent
f3a11f2eb1
commit
c6f04742d8
@ -105,6 +105,7 @@ 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?.render) {
|
||||
return (
|
||||
<ToolbarMenuItem
|
||||
|
@ -38,7 +38,7 @@ export interface ToolbarOptionConfiguration {
|
||||
*/
|
||||
useClickToClose?: boolean;
|
||||
/**
|
||||
* if false the nmenu entry or button is not visible. Entries with custom render will ignore this property
|
||||
* if false the nmenu entry or button is not visible. Also custom render will be ignored.
|
||||
*/
|
||||
visible?: boolean;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import Box from '@mui/material/Box';
|
||||
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, EditorRenderMode } from '@wisemapping/mindplot';
|
||||
import { $msg, Designer } from '@wisemapping/mindplot';
|
||||
import { ToolbarOptionConfiguration } from './ToolbarOptionConfigurationInterface';
|
||||
import { SwitchValueDirection, NodePropertyValueModelBuilder } from './ToolbarValueModelBuilder';
|
||||
import {
|
||||
@ -354,9 +354,14 @@ export function buildEditorAppBarConfiguration(
|
||||
designer: Designer,
|
||||
onAction: (type: ToolbarActionType) => void,
|
||||
save: () => void,
|
||||
editorMode: EditorRenderMode,
|
||||
isMobile: boolean,
|
||||
showOnlyCommonActions: boolean,
|
||||
showAccessChangeActions: boolean,
|
||||
showMapEntityActions: boolean,
|
||||
showMindMapNodesActions: boolean,
|
||||
showPersistenceActions: boolean,
|
||||
): ToolbarOptionConfiguration[] {
|
||||
if (!designer) return [];
|
||||
|
||||
let commonConfiguration = [
|
||||
{
|
||||
icon: <ArrowBackIosNewOutlinedIcon />,
|
||||
@ -366,104 +371,106 @@ export function buildEditorAppBarConfiguration(
|
||||
{
|
||||
render: () => <img src={LogoTextBlackSvg} />,
|
||||
},
|
||||
];
|
||||
if (editorMode === 'viewonly' || editorMode === 'showcase' || isMobile)
|
||||
return commonConfiguration;
|
||||
if (!designer) return [];
|
||||
|
||||
const isEditor =
|
||||
editorMode === 'edition-owner' ||
|
||||
editorMode === 'edition-editor' ||
|
||||
editorMode === 'edition-viewer';
|
||||
|
||||
if (isEditor) {
|
||||
return [
|
||||
...commonConfiguration,
|
||||
{
|
||||
render: () => (
|
||||
<Tooltip title={designer.getMindmap().getCentralTopic().getText()}>
|
||||
<Typography
|
||||
className="truncated"
|
||||
variant="body1"
|
||||
component="div"
|
||||
sx={{ marginX: '1.5rem' }}
|
||||
>
|
||||
{designer.getMindmap().getCentralTopic().getText()}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
null,
|
||||
{
|
||||
render: () => (
|
||||
<UndoAndRedoButton
|
||||
configuration={{
|
||||
icon: <UndoOutlinedIcon />,
|
||||
tooltip: $msg('UNDO') + ' (' + $msg('CTRL') + ' + Z)',
|
||||
onClick: () => designer.undo(),
|
||||
}}
|
||||
disabledCondition={(event) => event.undoSteps > 0}
|
||||
></UndoAndRedoButton>
|
||||
),
|
||||
},
|
||||
{
|
||||
render: () => (
|
||||
<UndoAndRedoButton
|
||||
configuration={{
|
||||
icon: <RedoOutlinedIcon />,
|
||||
tooltip: $msg('REDO') + ' (' + $msg('CTRL') + ' + Shift + Z)',
|
||||
onClick: () => designer.redo(),
|
||||
}}
|
||||
disabledCondition={(event) => event.redoSteps > 0}
|
||||
></UndoAndRedoButton>
|
||||
),
|
||||
},
|
||||
null,
|
||||
{
|
||||
icon: <RestoreOutlinedIcon />,
|
||||
tooltip: $msg('HISTORY'),
|
||||
onClick: () => onAction('history'),
|
||||
},
|
||||
{
|
||||
icon: <SaveOutlinedIcon />,
|
||||
tooltip: $msg('SAVE') + ' (' + $msg('CTRL') + ' + S)',
|
||||
onClick: save,
|
||||
},
|
||||
{
|
||||
render: () => <Typography component="div" sx={{ flexGrow: 1 }} />,
|
||||
},
|
||||
{
|
||||
icon: <PrintOutlinedIcon />,
|
||||
tooltip: $msg('PRINT'),
|
||||
onClick: () => onAction('print'),
|
||||
},
|
||||
{
|
||||
icon: <FileDownloadOutlinedIcon />,
|
||||
tooltip: $msg('EXPORT'),
|
||||
onClick: () => onAction('export'),
|
||||
},
|
||||
{
|
||||
icon: <CloudUploadOutlinedIcon />,
|
||||
onClick: () => onAction('publish'),
|
||||
tooltip: $msg('PUBLISH'),
|
||||
disabled: () => editorMode !== 'edition-owner',
|
||||
},
|
||||
{
|
||||
render: () => (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => onAction('share')}
|
||||
disabled={editorMode !== 'edition-owner'}
|
||||
{
|
||||
render: () => (
|
||||
<Tooltip title={designer.getMindmap().getCentralTopic().getText()}>
|
||||
<Typography
|
||||
className="truncated"
|
||||
variant="body1"
|
||||
component="div"
|
||||
sx={{ marginX: '1.5rem' }}
|
||||
>
|
||||
{$msg('COLLABORATE')}
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
icon: <HelpOutlineOutlinedIcon />,
|
||||
onClick: () => onAction('info'),
|
||||
tooltip: $msg('MAP_INFO'),
|
||||
},
|
||||
];
|
||||
}
|
||||
{designer.getMindmap().getCentralTopic().getText()}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const exportConfiguration = {
|
||||
icon: <FileDownloadOutlinedIcon />,
|
||||
tooltip: $msg('EXPORT'),
|
||||
onClick: () => onAction('export'),
|
||||
};
|
||||
const helpConfiguration = {
|
||||
icon: <HelpOutlineOutlinedIcon />,
|
||||
onClick: () => onAction('info'),
|
||||
tooltip: $msg('MAP_INFO'),
|
||||
};
|
||||
const appBarDivisor = {
|
||||
render: () => <Typography component="div" sx={{ flexGrow: 1 }} />,
|
||||
};
|
||||
|
||||
if (showOnlyCommonActions)
|
||||
return [...commonConfiguration, appBarDivisor, exportConfiguration, helpConfiguration];
|
||||
|
||||
return [
|
||||
...commonConfiguration,
|
||||
null,
|
||||
{
|
||||
render: () => (
|
||||
<UndoAndRedoButton
|
||||
configuration={{
|
||||
icon: <UndoOutlinedIcon />,
|
||||
tooltip: $msg('UNDO') + ' (' + $msg('CTRL') + ' + Z)',
|
||||
onClick: () => designer.undo(),
|
||||
}}
|
||||
disabledCondition={(event) => event.undoSteps > 0}
|
||||
></UndoAndRedoButton>
|
||||
),
|
||||
visible: showMindMapNodesActions,
|
||||
},
|
||||
{
|
||||
render: () => (
|
||||
<UndoAndRedoButton
|
||||
configuration={{
|
||||
icon: <RedoOutlinedIcon />,
|
||||
tooltip: $msg('REDO') + ' (' + $msg('CTRL') + ' + Shift + Z)',
|
||||
onClick: () => designer.redo(),
|
||||
}}
|
||||
disabledCondition={(event) => event.redoSteps > 0}
|
||||
></UndoAndRedoButton>
|
||||
),
|
||||
visible: showMindMapNodesActions,
|
||||
},
|
||||
null,
|
||||
{
|
||||
icon: <RestoreOutlinedIcon />,
|
||||
tooltip: $msg('HISTORY'),
|
||||
onClick: () => onAction('history'),
|
||||
visible: showPersistenceActions,
|
||||
},
|
||||
{
|
||||
icon: <SaveOutlinedIcon />,
|
||||
tooltip: $msg('SAVE') + ' (' + $msg('CTRL') + ' + S)',
|
||||
onClick: save,
|
||||
visible: showPersistenceActions,
|
||||
},
|
||||
appBarDivisor,
|
||||
{
|
||||
icon: <PrintOutlinedIcon />,
|
||||
tooltip: $msg('PRINT'),
|
||||
onClick: () => onAction('print'),
|
||||
visible: showMapEntityActions,
|
||||
},
|
||||
exportConfiguration,
|
||||
{
|
||||
icon: <CloudUploadOutlinedIcon />,
|
||||
onClick: () => onAction('publish'),
|
||||
tooltip: $msg('PUBLISH'),
|
||||
disabled: () => !showAccessChangeActions,
|
||||
},
|
||||
{
|
||||
render: () => (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => onAction('share')}
|
||||
disabled={!showAccessChangeActions}
|
||||
>
|
||||
{$msg('COLLABORATE')}
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
helpConfiguration,
|
||||
];
|
||||
}
|
||||
|
@ -96,10 +96,15 @@ const Editor = ({
|
||||
const [mindplotComponent, setMindplotComponent]: [MindplotWebComponent | undefined, Function] =
|
||||
useState();
|
||||
|
||||
const editMode =
|
||||
options.mode === 'edition-owner' ||
|
||||
options.mode === 'edition-editor' ||
|
||||
options.mode === 'edition-viewer';
|
||||
const {
|
||||
editMode,
|
||||
showOnlyCommonActions,
|
||||
showAccessChangeActions,
|
||||
showMapEntityActions,
|
||||
showMindMapNodesActions,
|
||||
showPersistenceActions,
|
||||
} = getToolsVisibilityConfiguration(options, isMobile);
|
||||
|
||||
const editorTheme: Theme = theme ? theme : defaultEditorTheme;
|
||||
const [toolbarsRerenderSwitch, setToolbarsRerenderSwitch] = useState(0);
|
||||
const toolbarConfiguration = useRef([]);
|
||||
@ -200,12 +205,24 @@ const Editor = ({
|
||||
() => {
|
||||
mindplotComponent.save(true);
|
||||
},
|
||||
options.mode,
|
||||
isMobile,
|
||||
showOnlyCommonActions,
|
||||
showAccessChangeActions,
|
||||
showMapEntityActions,
|
||||
showMindMapNodesActions,
|
||||
showPersistenceActions,
|
||||
);
|
||||
menubarConfiguration.push({
|
||||
render: () => accountConfiguration,
|
||||
});
|
||||
if (options.mode !== 'showcase') {
|
||||
menubarConfiguration.push({
|
||||
render: () => accountConfiguration,
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
mindplotComponent.unlockMap();
|
||||
};
|
||||
}, []);
|
||||
|
||||
// if the Toolbar is not hidden before the variable 'isMobile' is defined, it appears intermittently when the page loads
|
||||
// if the Toolbar is not rendered, Menu.ts cant find buttons for create event listeners
|
||||
// so, with this hack the Toolbar is rendered but no visible until the variable 'isMobile' is defined
|
||||
@ -225,7 +242,7 @@ const Editor = ({
|
||||
>
|
||||
{widgetManager.getEditorContent()}
|
||||
</Popover>
|
||||
{editMode && !isMobile && (
|
||||
{showMindMapNodesActions && (
|
||||
<Toolbar
|
||||
configurations={toolbarConfiguration.current}
|
||||
rerender={toolbarsRerenderSwitch}
|
||||
@ -252,3 +269,20 @@ const Editor = ({
|
||||
);
|
||||
};
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
@ -50,6 +50,10 @@
|
||||
<ul>
|
||||
<li><a href="/showcase.html">Sample</a></li>
|
||||
</ul>
|
||||
<p><span class="section">Editor Mode (locked):</span>Example on how mindplot can be used for mindmap edition. Browser local storage is used for persistance.</p>
|
||||
<ul>
|
||||
<li><a href="/editorlocked.html">Sample</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 ReactDOM from 'react-dom';
|
||||
import Editor, { EditorOptions } from '../../../../src/index';
|
||||
import { LocalStorageManager, Designer } from '@wisemapping/mindplot';
|
||||
|
||||
const initialization = (designer: Designer) => {
|
||||
designer.addEvent('loadSuccess', () => {
|
||||
const elem = document.getElementById('mindmap-comp');
|
||||
if (elem) {
|
||||
elem.classList.add('ready');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const persistence = new LocalStorageManager('samples/{id}.wxml', false, false);
|
||||
const mapId = 'welcome';
|
||||
const options: EditorOptions = {
|
||||
zoom: 0.8,
|
||||
locked: true,
|
||||
lockedMsg: 'Blockeado',
|
||||
mapTitle: 'Develop WiseMapping',
|
||||
mode: 'edition-editor',
|
||||
locale: 'en',
|
||||
enableKeyboardEvents: true,
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Editor
|
||||
mapId={mapId}
|
||||
options={options}
|
||||
persistenceManager={persistence}
|
||||
onAction={(action) => console.log('action called:', action)}
|
||||
onLoad={initialization}
|
||||
/>,
|
||||
document.getElementById('root'),
|
||||
);
|
@ -11,6 +11,7 @@ const playgroundConfig = {
|
||||
viewmode: path.resolve(__dirname, './test/playground/map-render/js/viewmode'),
|
||||
editor: path.resolve(__dirname, './test/playground/map-render/js/editor'),
|
||||
showcase: path.resolve(__dirname, './test/playground/map-render/js/showcase'),
|
||||
editorlocked: path.resolve(__dirname, './test/playground/map-render/js/editorlocked'),
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'test/playground/dist'),
|
||||
@ -53,6 +54,11 @@ const playgroundConfig = {
|
||||
filename: 'showcase.html',
|
||||
template: 'test/playground/map-render/html/showcase.html',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
chunks: ['editorlocked'],
|
||||
filename: 'editorlocked.html',
|
||||
template: 'test/playground/map-render/html/editor.html',
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user