Merged in features/move_menu (pull request #47)
Move Menu to editor * Move Menu
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 281 B |
Before Width: | Height: | Size: 172 B After Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 247 B |
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 189 B |
156
packages/editor/src/classes/bootstrap/BootstrapDialog.js
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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 $ from 'jquery';
|
||||
import Options from '@wisemapping/mindplot/src/components/Options';
|
||||
import { $msg } from '@wisemapping/mindplot/src/components/Messages';
|
||||
|
||||
class BootstrapDialog extends Options {
|
||||
constructor(title, options) {
|
||||
super();
|
||||
this.options = {
|
||||
cancelButton: false,
|
||||
closeButton: false,
|
||||
acceptButton: true,
|
||||
removeButton: false,
|
||||
errorMessage: false,
|
||||
onEventData: {},
|
||||
};
|
||||
|
||||
this.setOptions(options);
|
||||
this.options.onEventData.dialog = this;
|
||||
this._native = $('<div class="modal fade" tabindex="-1"></div>').append(
|
||||
'<div class="modal-dialog"></div>',
|
||||
);
|
||||
const content = $('<div class="modal-content"></div>');
|
||||
const header = this._buildHeader(title);
|
||||
|
||||
if (header) {
|
||||
content.append(header);
|
||||
}
|
||||
const body = $('<div class="modal-body"></div>');
|
||||
if (this.options.errorMessage) {
|
||||
const error = $('<div class="alert alert-danger"></div>');
|
||||
error.hide();
|
||||
body.append(error);
|
||||
}
|
||||
content.append(body);
|
||||
const footer = this._buildFooter();
|
||||
if (footer) {
|
||||
content.append(footer);
|
||||
}
|
||||
this._native.find('.modal-dialog').append(content);
|
||||
this._native.on('hidden.bs.modal', function remove() {
|
||||
$(this).remove();
|
||||
});
|
||||
this._native.on('shown.bs.modal', this.onDialogShown);
|
||||
|
||||
this._native.appendTo('#mindplot-tooltips');
|
||||
}
|
||||
|
||||
_buildFooter() {
|
||||
let footer = null;
|
||||
if (this.options.acceptButton || this.options.removeButton || this.options.cancelButton) {
|
||||
footer = $('<div class="modal-footer" style="paddingTop:5;textAlign:center">');
|
||||
}
|
||||
if (this.options.acceptButton) {
|
||||
this.acceptButton = $(
|
||||
`<button type="button" class="btn btn-primary" id="acceptBtn" data-dismiss="modal">${$msg(
|
||||
'ACCEPT',
|
||||
)}</button>`,
|
||||
);
|
||||
footer.append(this.acceptButton);
|
||||
this.acceptButton
|
||||
.unbind('click')
|
||||
.on('click', this.options.onEventData, this.onAcceptClick);
|
||||
}
|
||||
if (this.options.removeButton) {
|
||||
this.removeButton = $(
|
||||
`<button type="button" class="btn btn-secondary" id="removeBtn" data-dismiss="modal">${$msg(
|
||||
'REMOVE',
|
||||
)}</button>`,
|
||||
);
|
||||
footer.append(this.removeButton);
|
||||
this.removeButton.on('click', this.options.onEventData, this.onRemoveClick);
|
||||
}
|
||||
if (this.options.cancelButton) {
|
||||
footer.append(
|
||||
`<button type="button" class="btn btn-secondary" data-dismiss="modal">${$msg(
|
||||
'CANCEL',
|
||||
)}</button>`,
|
||||
);
|
||||
}
|
||||
return footer;
|
||||
}
|
||||
|
||||
_buildHeader(title) {
|
||||
let header = null;
|
||||
if (this.options.closeButton || title) {
|
||||
header = $('<div class="modal-header"></div>');
|
||||
}
|
||||
if (this.options.closeButton) {
|
||||
header.append(
|
||||
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>',
|
||||
);
|
||||
}
|
||||
if (title) {
|
||||
header.append(`<h2 class="modal-title">${title}</h2>`);
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
onAcceptClick() {
|
||||
throw new Error('Unsupported operation');
|
||||
}
|
||||
|
||||
onDialogShown() {
|
||||
// Overwrite default behaviour ...
|
||||
}
|
||||
|
||||
onRemoveClick() {
|
||||
throw new Error('Unsupported operation');
|
||||
}
|
||||
|
||||
show() {
|
||||
this._native.modal();
|
||||
}
|
||||
|
||||
setContent(content) {
|
||||
const modalBody = this._native.find('.modal-body');
|
||||
modalBody.append(content);
|
||||
}
|
||||
|
||||
css(options) {
|
||||
this._native.find('.modal-dialog').css(options);
|
||||
}
|
||||
|
||||
close() {
|
||||
this._native.modal('hide');
|
||||
}
|
||||
|
||||
alertError(message) {
|
||||
this._native.find('.alert-danger').text(message);
|
||||
this._native.find('.alert-danger').show();
|
||||
}
|
||||
|
||||
cleanError() {
|
||||
this._native.find('.alert-danger').hide();
|
||||
}
|
||||
}
|
||||
|
||||
export default BootstrapDialog;
|
68
packages/editor/src/classes/menu/Events.ts
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class Events {
|
||||
private _handlerByType;
|
||||
|
||||
constructor() {
|
||||
this._handlerByType = {};
|
||||
}
|
||||
|
||||
static _normalizeEventName(string: string) {
|
||||
return string.replace(/^on([A-Z])/, (_full, first) => first.toLowerCase());
|
||||
}
|
||||
|
||||
addEvent(typeName: string, fn?, internal?: boolean): Events {
|
||||
const type = Events._normalizeEventName(typeName);
|
||||
|
||||
// Add function had not been added yet
|
||||
const funByType = this._handlerByType[type] ? this._handlerByType[type] : [];
|
||||
if (!funByType.includes(fn)) {
|
||||
funByType.push(fn);
|
||||
this._handlerByType[type] = funByType;
|
||||
}
|
||||
|
||||
// Mark reference ...
|
||||
fn.internal = Boolean(internal);
|
||||
return this;
|
||||
}
|
||||
|
||||
fireEvent(typeName: string, eventArgs?): Events {
|
||||
const type = Events._normalizeEventName(typeName);
|
||||
const events = this._handlerByType[type];
|
||||
if (!events) return this;
|
||||
|
||||
const args = Array.isArray(eventArgs) ? eventArgs : [eventArgs];
|
||||
events.forEach(((fn) => {
|
||||
fn.apply(this, args);
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
|
||||
removeEvent(typeName: string, fn?): Events {
|
||||
const type = Events._normalizeEventName(typeName);
|
||||
const events = this._handlerByType[type];
|
||||
if (events && !fn.internal) {
|
||||
const index = events.indexOf(fn);
|
||||
if (index !== -1) events.splice(index, 1);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export default Events;
|
@ -16,12 +16,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import { $msg } from '../Messages';
|
||||
import PersistenceManager from '../PersistenceManager';
|
||||
import { $notify } from './ToolbarNotifier';
|
||||
import { $notifyModal } from './ModalDialogNotifier';
|
||||
import Designer from '../Designer';
|
||||
import ToolbarItem from './ToolbarItem';
|
||||
import { $msg } from '@wisemapping/mindplot/src/components/Messages';
|
||||
import PersistenceManager from '@wisemapping/mindplot/src/components/PersistenceManager';
|
||||
import { $notify } from '@wisemapping/mindplot/src/components/widget/ToolbarNotifier';
|
||||
import { $notifyModal } from '../menu/ModalDialogNotifier';
|
||||
import Designer from '@wisemapping/mindplot/src/components/Designer';
|
||||
import ToolbarItem from '../menu/ToolbarItem';
|
||||
|
||||
class IMenu {
|
||||
private _designer: Designer;
|
@ -17,7 +17,8 @@
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import ToolbarPaneItem from './ToolbarPaneItem';
|
||||
import ImageIcon from '../ImageIcon';
|
||||
import { ImageIcon } from '@wisemapping/mindplot';
|
||||
|
||||
|
||||
class IconPanel extends ToolbarPaneItem {
|
||||
_updateSelectedItem() {
|
@ -15,16 +15,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import BootstrapDialog from '../libraries/bootstrap/BootstrapDialog';
|
||||
import { $msg } from '../Messages';
|
||||
import BootstrapDialog from '../bootstrap/BootstrapDialog';
|
||||
import { $msg } from '@wisemapping/mindplot';
|
||||
|
||||
|
||||
class KeyboardShortcutDialog extends BootstrapDialog {
|
||||
constructor() {
|
||||
super($msg('SHORTCUTS'), {
|
||||
closeButton: true,
|
||||
acceptButton: false,
|
||||
});
|
||||
this.setContent(`<div id="keyboardTable">
|
||||
constructor() {
|
||||
super($msg('SHORTCUTS'), {
|
||||
closeButton: true,
|
||||
acceptButton: false,
|
||||
});
|
||||
this.setContent(`<div id="keyboardTable">
|
||||
<table>
|
||||
<colgroup>
|
||||
<col width="40%"/>
|
||||
@ -128,8 +129,8 @@ class KeyboardShortcutDialog extends BootstrapDialog {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>`);
|
||||
this.show();
|
||||
}
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
|
||||
export default KeyboardShortcutDialog;
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import FloatingTip from './FloatingTip';
|
||||
import FloatingTip from '@wisemapping/mindplot/src/components/widget/FloatingTip';
|
||||
|
||||
class KeyboardShortcutTooltip extends FloatingTip {
|
||||
constructor(buttonElem, text) {
|
@ -17,8 +17,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import { $msg } from '../Messages';
|
||||
import IMenu from './IMenu';
|
||||
import { Designer } from '@wisemapping/mindplot';
|
||||
import FontFamilyPanel from './FontFamilyPanel';
|
||||
import FontSizePanel from './FontSizePanel';
|
||||
import TopicShapePanel from './TopicShapePanel';
|
||||
@ -28,7 +27,8 @@ import ToolbarItem from './ToolbarItem';
|
||||
import KeyboardShortcutTooltip from './KeyboardShortcutTooltip';
|
||||
import KeyboardShortcutDialog from './KeyboardShortcutDialog';
|
||||
import AccountSettingsPanel from './AccountSettingsPanel';
|
||||
import Designer from '../Designer';
|
||||
import IMenu from './IMenu';
|
||||
import { $msg } from '@wisemapping/mindplot';
|
||||
|
||||
class Menu extends IMenu {
|
||||
constructor(designer: Designer, containerId: string, readOnly = false, baseUrl = '') {
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import AlertImage from '../../../assets/images/alert-sign.png';
|
||||
|
||||
class ModalDialogNotifier {
|
||||
show(message, title) {
|
||||
@ -29,7 +28,6 @@ class ModalDialogNotifier {
|
||||
<div class="modal-body">
|
||||
</div>
|
||||
<div class="alert alert-block alert-warning">
|
||||
<img src="${AlertImage}">
|
||||
<div style="display: inline-block" class="alert-content"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import Events from '../Events';
|
||||
import Events from './Events';
|
||||
|
||||
class ToolbarItem extends Events {
|
||||
constructor(buttonId, fn, options) {
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import ToolbarItem from './ToolbarItem';
|
||||
import FloatingTip from './FloatingTip';
|
||||
import FloatingTip from '@wisemapping/mindplot/src/components/widget/FloatingTip';
|
||||
|
||||
class ToolbarPaneItem extends ToolbarItem {
|
||||
constructor(buttonId, model, delayInit) {
|
@ -13,6 +13,7 @@ import {
|
||||
} from '@wisemapping/mindplot';
|
||||
import './global-styled.css';
|
||||
import I18nMsg from './classes/i18n-msg';
|
||||
import Menu from './classes/menu/Menu';
|
||||
|
||||
declare global {
|
||||
// used in mindplot
|
||||
@ -74,6 +75,7 @@ const Editor = ({
|
||||
DesignerKeyboard.pause();
|
||||
}
|
||||
}, [options.enableKeyboardEvents]);
|
||||
|
||||
const onLoadDesigner = (mapId: string, options: EditorOptions, persistenceManager: PersistenceManager): Designer => {
|
||||
const buildOptions = DesignerOptionsBuilder.buildOptions({
|
||||
persistenceManager,
|
||||
@ -85,7 +87,19 @@ const Editor = ({
|
||||
});
|
||||
|
||||
// Build designer ...
|
||||
return buildDesigner(buildOptions);
|
||||
const result = buildDesigner(buildOptions);
|
||||
|
||||
// Register toolbar event ...
|
||||
if (options.mode === 'edition-owner' || options.mode === 'edition-editor' || options.mode === 'showcase') {
|
||||
const menu = new Menu(designer, 'toolbar');
|
||||
|
||||
// If a node has focus, focus can be move to another node using the keys.
|
||||
designer.cleanScreen = () => {
|
||||
menu.clear();
|
||||
};
|
||||
}
|
||||
return result;
|
||||
|
||||
};
|
||||
|
||||
const locale = options.locale;
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
, "../mindplot/src/components/widget/FloatingTip.ts" ],
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"outDir": "./dist/",
|
||||
|
Before Width: | Height: | Size: 4.9 KiB |
@ -19,7 +19,6 @@ import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import PersistenceManager from './PersistenceManager';
|
||||
import Designer from './Designer';
|
||||
import Menu from './widget/Menu';
|
||||
import { DesignerOptions } from './DesignerOptionsBuilder';
|
||||
|
||||
let designer: Designer;
|
||||
@ -36,16 +35,6 @@ export function buildDesigner(options: DesignerOptions): Designer {
|
||||
$assert(persistence, 'persistence must be defined');
|
||||
PersistenceManager.init(persistence);
|
||||
|
||||
// Register toolbar event ...
|
||||
if (options.mode === 'edition-owner' || options.mode === 'edition-editor' || options.mode === 'showcase') {
|
||||
const menu = new Menu(designer, 'toolbar');
|
||||
|
||||
// If a node has focus, focus can be move to another node using the keys.
|
||||
designer.cleanScreen = () => {
|
||||
menu.clear();
|
||||
};
|
||||
}
|
||||
|
||||
return designer;
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,11 @@ import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import { $msg } from './Messages';
|
||||
import Icon from './Icon';
|
||||
import FloatingTip from './widget/FloatingTip';
|
||||
import NotesImage from '../../assets/icons/notes.svg';
|
||||
import Topic from './Topic';
|
||||
import NoteModel from './model/NoteModel';
|
||||
import FeatureModel from './model/FeatureModel';
|
||||
import FloatingTip from './widget/FloatingTip';
|
||||
|
||||
class NoteIcon extends Icon {
|
||||
private _linksModel: NoteModel;
|
||||
@ -56,6 +56,7 @@ class NoteIcon extends Icon {
|
||||
event.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
this._tip = new FloatingTip($(me.getImage().peer._native), {
|
||||
title: $msg('NOTE'),
|
||||
// Content can also be a function of the target element!
|
||||
|
@ -32,9 +32,13 @@ const defaultOptions = {
|
||||
};
|
||||
|
||||
class FloatingTip extends Events {
|
||||
private options;
|
||||
|
||||
private element;
|
||||
|
||||
constructor(element, options) {
|
||||
super();
|
||||
const opts = { ...defaultOptions, ...options };
|
||||
super(element, opts);
|
||||
this.setOptions(opts);
|
||||
this.element = element;
|
||||
this._createPopover();
|
@ -18,7 +18,7 @@
|
||||
import $ from 'jquery';
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import { $msg } from '../Messages';
|
||||
import BootstrapDialog from '../libraries/bootstrap/BootstrapDialog';
|
||||
import BootstrapDialog from './bootstrap/BootstrapDialog';
|
||||
|
||||
class LinkEditor extends BootstrapDialog {
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import BootstrapDialog from '../libraries/bootstrap/BootstrapDialog';
|
||||
import BootstrapDialog from '../../../../editor/src/classes/bootstrap/BootstrapDialog';
|
||||
import { $msg } from '../Messages';
|
||||
|
||||
class NoteEditor extends BootstrapDialog {
|
||||
|
@ -23,21 +23,26 @@ import Designer from './components/Designer';
|
||||
import LocalStorageManager from './components/LocalStorageManager';
|
||||
import RESTPersistenceManager from './components/RestPersistenceManager';
|
||||
import MockPersistenceManager from './components/MockPersistenceManager';
|
||||
import Menu from './components/widget/Menu';
|
||||
import DesignerOptionsBuilder from './components/DesignerOptionsBuilder';
|
||||
import ImageExporterFactory from './components/export/ImageExporterFactory';
|
||||
import TextExporterFactory from './components/export/TextExporterFactory';
|
||||
import Exporter from './components/export/Exporter';
|
||||
import DesignerKeyboard from './components/DesignerKeyboard';
|
||||
import EditorRenderMode from './components/EditorRenderMode';
|
||||
import ImageIcon from './components/ImageIcon';
|
||||
|
||||
import {
|
||||
buildDesigner,
|
||||
} from './components/DesignerBuilder';
|
||||
|
||||
import {
|
||||
$notify,
|
||||
} from './components/widget/ToolbarNotifier';
|
||||
|
||||
import {
|
||||
$msg,
|
||||
} from './components/Messages';
|
||||
|
||||
// This hack is required to initialize Bootstrap. In future, this should be removed.
|
||||
const globalAny: any = global;
|
||||
globalAny.jQuery = jquery;
|
||||
@ -46,7 +51,6 @@ require('../../../libraries/bootstrap/js/bootstrap.min');
|
||||
export {
|
||||
Mindmap,
|
||||
Designer,
|
||||
Menu,
|
||||
DesignerBuilder,
|
||||
PersistenceManager,
|
||||
RESTPersistenceManager,
|
||||
@ -58,6 +62,8 @@ export {
|
||||
TextExporterFactory,
|
||||
ImageExporterFactory,
|
||||
Exporter,
|
||||
ImageIcon,
|
||||
$notify,
|
||||
$msg,
|
||||
DesignerKeyboard,
|
||||
};
|
||||
|
@ -15,7 +15,7 @@
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
, "../editor/src/classes/menu/AccountSettingsPanel.js", "../editor/src/classes/menu/IMenu.ts", "../editor/src/classes/bootstrap" ],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
|
@ -35,6 +35,6 @@ export default class EditorOptionsBulder {
|
||||
}
|
||||
|
||||
static loadMapId(): number {
|
||||
return !AppConfig.isDevelopEnv() ? global.mapId : 555;
|
||||
return !AppConfig.isDevelopEnv() ? global.mapId : 11;
|
||||
}
|
||||
}
|