mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-11 01:43:23 +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()}>
|
<div style={{ display: 'flex' }} onScroll={(e) => e.stopPropagation()}>
|
||||||
{props.configuration.options?.map((o, i) => {
|
{props.configuration.options?.map((o, i) => {
|
||||||
|
if (o?.visible === false) return null;
|
||||||
if (!o?.render) {
|
if (!o?.render) {
|
||||||
return (
|
return (
|
||||||
<ToolbarMenuItem
|
<ToolbarMenuItem
|
||||||
|
@ -38,7 +38,7 @@ export interface ToolbarOptionConfiguration {
|
|||||||
*/
|
*/
|
||||||
useClickToClose?: boolean;
|
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;
|
visible?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ import Box from '@mui/material/Box';
|
|||||||
import LogoTextBlackSvg from '../../../images/logo-text-black.svg';
|
import LogoTextBlackSvg from '../../../images/logo-text-black.svg';
|
||||||
import Palette from '@mui/icons-material/Square';
|
import Palette from '@mui/icons-material/Square';
|
||||||
import SquareOutlined from '@mui/icons-material/SquareOutlined';
|
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 { ToolbarOptionConfiguration } from './ToolbarOptionConfigurationInterface';
|
||||||
import { SwitchValueDirection, NodePropertyValueModelBuilder } from './ToolbarValueModelBuilder';
|
import { SwitchValueDirection, NodePropertyValueModelBuilder } from './ToolbarValueModelBuilder';
|
||||||
import {
|
import {
|
||||||
@ -354,9 +354,14 @@ export function buildEditorAppBarConfiguration(
|
|||||||
designer: Designer,
|
designer: Designer,
|
||||||
onAction: (type: ToolbarActionType) => void,
|
onAction: (type: ToolbarActionType) => void,
|
||||||
save: () => void,
|
save: () => void,
|
||||||
editorMode: EditorRenderMode,
|
showOnlyCommonActions: boolean,
|
||||||
isMobile: boolean,
|
showAccessChangeActions: boolean,
|
||||||
|
showMapEntityActions: boolean,
|
||||||
|
showMindMapNodesActions: boolean,
|
||||||
|
showPersistenceActions: boolean,
|
||||||
): ToolbarOptionConfiguration[] {
|
): ToolbarOptionConfiguration[] {
|
||||||
|
if (!designer) return [];
|
||||||
|
|
||||||
let commonConfiguration = [
|
let commonConfiguration = [
|
||||||
{
|
{
|
||||||
icon: <ArrowBackIosNewOutlinedIcon />,
|
icon: <ArrowBackIosNewOutlinedIcon />,
|
||||||
@ -366,104 +371,106 @@ export function buildEditorAppBarConfiguration(
|
|||||||
{
|
{
|
||||||
render: () => <img src={LogoTextBlackSvg} />,
|
render: () => <img src={LogoTextBlackSvg} />,
|
||||||
},
|
},
|
||||||
];
|
{
|
||||||
if (editorMode === 'viewonly' || editorMode === 'showcase' || isMobile)
|
render: () => (
|
||||||
return commonConfiguration;
|
<Tooltip title={designer.getMindmap().getCentralTopic().getText()}>
|
||||||
if (!designer) return [];
|
<Typography
|
||||||
|
className="truncated"
|
||||||
const isEditor =
|
variant="body1"
|
||||||
editorMode === 'edition-owner' ||
|
component="div"
|
||||||
editorMode === 'edition-editor' ||
|
sx={{ marginX: '1.5rem' }}
|
||||||
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'}
|
|
||||||
>
|
>
|
||||||
{$msg('COLLABORATE')}
|
{designer.getMindmap().getCentralTopic().getText()}
|
||||||
</Button>
|
</Typography>
|
||||||
),
|
</Tooltip>
|
||||||
},
|
),
|
||||||
{
|
},
|
||||||
icon: <HelpOutlineOutlinedIcon />,
|
];
|
||||||
onClick: () => onAction('info'),
|
|
||||||
tooltip: $msg('MAP_INFO'),
|
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] =
|
const [mindplotComponent, setMindplotComponent]: [MindplotWebComponent | undefined, Function] =
|
||||||
useState();
|
useState();
|
||||||
|
|
||||||
const editMode =
|
const {
|
||||||
options.mode === 'edition-owner' ||
|
editMode,
|
||||||
options.mode === 'edition-editor' ||
|
showOnlyCommonActions,
|
||||||
options.mode === 'edition-viewer';
|
showAccessChangeActions,
|
||||||
|
showMapEntityActions,
|
||||||
|
showMindMapNodesActions,
|
||||||
|
showPersistenceActions,
|
||||||
|
} = getToolsVisibilityConfiguration(options, isMobile);
|
||||||
|
|
||||||
const editorTheme: Theme = theme ? theme : defaultEditorTheme;
|
const editorTheme: Theme = theme ? theme : defaultEditorTheme;
|
||||||
const [toolbarsRerenderSwitch, setToolbarsRerenderSwitch] = useState(0);
|
const [toolbarsRerenderSwitch, setToolbarsRerenderSwitch] = useState(0);
|
||||||
const toolbarConfiguration = useRef([]);
|
const toolbarConfiguration = useRef([]);
|
||||||
@ -200,12 +205,24 @@ const Editor = ({
|
|||||||
() => {
|
() => {
|
||||||
mindplotComponent.save(true);
|
mindplotComponent.save(true);
|
||||||
},
|
},
|
||||||
options.mode,
|
showOnlyCommonActions,
|
||||||
isMobile,
|
showAccessChangeActions,
|
||||||
|
showMapEntityActions,
|
||||||
|
showMindMapNodesActions,
|
||||||
|
showPersistenceActions,
|
||||||
);
|
);
|
||||||
menubarConfiguration.push({
|
if (options.mode !== 'showcase') {
|
||||||
render: () => accountConfiguration,
|
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 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
|
// 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
|
// 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()}
|
{widgetManager.getEditorContent()}
|
||||||
</Popover>
|
</Popover>
|
||||||
{editMode && !isMobile && (
|
{showMindMapNodesActions && (
|
||||||
<Toolbar
|
<Toolbar
|
||||||
configurations={toolbarConfiguration.current}
|
configurations={toolbarConfiguration.current}
|
||||||
rerender={toolbarsRerenderSwitch}
|
rerender={toolbarsRerenderSwitch}
|
||||||
@ -252,3 +269,20 @@ const Editor = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default 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>
|
<ul>
|
||||||
<li><a href="/showcase.html">Sample</a></li>
|
<li><a href="/showcase.html">Sample</a></li>
|
||||||
</ul>
|
</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>
|
</div>
|
||||||
</body>
|
</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'),
|
viewmode: path.resolve(__dirname, './test/playground/map-render/js/viewmode'),
|
||||||
editor: path.resolve(__dirname, './test/playground/map-render/js/editor'),
|
editor: path.resolve(__dirname, './test/playground/map-render/js/editor'),
|
||||||
showcase: path.resolve(__dirname, './test/playground/map-render/js/showcase'),
|
showcase: path.resolve(__dirname, './test/playground/map-render/js/showcase'),
|
||||||
|
editorlocked: path.resolve(__dirname, './test/playground/map-render/js/editorlocked'),
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'test/playground/dist'),
|
path: path.resolve(__dirname, 'test/playground/dist'),
|
||||||
@ -53,6 +54,11 @@ const playgroundConfig = {
|
|||||||
filename: 'showcase.html',
|
filename: 'showcase.html',
|
||||||
template: 'test/playground/map-render/html/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