mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-11 01:43:23 +01:00
Add editor route and component
This commit is contained in:
parent
516e9b4ded
commit
f84ccfdcbd
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { $msg } from '../Messages';
|
import { $msg } from '../Messages';
|
||||||
import BootstrapDialogRequest from '../libraries/bootstrap/BootstrapDialogRequest';
|
|
||||||
import IMenu from './IMenu';
|
import IMenu from './IMenu';
|
||||||
import FontFamilyPanel from './FontFamilyPanel';
|
import FontFamilyPanel from './FontFamilyPanel';
|
||||||
import FontSizePanel from './FontSizePanel';
|
import FontSizePanel from './FontSizePanel';
|
||||||
@ -38,17 +37,6 @@ class Menu extends IMenu {
|
|||||||
|
|
||||||
const widgetsBaseUrl = `${baseUrl}css/widget`;
|
const widgetsBaseUrl = `${baseUrl}css/widget`;
|
||||||
|
|
||||||
// Stop event propagation ...
|
|
||||||
$(`#${this._containerId}`).bind('click', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$(`#${this._containerId}`).bind('dblclick', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create panels ...
|
// Create panels ...
|
||||||
const designerModel = designer.getModel();
|
const designerModel = designer.getModel();
|
||||||
|
|
||||||
@ -216,38 +204,8 @@ class Menu extends IMenu {
|
|||||||
Menu._registerTooltip('fontColor', $msg('FONT_COLOR'));
|
Menu._registerTooltip('fontColor', $msg('FONT_COLOR'));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._addButton('export', false, false, () => {
|
|
||||||
// @Todo: this must be configured in the dialog...
|
|
||||||
const formatExtension = 'jpg';
|
|
||||||
|
|
||||||
designer.export(formatExtension)
|
|
||||||
.then((url: string) => {
|
|
||||||
// Create hidden anchor to force download ...
|
|
||||||
const anchor: HTMLAnchorElement = document.createElement('a');
|
|
||||||
anchor.style.display = 'display: none';
|
|
||||||
anchor.download = `${mapId}.${formatExtension}`;
|
|
||||||
anchor.href = url;
|
|
||||||
document.body.appendChild(anchor);
|
|
||||||
|
|
||||||
// Trigger click ...
|
|
||||||
anchor.click();
|
|
||||||
|
|
||||||
// Clean up ...
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
document.body.removeChild(anchor);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create anchor element ...
|
|
||||||
});
|
|
||||||
|
|
||||||
Menu._registerTooltip('export', $msg('EXPORT'));
|
Menu._registerTooltip('export', $msg('EXPORT'));
|
||||||
|
|
||||||
this._addButton('print', false, false, () => {
|
|
||||||
this.save(saveElem, designer, false);
|
|
||||||
const urlPrefix = window.location.href.substring(0, window.location.href.lastIndexOf('c/maps/'));
|
|
||||||
window.open(`${urlPrefix}c/maps/${mapId}/print`);
|
|
||||||
});
|
|
||||||
|
|
||||||
Menu._registerTooltip('print', $msg('PRINT'));
|
Menu._registerTooltip('print', $msg('PRINT'));
|
||||||
|
|
||||||
this._addButton('zoom-plus', false, false, () => {
|
this._addButton('zoom-plus', false, false, () => {
|
||||||
@ -367,42 +325,6 @@ class Menu extends IMenu {
|
|||||||
Menu._registerTooltip('discard', $msg('DISCARD_CHANGES'));
|
Menu._registerTooltip('discard', $msg('DISCARD_CHANGES'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const shareElem = $('#shareIt');
|
|
||||||
if (shareElem.length !== 0) {
|
|
||||||
this._addButton('shareIt', false, false, () => {
|
|
||||||
new BootstrapDialogRequest(`c/maps/${mapId}/sharef`, $msg('COLLABORATE'), {
|
|
||||||
closeButton: true,
|
|
||||||
cancelButton: true,
|
|
||||||
});
|
|
||||||
designer.onObjectFocusEvent();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('shareIt', $msg('COLLABORATE'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const publishElem = $('#publishIt');
|
|
||||||
if (publishElem.length !== 0) {
|
|
||||||
this._addButton('publishIt', false, false, () => {
|
|
||||||
new BootstrapDialogRequest(`c/maps/${mapId}/publishf`, $msg('PUBLISH'), {
|
|
||||||
closeButton: true,
|
|
||||||
cancelButton: true,
|
|
||||||
});
|
|
||||||
designer.onObjectFocusEvent();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('publishIt', $msg('PUBLISH'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const historyElem = $('#history');
|
|
||||||
if (historyElem.length !== 0) {
|
|
||||||
this._addButton('history', false, false, () => {
|
|
||||||
new BootstrapDialogRequest(`c/maps/${mapId}/historyf`, $msg('HISTORY'), {
|
|
||||||
closeButton: true,
|
|
||||||
cancelButton: true,
|
|
||||||
});
|
|
||||||
designer.onObjectFocusEvent();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('history', $msg('HISTORY'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keyboard Shortcuts Action ...
|
// Keyboard Shortcuts Action ...
|
||||||
const keyboardShortcut = $('#keyboardShortcuts');
|
const keyboardShortcut = $('#keyboardShortcuts');
|
||||||
if (keyboardShortcut.length !== 0) {
|
if (keyboardShortcut.length !== 0) {
|
||||||
|
@ -15,6 +15,7 @@ import MapsPage from './components/maps-page';
|
|||||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||||
import { ThemeProvider } from '@material-ui/core/styles';
|
import { ThemeProvider } from '@material-ui/core/styles';
|
||||||
import GoogleAnalytics from 'react-ga';
|
import GoogleAnalytics from 'react-ga';
|
||||||
|
import Editor from './components/maps-page/editor';
|
||||||
|
|
||||||
// Google Analytics Initialization.
|
// Google Analytics Initialization.
|
||||||
GoogleAnalytics.initialize('UA-0000000-0');
|
GoogleAnalytics.initialize('UA-0000000-0');
|
||||||
@ -31,7 +32,6 @@ const queryClient = new QueryClient({
|
|||||||
const App = (): ReactElement => {
|
const App = (): ReactElement => {
|
||||||
const appi18n = new AppI18n();
|
const appi18n = new AppI18n();
|
||||||
const locale = appi18n.getBrowserLocale();
|
const locale = appi18n.getBrowserLocale();
|
||||||
|
|
||||||
return locale.message ? (
|
return locale.message ? (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
@ -62,9 +62,12 @@ const App = (): ReactElement => {
|
|||||||
path="/c/forgot-password-success"
|
path="/c/forgot-password-success"
|
||||||
component={ForgotPasswordSuccessPage}
|
component={ForgotPasswordSuccessPage}
|
||||||
/>
|
/>
|
||||||
<Route path="/c/maps/">
|
<Route exact path="/c/maps/">
|
||||||
<MapsPage />
|
<MapsPage />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route exact path="/c/maps/:id/edit">
|
||||||
|
<Editor />
|
||||||
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</Router>
|
</Router>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
62
packages/webapp/src/components/maps-page/editor/index.tsx
Normal file
62
packages/webapp/src/components/maps-page/editor/index.tsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Toolbar from './toolbar';
|
||||||
|
import ActionDispatcher from '../action-dispatcher';
|
||||||
|
import { ActionType } from '../action-chooser';
|
||||||
|
|
||||||
|
|
||||||
|
// this component is a hack. In order to work, we need to load externally the "loader.js" script from mindplot
|
||||||
|
// TODO: create the Editor component in the editor package, with its own build and include it instead
|
||||||
|
export default function Editor(): React.ReactElement {
|
||||||
|
const memoryPersistence = false;
|
||||||
|
const readOnlyMode = false;
|
||||||
|
const mapId = 1;
|
||||||
|
const [activeDialog, setActiveDialog] = React.useState<ActionType | null>(null);
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<div id="header">
|
||||||
|
<Toolbar
|
||||||
|
memoryPersistence={memoryPersistence}
|
||||||
|
readOnlyMode={readOnlyMode}
|
||||||
|
onAction={setActiveDialog} />
|
||||||
|
</div>
|
||||||
|
<div id="mindplot"></div>
|
||||||
|
<div id="floating-panel">
|
||||||
|
<div id="keyboardShortcuts" className="buttonExtOn">
|
||||||
|
<img src="../../images/editor/keyboard.svg"/>
|
||||||
|
</div>
|
||||||
|
<div id="zoom-button">
|
||||||
|
<button id="zoom-plus">
|
||||||
|
<img src="../../images/editor/add.svg" />
|
||||||
|
</button>
|
||||||
|
<button id="zoom-minus">
|
||||||
|
<img src="../../images/editor/minus.svg" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="position">
|
||||||
|
<button id="position-button">
|
||||||
|
<img src="../../images/editor/center_focus.svg" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="bottom-logo"></div>
|
||||||
|
<div id="headerNotifier"></div>
|
||||||
|
{
|
||||||
|
memoryPersistence && <div id="tryInfoPanel">
|
||||||
|
<p>TRY_WELCOME</p>
|
||||||
|
<p>TRY_WELCOME_DESC</p>
|
||||||
|
<a href="/c/registration"><div className="actionButton">
|
||||||
|
SIGN_UP</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
activeDialog &&
|
||||||
|
<ActionDispatcher
|
||||||
|
action={activeDialog}
|
||||||
|
onClose={() => setActiveDialog(null)}
|
||||||
|
mapsId={[mapId]}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
112
packages/webapp/src/components/maps-page/editor/toolbar.tsx
Normal file
112
packages/webapp/src/components/maps-page/editor/toolbar.tsx
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { ActionType } from '../action-chooser';
|
||||||
|
|
||||||
|
export type ToolbarPropsType = {
|
||||||
|
memoryPersistence: boolean;
|
||||||
|
readOnlyMode: boolean;
|
||||||
|
onAction: (action: ActionType) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Toolbar({
|
||||||
|
memoryPersistence,
|
||||||
|
readOnlyMode,
|
||||||
|
onAction,
|
||||||
|
}: ToolbarPropsType): React.ReactElement {
|
||||||
|
return (
|
||||||
|
<div id="toolbar">
|
||||||
|
<div id="backToList">
|
||||||
|
<img src="../../images/editor/back-icon.svg" />
|
||||||
|
</div>
|
||||||
|
{!memoryPersistence && (
|
||||||
|
<div id="persist" className="buttonContainer">
|
||||||
|
<div id="save" className="buttonOn">
|
||||||
|
<img src="../../images/editor/save.svg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{!readOnlyMode && (
|
||||||
|
<>
|
||||||
|
<div id="edit" className="buttonContainer">
|
||||||
|
<div id="undoEdition" className="buttonOn">
|
||||||
|
<img src="../../images/editor/undo.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="redoEdition" className="buttonOn">
|
||||||
|
<img src="../../images/editor/redo.svg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="nodeStyle" className="buttonContainer">
|
||||||
|
<div id="addTopic" className="buttonOn">
|
||||||
|
<img src="../../images/editor/topic-add.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="deleteTopic" className="buttonOn">
|
||||||
|
<img src="../../images/editor/topic-delete.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="topicBorder" className="buttonExtOn">
|
||||||
|
<img src="../../images/editor/topic-border.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="topicColor" className="buttonExtOn">
|
||||||
|
<img src="../../images/editor/topic-color.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="topicShape" className="buttonExtOn">
|
||||||
|
<img src="../../images/editor/topic-shape.svg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="font" className="buttonContainer">
|
||||||
|
<div id="fontFamily" className="buttonOn">
|
||||||
|
<img src="../../images/editor/font-type.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="fontSize" className="buttonExtOn">
|
||||||
|
<img src="../../images/editor/font-size.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="fontBold" className="buttonOn">
|
||||||
|
<img src="../../images/editor/font-bold.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="fontItalic" className="buttonOn">
|
||||||
|
<img src="../../images/editor/font-italic.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="fontColor" className="buttonExtOn">
|
||||||
|
<img src="../../images/editor/font-color.svg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="nodeContent" className="buttonContainer">
|
||||||
|
<div id="topicIcon" className="buttonExtOn">
|
||||||
|
<img src="../../images/editor/topic-icon.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="topicNote" className="buttonOn">
|
||||||
|
<img src="../../images/editor/topic-note.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="topicLink" className="buttonOn">
|
||||||
|
<img src="../../images/editor/topic-link.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="topicRelation" className="buttonOn">
|
||||||
|
<img src="../../images/editor/topic-relation.svg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="separator" className="buttonContainer"></div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!memoryPersistence && (
|
||||||
|
<div id="toolbarRight">
|
||||||
|
<div id="export" className="buttonOn" onClick={() => onAction('export')}>
|
||||||
|
<img src="../../images/editor/export.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="publishIt" className="buttonOn" onClick={() => onAction('publish')}>
|
||||||
|
<img src="../../images/editor/public.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="history" className="buttonOn" onClick={() => onAction('history')}>
|
||||||
|
<img src="../../images/editor/history.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="print" className="buttonOn" onClick={() => onAction('print')}>
|
||||||
|
<img src="../../images/editor/print.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="account">
|
||||||
|
<img src="../../images/editor/account.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="share" className="actionButton" onClick={() => onAction('share')}>
|
||||||
|
SHARE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user