mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-21 22:27:56 +01:00
Merged in mindplot-webcomponent (pull request #57)
Mindplot webcomponent * styles in js file * editor now uses bootstrap widget manager * fix console error: preventDefault on pasive events * Mode as webcomponent parámeter. Rename of init method * fix merge * Mindplot webcomponent documentation * fix * remove comments * delete comments * Merged in Alejandro-Raiczyk/just-details-1661445571189 (pull request #56) just details Approved-by: Paulo Veiga
This commit is contained in:
parent
f6d04523b8
commit
2370faea62
@ -0,0 +1,90 @@
|
||||
import {
|
||||
WidgetManager,
|
||||
Topic,
|
||||
LinkModel,
|
||||
LinkIcon,
|
||||
NoteModel,
|
||||
NoteIcon,
|
||||
$msg,
|
||||
} from '@wisemapping/mindplot';
|
||||
import LinkIconTooltip from './LinkIconTooltip';
|
||||
import LinkEditor from './LinkEditor';
|
||||
import FloatingTip from './FloatingTip';
|
||||
import NoteEditor from './NoteEditor';
|
||||
import $ from 'jquery';
|
||||
|
||||
export default class BootstrapWidgetManager extends WidgetManager {
|
||||
createTooltipForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
||||
const htmlImage = linkIcon.getImage().peer;
|
||||
const toolTip = new LinkIconTooltip(linkIcon);
|
||||
linkIcon.addEvent('mouseleave', (event) => {
|
||||
setTimeout(() => {
|
||||
if (!$('#linkPopover:hover').length) {
|
||||
toolTip.hide();
|
||||
}
|
||||
event.stopPropagation();
|
||||
}, 100);
|
||||
});
|
||||
$(htmlImage._native).mouseenter(() => {
|
||||
toolTip.show();
|
||||
});
|
||||
}
|
||||
|
||||
showEditorForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
||||
const editorModel = {
|
||||
getValue(): string {
|
||||
return topic.getLinkValue();
|
||||
},
|
||||
setValue(value: string) {
|
||||
topic.setLinkValue(value);
|
||||
},
|
||||
};
|
||||
topic.closeEditors();
|
||||
const editor = new LinkEditor(editorModel);
|
||||
editor.show();
|
||||
}
|
||||
|
||||
private _buildTooltipContentForNote(noteModel: NoteModel): JQuery {
|
||||
if ($('body').find('#textPopoverNote').length === 1) {
|
||||
const text = $('body').find('#textPopoverNote');
|
||||
text.text(noteModel.getText());
|
||||
return text;
|
||||
}
|
||||
const result = $('<div id="textPopoverNote"></div>').css({ padding: '5px' });
|
||||
|
||||
const text = $('<div></div>').text(noteModel.getText()).css({
|
||||
'white-space': 'pre-wrap',
|
||||
'word-wrap': 'break-word',
|
||||
});
|
||||
result.append(text);
|
||||
return result;
|
||||
}
|
||||
|
||||
createTooltipForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
||||
const htmlImage = noteIcon.getImage().peer;
|
||||
const me = this;
|
||||
const toolTip = new FloatingTip($(htmlImage._native), {
|
||||
title: $msg('NOTE'),
|
||||
content() {
|
||||
return me._buildTooltipContentForNote(noteModel);
|
||||
},
|
||||
html: true,
|
||||
placement: 'bottom',
|
||||
destroyOnExit: true,
|
||||
});
|
||||
}
|
||||
|
||||
showEditorForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
||||
const editorModel = {
|
||||
getValue(): string {
|
||||
return topic.getNoteValue();
|
||||
},
|
||||
setValue(value: string) {
|
||||
topic.setNoteValue(value);
|
||||
},
|
||||
};
|
||||
topic.closeEditors();
|
||||
const editor = new NoteEditor(editorModel);
|
||||
editor.show();
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import merge from 'lodash/merge';
|
||||
import Events from '../Events';
|
||||
import Events from '../menu/Events';
|
||||
|
||||
const defaultOptions = {
|
||||
animation: true,
|
@ -17,8 +17,8 @@
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import { $msg } from '../Messages';
|
||||
import BootstrapDialog from './bootstrap/BootstrapDialog';
|
||||
import { $msg } from '@wisemapping/mindplot';
|
||||
import BootstrapDialog from './BootstrapDialog';
|
||||
|
||||
interface LinkEditorModel {
|
||||
getValue(): string;
|
@ -17,9 +17,9 @@
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import LinkIcon from '../LinkIcon';
|
||||
import LinkModel from '../model/LinkModel';
|
||||
import { $msg } from '../Messages';
|
||||
import { LinkIcon } from '@wisemapping/mindplot';
|
||||
import { LinkModel } from '@wisemapping/mindplot';
|
||||
import { $msg } from '@wisemapping/mindplot';
|
||||
import FloatingTip from './FloatingTip';
|
||||
|
||||
class LinkIconTooltip extends FloatingTip {
|
||||
@ -56,7 +56,7 @@ class LinkIconTooltip extends FloatingTip {
|
||||
target: '_blank',
|
||||
});
|
||||
|
||||
link.append(linkText);
|
||||
link.html(linkText);
|
||||
result.append(link);
|
||||
return result;
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import BootstrapDialog from '../../../../editor/src/classes/bootstrap/BootstrapDialog';
|
||||
import { $msg } from '../Messages';
|
||||
import { $msg } from '@wisemapping/mindplot';
|
||||
|
||||
interface NoteEditorModel {
|
||||
getValue(): string;
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import FloatingTip from '@wisemapping/mindplot/src/components/widget/FloatingTip';
|
||||
import FloatingTip from '../bootstrap/FloatingTip';
|
||||
|
||||
class KeyboardShortcutTooltip extends FloatingTip {
|
||||
constructor(buttonElem, text) {
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import ToolbarItem from './ToolbarItem';
|
||||
import FloatingTip from '@wisemapping/mindplot/src/components/widget/FloatingTip';
|
||||
import FloatingTip from '../bootstrap/FloatingTip';
|
||||
|
||||
class ToolbarPaneItem extends ToolbarItem {
|
||||
constructor(buttonId, model, delayInit) {
|
||||
|
@ -22,21 +22,6 @@ body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div#mindplot {
|
||||
position: relative;
|
||||
top: 50px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
background-color: #f2f2f2;
|
||||
background-image: linear-gradient(#ebe9e7 1px, transparent 1px),
|
||||
linear-gradient(to right, #ebe9e7 1px, #f2f2f2 1px);
|
||||
background-size: 50px 50px;
|
||||
}
|
||||
|
||||
.notesTip {
|
||||
background-color: #dfcf3c;
|
||||
padding: 5px 15px;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import Toolbar, { ToolbarActionType } from './components/toolbar';
|
||||
import Footer from './components/footer';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
@ -10,10 +10,23 @@ import {
|
||||
Designer,
|
||||
DesignerKeyboard,
|
||||
EditorRenderMode,
|
||||
MindplotWebComponentInterface,
|
||||
Mindmap,
|
||||
MockPersistenceManager,
|
||||
LocalStorageManager,
|
||||
RESTPersistenceManager,
|
||||
TextExporterFactory,
|
||||
ImageExporterFactory,
|
||||
Exporter,
|
||||
Importer,
|
||||
TextImporterFactory,
|
||||
} from '@wisemapping/mindplot';
|
||||
import './global-styled.css';
|
||||
import I18nMsg from './classes/i18n-msg';
|
||||
import Menu from './classes/menu/Menu';
|
||||
import BootstrapWidgetManager from './classes/bootstrap/BootstrapWidgetManager';
|
||||
|
||||
require('../../../libraries/bootstrap/js/bootstrap.min');
|
||||
|
||||
declare global {
|
||||
// used in mindplot
|
||||
@ -21,6 +34,14 @@ declare global {
|
||||
var accountEmail: string;
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
['mindplot-component']: MindplotWebComponentInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type EditorOptions = {
|
||||
mode: EditorRenderMode;
|
||||
locale: string;
|
||||
@ -31,6 +52,23 @@ export type EditorOptions = {
|
||||
enableKeyboardEvents: boolean;
|
||||
};
|
||||
|
||||
export {
|
||||
PersistenceManager,
|
||||
DesignerOptionsBuilder,
|
||||
Designer,
|
||||
DesignerKeyboard,
|
||||
EditorRenderMode,
|
||||
Mindmap,
|
||||
MockPersistenceManager,
|
||||
LocalStorageManager,
|
||||
RESTPersistenceManager,
|
||||
TextExporterFactory,
|
||||
ImageExporterFactory,
|
||||
Exporter,
|
||||
Importer,
|
||||
TextImporterFactory,
|
||||
};
|
||||
|
||||
export type EditorProps = {
|
||||
mapId: string;
|
||||
options: EditorOptions;
|
||||
@ -41,22 +79,21 @@ export type EditorProps = {
|
||||
|
||||
const Editor = ({ mapId, options, persistenceManager, onAction, onLoad }: EditorProps) => {
|
||||
const [isMobile, setIsMobile] = useState(undefined);
|
||||
const mindplotComponent: any = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
// Change page title ...
|
||||
document.title = `${options.mapTitle} | WiseMapping `;
|
||||
|
||||
// Load mindmap ...
|
||||
|
||||
const designer = onLoadDesigner(mapId, options, persistenceManager);
|
||||
// Has extended actions been customized ...
|
||||
if (onLoad) {
|
||||
onLoad(designer);
|
||||
}
|
||||
|
||||
// Load mindmap ...
|
||||
const instance = PersistenceManager.getInstance();
|
||||
const mindmap = instance.load(mapId);
|
||||
designer.loadMap(mindmap);
|
||||
mindplotComponent.current.loadMap(mapId);
|
||||
|
||||
setIsMobile(checkMobile());
|
||||
|
||||
@ -89,17 +126,10 @@ const Editor = ({ mapId, options, persistenceManager, onAction, onLoad }: Editor
|
||||
options: EditorOptions,
|
||||
persistenceManager: PersistenceManager,
|
||||
): Designer => {
|
||||
const buildOptions = DesignerOptionsBuilder.buildOptions({
|
||||
persistenceManager,
|
||||
mode: options.mode,
|
||||
mapId: mapId,
|
||||
container: 'mindplot',
|
||||
zoom: options.zoom,
|
||||
locale: options.locale,
|
||||
});
|
||||
mindplotComponent.current.buildDesigner(persistenceManager, new BootstrapWidgetManager());
|
||||
|
||||
// Build designer ...
|
||||
const result = buildDesigner(buildOptions);
|
||||
const result = mindplotComponent.current && mindplotComponent.current.getDesigner();
|
||||
|
||||
// Register toolbar event ...
|
||||
if (
|
||||
@ -132,7 +162,11 @@ const Editor = ({ mapId, options, persistenceManager, onAction, onLoad }: Editor
|
||||
<Toolbar editorMode={options.mode} onAction={onAction} />
|
||||
)}
|
||||
</div>
|
||||
<div id="mindplot" style={mindplotStyle} className="wise-editor"></div>
|
||||
<mindplot-component
|
||||
ref={mindplotComponent}
|
||||
id="mindmap-comp"
|
||||
mode={options.mode}
|
||||
></mindplot-component>
|
||||
<div id="mindplot-tooltips" className="wise-editor"></div>
|
||||
<Footer editorMode={options.mode} isMobile={isMobile} />
|
||||
</IntlProvider>
|
||||
|
@ -22,7 +22,7 @@ import { LocalStorageManager, Designer } from '@wisemapping/mindplot';
|
||||
|
||||
const initialization = (designer: Designer) => {
|
||||
designer.addEvent('loadSuccess', () => {
|
||||
const elem = document.getElementById('mindplot');
|
||||
const elem = document.getElementById('mindmap-comp');
|
||||
if (elem) {
|
||||
elem.classList.add('ready');
|
||||
}
|
||||
|
@ -1,7 +1,78 @@
|
||||
# WiseMapping Mindplot
|
||||
|
||||
WiseMapping Mindplot module is the core mind map rerendering of WiseMapping. This lighway library allows eithe edition and visualization of saves mindmaps.
|
||||
WiseMapping Mindplot module is the core mind map rerendering of WiseMapping. This lighway library allows eithe edition and visualization of saved mindmaps.
|
||||
|
||||
## Usage
|
||||
|
||||
A WebComponent implementation for mindplot designer is available.
|
||||
This component is registered as mindplot-component in customElements API. (see https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define)
|
||||
For use it you need to import minplot.js and put in your DOM a <mindplot-component id="mindplot-comp"/> tag. In order to create a Designer on it you need to call its buildDesigner method. Maps can be loaded through loadMap method.
|
||||
|
||||
#### Code example
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src='mindplot.js'></script>
|
||||
</head>
|
||||
<body>
|
||||
<mindmap-comp id='mindmap-comp' mode="viewonly"></mindmap-comp>
|
||||
<script>
|
||||
var webComponent = document.getElementById('mindmap-comp');
|
||||
webComponent.buildDesigner(persistence, widget);
|
||||
webComponent.loadMap("1");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Optionaly you can use your own presistence manager and widget manager.
|
||||
If you don't have special requirements you can use the defaults.
|
||||
|
||||
```
|
||||
var persistence = new LocalStorageManager(
|
||||
'map.xml',
|
||||
false, false
|
||||
);
|
||||
var widget = new MyAwesomeWidgetManager();
|
||||
// then build the designer with these params
|
||||
webComponent.buildDesigner(persistence, widget);
|
||||
```
|
||||
|
||||
## Usage with React framework
|
||||
|
||||
To use the web component in your JSX code, first you need to register it in the IntrinsicElements interface using provided MindplotWebComponentInterface
|
||||
|
||||
#### TypeScript example
|
||||
```
|
||||
import { MindplotWebComponentInterface } from '@wisemapping/mindplot';
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
['mindplot-component']: MindplotWebComponentInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const App = ()=>{
|
||||
const mindplotComponent: any = useRef();
|
||||
|
||||
useEffect(()=>{
|
||||
mindplotComponent.current.buildDesigner();
|
||||
mindplotComponent.current.loadMap("map_id");
|
||||
}, [])
|
||||
|
||||
return (<div>
|
||||
<mindplot-component
|
||||
ref={mindplotComponent}
|
||||
id="mindmap-comp"
|
||||
mode={options.mode}
|
||||
></mindplot-component>
|
||||
</div>);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Check out the examples located in `test/playground/map-render/js` for some hints on high level usage. You can browse them by running `yarn playground`.
|
||||
|
@ -56,6 +56,7 @@ import { DesignerOptions } from './DesignerOptionsBuilder';
|
||||
import DragTopic from './DragTopic';
|
||||
import CentralTopic from './CentralTopic';
|
||||
import FeatureType from './model/FeatureType';
|
||||
import WidgetManager from './WidgetManager';
|
||||
|
||||
class Designer extends Events {
|
||||
private _mindmap: Mindmap;
|
||||
@ -882,7 +883,8 @@ class Designer extends Events {
|
||||
const model = this.getModel();
|
||||
const topic = model.selectedTopic();
|
||||
if (topic) {
|
||||
topic.showLinkEditor();
|
||||
const manager = WidgetManager.getInstance();
|
||||
manager.showEditorForLink(topic, null, null);
|
||||
this.onObjectFocusEvent();
|
||||
}
|
||||
}
|
||||
@ -891,7 +893,8 @@ class Designer extends Events {
|
||||
const model = this.getModel();
|
||||
const topic = model.selectedTopic();
|
||||
if (topic) {
|
||||
topic.showNoteEditor();
|
||||
const manager = WidgetManager.getInstance();
|
||||
manager.showEditorForNote(topic, null, null);
|
||||
this.onObjectFocusEvent();
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,12 @@ import $ from 'jquery';
|
||||
import PersistenceManager from './PersistenceManager';
|
||||
import Designer from './Designer';
|
||||
import { DesignerOptions } from './DesignerOptionsBuilder';
|
||||
import WidgetManager from './WidgetManager';
|
||||
|
||||
let designer: Designer;
|
||||
|
||||
export function buildDesigner(options: DesignerOptions): Designer {
|
||||
const divContainer = $(`#${options.container}`);
|
||||
const divContainer = options.divContainer ? $(options.divContainer) : $(`#${options.container}`);
|
||||
$assert(divContainer, 'container could not be null');
|
||||
|
||||
// Register load events ...
|
||||
@ -34,7 +35,8 @@ export function buildDesigner(options: DesignerOptions): Designer {
|
||||
const persistence = options.persistenceManager;
|
||||
$assert(persistence, 'persistence must be defined');
|
||||
PersistenceManager.init(persistence);
|
||||
|
||||
const widgetManager = options.widgetManager ? options.widgetManager : new WidgetManager();
|
||||
WidgetManager.init(widgetManager);
|
||||
return designer;
|
||||
}
|
||||
|
||||
|
@ -17,14 +17,17 @@
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import EditorRenderMode from './EditorRenderMode';
|
||||
import WidgetManager from './WidgetManager';
|
||||
import PersistenceManager from './PersistenceManager';
|
||||
|
||||
export type DesignerOptions = {
|
||||
zoom: number;
|
||||
mode: EditorRenderMode;
|
||||
mapId?: string;
|
||||
divContainer?: HTMLElement;
|
||||
container: string;
|
||||
persistenceManager?: PersistenceManager;
|
||||
widgetManager?: WidgetManager;
|
||||
saveOnLoad?: boolean;
|
||||
locale?: string;
|
||||
};
|
||||
|
@ -16,13 +16,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import Icon from './Icon';
|
||||
import LinkIconTooltip from './widget/LinkIconTooltip';
|
||||
import LinksImage from '../../assets/icons/links.svg';
|
||||
import LinkModel from './model/LinkModel';
|
||||
import Topic from './Topic';
|
||||
import FeatureModel from './model/FeatureModel';
|
||||
import WidgetManager from './WidgetManager';
|
||||
|
||||
class LinkIcon extends Icon {
|
||||
private _linksModel: FeatureModel;
|
||||
@ -31,8 +30,6 @@ class LinkIcon extends Icon {
|
||||
|
||||
private _readOnly: boolean;
|
||||
|
||||
private _tip: LinkIconTooltip;
|
||||
|
||||
constructor(topic: Topic, linkModel: LinkModel, readOnly: boolean) {
|
||||
$assert(topic, 'topic can not be null');
|
||||
$assert(linkModel, 'linkModel can not be null');
|
||||
@ -47,30 +44,12 @@ class LinkIcon extends Icon {
|
||||
|
||||
private _registerEvents() {
|
||||
this._image.setCursor('pointer');
|
||||
this._tip = new LinkIconTooltip(this);
|
||||
|
||||
const me = this;
|
||||
const manager = WidgetManager.getInstance();
|
||||
manager.createTooltipForLink(this._topic, this._linksModel as LinkModel, this);
|
||||
if (!this._readOnly) {
|
||||
// Add on click event to open the editor ...
|
||||
this.addEvent('click', (event) => {
|
||||
me._tip.hide();
|
||||
me._topic.showLinkEditor();
|
||||
event.stopPropagation();
|
||||
});
|
||||
// FIXME: we shouldn't have timeout of that..
|
||||
this.addEvent('mouseleave', (event) => {
|
||||
setTimeout(() => {
|
||||
if (!$('#linkPopover:hover').length) {
|
||||
me._tip.hide();
|
||||
}
|
||||
event.stopPropagation();
|
||||
}, 100);
|
||||
});
|
||||
manager.configureEditorForLink(this._topic, this._linksModel as LinkModel, this);
|
||||
}
|
||||
|
||||
$(this.getImage().peer._native).mouseenter(() => {
|
||||
me._tip.show();
|
||||
});
|
||||
}
|
||||
|
||||
getModel(): FeatureModel {
|
||||
|
81
packages/mindplot/src/components/MindplotWebComponent.ts
Normal file
81
packages/mindplot/src/components/MindplotWebComponent.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import Designer from './Designer';
|
||||
import buildDesigner from './DesignerBuilder';
|
||||
import DesignerOptionsBuilder from './DesignerOptionsBuilder';
|
||||
import EditorRenderMode from './EditorRenderMode';
|
||||
import LocalStorageManager from './LocalStorageManager';
|
||||
import Mindmap from './model/Mindmap';
|
||||
import PersistenceManager from './PersistenceManager';
|
||||
import WidgetManager from './WidgetManager';
|
||||
import mindplotStyles from './styles/mindplot-styles';
|
||||
|
||||
const defaultPersistenceManager = () => new LocalStorageManager('map.xml', false, false);
|
||||
|
||||
export type MindplotWebComponentInterface = {
|
||||
id: string;
|
||||
mode: string;
|
||||
ref: any;
|
||||
};
|
||||
/**
|
||||
* WebComponent implementation for minplot designer.
|
||||
* This component is registered as mindplot-component in customElements api. (see https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define)
|
||||
* For use it you need to import minplot.js and put in your DOM a <mindplot-component/> tag. In order to create a Designer on it you need to call its buildDesigner method. Maps can be loaded throught loadMap method.
|
||||
*/
|
||||
class MindplotWebComponent extends HTMLElement {
|
||||
private _shadowRoot: ShadowRoot;
|
||||
|
||||
private _mindmap: Mindmap;
|
||||
|
||||
private _designer: Designer;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
const mindplotStylesElement = document.createElement('style');
|
||||
mindplotStylesElement.innerHTML = mindplotStyles;
|
||||
this._shadowRoot.appendChild(mindplotStylesElement);
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.setAttribute('class', 'wise-editor');
|
||||
wrapper.setAttribute('id', 'mindplot');
|
||||
this._shadowRoot.appendChild(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the designer
|
||||
*/
|
||||
getDesigner(): Designer {
|
||||
return this._designer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the designer of the component
|
||||
* @param {PersistenceManager} persistence the persistence manager to be used. By default a LocalStorageManager is created
|
||||
* @param {UIManager} widgetManager an UI Manager to override default Designer option.
|
||||
*/
|
||||
buildDesigner(persistence?: PersistenceManager, widgetManager?: WidgetManager) {
|
||||
const editorRenderMode = this.getAttribute('mode') as EditorRenderMode;
|
||||
const persistenceManager = persistence || defaultPersistenceManager();
|
||||
const mode = editorRenderMode || 'viewonly';
|
||||
const options = DesignerOptionsBuilder.buildOptions({
|
||||
persistenceManager,
|
||||
mode,
|
||||
widgetManager,
|
||||
divContainer: this._shadowRoot.getElementById('mindplot'),
|
||||
container: 'mindplot',
|
||||
zoom: 0.85,
|
||||
locale: 'en',
|
||||
});
|
||||
this._designer = buildDesigner(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load map in designer throught persistence manager instance
|
||||
* @param id the map id to be loaded.
|
||||
*/
|
||||
loadMap(id: string) {
|
||||
const instance = PersistenceManager.getInstance();
|
||||
this._mindmap = instance.load(id);
|
||||
this._designer.loadMap(this._mindmap);
|
||||
}
|
||||
}
|
||||
|
||||
export default MindplotWebComponent;
|
@ -16,14 +16,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { $assert } from '@wisemapping/core-js';
|
||||
import $ from 'jquery';
|
||||
import { $msg } from './Messages';
|
||||
import Icon from './Icon';
|
||||
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';
|
||||
import WidgetManager from './WidgetManager';
|
||||
|
||||
class NoteIcon extends Icon {
|
||||
private _linksModel: NoteModel;
|
||||
@ -32,8 +30,6 @@ class NoteIcon extends Icon {
|
||||
|
||||
private _readOnly: boolean;
|
||||
|
||||
private _tip: FloatingTip;
|
||||
|
||||
constructor(topic: Topic, noteModel: NoteModel, readOnly: boolean) {
|
||||
$assert(topic, 'topic can not be null');
|
||||
|
||||
@ -47,42 +43,12 @@ class NoteIcon extends Icon {
|
||||
|
||||
private _registerEvents(): void {
|
||||
this._image.setCursor('pointer');
|
||||
const me = this;
|
||||
|
||||
const manager = WidgetManager.getInstance();
|
||||
manager.createTooltipForNote(this._topic, this._linksModel as NoteModel, this);
|
||||
if (!this._readOnly) {
|
||||
// Add on click event to open the editor ...
|
||||
this.addEvent('click', (event) => {
|
||||
me._topic.showNoteEditor();
|
||||
event.stopPropagation();
|
||||
});
|
||||
manager.configureEditorForNote(this._topic, this._linksModel as NoteModel, this);
|
||||
}
|
||||
|
||||
this._tip = new FloatingTip($(me.getImage().peer._native), {
|
||||
title: $msg('NOTE'),
|
||||
// Content can also be a function of the target element!
|
||||
content() {
|
||||
return me._buildTooltipContent();
|
||||
},
|
||||
html: true,
|
||||
placement: 'bottom',
|
||||
destroyOnExit: true,
|
||||
});
|
||||
}
|
||||
|
||||
private _buildTooltipContent(): JQuery {
|
||||
if ($('body').find('#textPopoverNote').length === 1) {
|
||||
const text = $('body').find('#textPopoverNote');
|
||||
text.text(this._linksModel.getText());
|
||||
return text;
|
||||
}
|
||||
const result = $('<div id="textPopoverNote"></div>').css({ padding: '5px' });
|
||||
|
||||
const text = $('<div></div>').text(this._linksModel.getText()).css({
|
||||
'white-space': 'pre-wrap',
|
||||
'word-wrap': 'break-word',
|
||||
});
|
||||
result.append(text);
|
||||
return result;
|
||||
}
|
||||
|
||||
getModel(): FeatureModel {
|
||||
|
@ -28,9 +28,7 @@ import ConnectionLine from './ConnectionLine';
|
||||
import IconGroup from './IconGroup';
|
||||
import EventBus from './layout/EventBus';
|
||||
import ShirinkConnector from './ShrinkConnector';
|
||||
import NoteEditor from './widget/NoteEditor';
|
||||
import ActionDispatcher from './ActionDispatcher';
|
||||
import LinkEditor from './widget/LinkEditor';
|
||||
|
||||
import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher';
|
||||
import { TopicShape } from './model/INodeModel';
|
||||
@ -732,79 +730,65 @@ abstract class Topic extends NodeGraph {
|
||||
});
|
||||
}
|
||||
|
||||
showNoteEditor(): void {
|
||||
const topicId = this.getId();
|
||||
getNoteValue(): string {
|
||||
const model = this.getModel();
|
||||
const editorModel = {
|
||||
getValue(): string {
|
||||
const notes = model.findFeatureByType(TopicFeatureFactory.Note.id);
|
||||
let result;
|
||||
if (notes.length > 0) {
|
||||
result = (notes[0] as NoteModel).getText();
|
||||
}
|
||||
const notes = model.findFeatureByType(TopicFeatureFactory.Note.id);
|
||||
let result;
|
||||
if (notes.length > 0) {
|
||||
result = (notes[0] as NoteModel).getText();
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
setValue(value: string) {
|
||||
const dispatcher = ActionDispatcher.getInstance();
|
||||
const notes = model.findFeatureByType(TopicFeatureFactory.Note.id);
|
||||
if (!$defined(value)) {
|
||||
const featureId = notes[0].getId();
|
||||
dispatcher.removeFeatureFromTopic(topicId, featureId);
|
||||
} else if (notes.length > 0) {
|
||||
dispatcher.changeFeatureToTopic(topicId, notes[0].getId(), {
|
||||
text: value,
|
||||
});
|
||||
} else {
|
||||
dispatcher.addFeatureToTopic(topicId, TopicFeatureFactory.Note.id, {
|
||||
text: value,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
const editor = new NoteEditor(editorModel);
|
||||
this.closeEditors();
|
||||
editor.show();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** opens a dialog where the user can enter or edit an existing link associated with this topic */
|
||||
showLinkEditor() {
|
||||
setNoteValue(value: string) {
|
||||
const topicId = this.getId();
|
||||
const model = this.getModel();
|
||||
const editorModel = {
|
||||
getValue(): string {
|
||||
// @param {mindplot.model.LinkModel[]} links
|
||||
const links = model.findFeatureByType(TopicFeatureFactory.Link.id);
|
||||
let result;
|
||||
if (links.length > 0) {
|
||||
result = (links[0] as LinkModel).getUrl();
|
||||
}
|
||||
const dispatcher = ActionDispatcher.getInstance();
|
||||
const notes = model.findFeatureByType(TopicFeatureFactory.Note.id);
|
||||
if (!$defined(value)) {
|
||||
const featureId = notes[0].getId();
|
||||
dispatcher.removeFeatureFromTopic(topicId, featureId);
|
||||
} else if (notes.length > 0) {
|
||||
dispatcher.changeFeatureToTopic(topicId, notes[0].getId(), {
|
||||
text: value,
|
||||
});
|
||||
} else {
|
||||
dispatcher.addFeatureToTopic(topicId, TopicFeatureFactory.Note.id, {
|
||||
text: value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
getLinkValue(): string {
|
||||
const model = this.getModel();
|
||||
// @param {mindplot.model.LinkModel[]} links
|
||||
const links = model.findFeatureByType(TopicFeatureFactory.Link.id);
|
||||
let result;
|
||||
if (links.length > 0) {
|
||||
result = (links[0] as LinkModel).getUrl();
|
||||
}
|
||||
|
||||
setValue(value: string) {
|
||||
const dispatcher = ActionDispatcher.getInstance();
|
||||
const links = model.findFeatureByType(TopicFeatureFactory.Link.id);
|
||||
if (!$defined(value)) {
|
||||
const featureId = links[0].getId();
|
||||
dispatcher.removeFeatureFromTopic(topicId, featureId);
|
||||
} else if (links.length > 0) {
|
||||
dispatcher.changeFeatureToTopic(topicId, links[0].getId(), {
|
||||
url: value,
|
||||
});
|
||||
} else {
|
||||
dispatcher.addFeatureToTopic(topicId, TopicFeatureFactory.Link.id, {
|
||||
url: value,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
this.closeEditors();
|
||||
const editor = new LinkEditor(editorModel);
|
||||
editor.show();
|
||||
setLinkValue(value: string) {
|
||||
const topicId = this.getId();
|
||||
const model = this.getModel();
|
||||
const dispatcher = ActionDispatcher.getInstance();
|
||||
const links = model.findFeatureByType(TopicFeatureFactory.Link.id);
|
||||
if (!$defined(value)) {
|
||||
const featureId = links[0].getId();
|
||||
dispatcher.removeFeatureFromTopic(topicId, featureId);
|
||||
} else if (links.length > 0) {
|
||||
dispatcher.changeFeatureToTopic(topicId, links[0].getId(), {
|
||||
url: value,
|
||||
});
|
||||
} else {
|
||||
dispatcher.addFeatureToTopic(topicId, TopicFeatureFactory.Link.id, {
|
||||
url: value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
closeEditors() {
|
||||
|
107
packages/mindplot/src/components/WidgetManager.ts
Normal file
107
packages/mindplot/src/components/WidgetManager.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import $ from 'jquery';
|
||||
import LinkIcon from './LinkIcon';
|
||||
import LinkModel from './model/LinkModel';
|
||||
import NoteModel from './model/NoteModel';
|
||||
import NoteIcon from './NoteIcon';
|
||||
import Topic from './Topic';
|
||||
import { $msg } from './Messages';
|
||||
|
||||
class WidgetManager {
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
static _instance: WidgetManager;
|
||||
|
||||
static init = (instance: WidgetManager) => {
|
||||
this._instance = instance;
|
||||
};
|
||||
|
||||
static getInstance(): WidgetManager {
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
private createTooltip(mindmapElement, title, linkModel: LinkModel, noteModel: NoteModel) {
|
||||
const webcomponentShadowRoot = $($('#mindmap-comp')[0].shadowRoot);
|
||||
let tooltip = webcomponentShadowRoot.find('#mindplot-svg-tooltip');
|
||||
if (!tooltip.length) {
|
||||
webcomponentShadowRoot.append(
|
||||
'<div id="mindplot-svg-tooltip" class="mindplot-svg-tooltip">' +
|
||||
'<div id="mindplot-svg-tooltip-title" class="mindplot-svg-tooltip-title"></div>' +
|
||||
'<div id="mindplot-svg-tooltip-content" class="mindplot-svg-tooltip-content">' +
|
||||
'<a id="mindplot-svg-tooltip-content-link" alt="Open in new window ..." class="mindplot-svg-tooltip-content-link" target="_blank"></a>' +
|
||||
'<p id="mindplot-svg-tooltip-content-note" class="mindplot-svg-tooltip-content-note"></p>' +
|
||||
'</div>' +
|
||||
'</div>',
|
||||
);
|
||||
tooltip = webcomponentShadowRoot.find('#mindplot-svg-tooltip');
|
||||
|
||||
tooltip.on('mouseover', (evt) => {
|
||||
tooltip.css({ display: 'block' });
|
||||
evt.stopPropagation();
|
||||
});
|
||||
tooltip.on('mouseleave', (evt) => {
|
||||
tooltip.css({ display: 'none' });
|
||||
evt.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
mindmapElement.addEvent('mouseenter', (evt) => {
|
||||
webcomponentShadowRoot.find('#mindplot-svg-tooltip-title').html(title);
|
||||
if (linkModel) {
|
||||
webcomponentShadowRoot
|
||||
.find('#mindplot-svg-tooltip-content-link')
|
||||
.attr('href', linkModel.getUrl());
|
||||
webcomponentShadowRoot.find('#mindplot-svg-tooltip-content-link').html(linkModel.getUrl());
|
||||
webcomponentShadowRoot.find('#mindplot-svg-tooltip-content-link').css({ display: 'block' });
|
||||
webcomponentShadowRoot.find('#mindplot-svg-tooltip-content-note').css({ display: 'none' });
|
||||
}
|
||||
if (noteModel) {
|
||||
webcomponentShadowRoot.find('#mindplot-svg-tooltip-content-note').html(noteModel.getText());
|
||||
webcomponentShadowRoot.find('#mindplot-svg-tooltip-content-note').css({ display: 'block' });
|
||||
webcomponentShadowRoot.find('#mindplot-svg-tooltip-content-link').css({ display: 'none' });
|
||||
}
|
||||
const targetRect = evt.target.getBoundingClientRect();
|
||||
const newX = Math.max(0, targetRect.left + targetRect.width / 2 - tooltip.width() / 2);
|
||||
const newY = Math.max(0, targetRect.bottom + 10);
|
||||
tooltip.css({ top: newY, left: newX, position: 'absolute' });
|
||||
tooltip.css({ display: 'block' });
|
||||
evt.stopPropagation();
|
||||
});
|
||||
mindmapElement.addEvent('mouseleave', (evt) => {
|
||||
tooltip.css({ display: 'none' });
|
||||
evt.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
createTooltipForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
||||
this.createTooltip(linkIcon.getImage().peer, $msg('LINK'), linkModel, undefined);
|
||||
}
|
||||
|
||||
createTooltipForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
||||
this.createTooltip(noteIcon.getImage().peer, $msg('NOTE'), undefined, noteModel);
|
||||
}
|
||||
|
||||
configureEditorForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
||||
const htmlImage = linkIcon.getImage().peer;
|
||||
htmlImage.addEvent('click', (evt) => {
|
||||
this.showEditorForLink(topic, linkModel, linkIcon);
|
||||
evt.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
configureEditorForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
||||
const htmlImage = noteIcon.getImage().peer;
|
||||
htmlImage.addEvent('click', (evt) => {
|
||||
this.showEditorForNote(topic, noteModel, noteIcon);
|
||||
evt.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
showEditorForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
||||
console.log('Show link editor not yet implemented');
|
||||
}
|
||||
|
||||
showEditorForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
||||
console.log('Show note editor not yet implemented');
|
||||
}
|
||||
}
|
||||
|
||||
export default WidgetManager;
|
@ -223,7 +223,9 @@ class Workspace {
|
||||
|
||||
// Change cursor.
|
||||
window.document.body.style.cursor = 'move';
|
||||
mouseMoveEvent.preventDefault();
|
||||
// If I dont ignore touchmove events, browser console shows a lot of errors:
|
||||
// Unable to preventDefault inside passive event listener invocation.
|
||||
if (mouseMoveEvent.type !== 'touchmove') mouseMoveEvent.preventDefault();
|
||||
|
||||
// Fire drag event ...
|
||||
screenManager.fireEvent('update');
|
||||
|
132
packages/mindplot/src/components/styles/mindplot-styles.js
Normal file
132
packages/mindplot/src/components/styles/mindplot-styles.js
Normal file
@ -0,0 +1,132 @@
|
||||
const mindplotStyles = `
|
||||
|
||||
div#mindplot {
|
||||
position: relative;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
background-color: #f2f2f2;
|
||||
background-image: linear-gradient(#ebe9e7 1px, transparent 1px),
|
||||
linear-gradient(to right, #ebe9e7 1px, #f2f2f2 1px);
|
||||
background-size: 50px 50px;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip {
|
||||
display: none;
|
||||
color: rgb(51, 51, 51);
|
||||
text-align: center;
|
||||
padding: 1px;
|
||||
border-radius: 6px;
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
background-color: rgb(255, 255, 255);
|
||||
animation: fadeIn 0.4s;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn ease 0.4s;
|
||||
-webkit-animation: fadeIn ease 0.4s;
|
||||
-moz-animation: fadeIn ease 0.4s;
|
||||
-o-animation: fadeIn ease 0.4s;
|
||||
-ms-animation: fadeIn ease 0.4s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-moz-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-o-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-ms-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-title {
|
||||
background-color: rgb(247, 247, 247);
|
||||
border-bottom-color: rgb(235, 235, 235);
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
color: rgb(51, 51, 51);
|
||||
cursor: default;
|
||||
display: block;
|
||||
padding: 8px 14px;
|
||||
text-align: left;
|
||||
font-family: Arial;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-content {
|
||||
background-color: rgb(255, 255, 255);
|
||||
padding: 6px 4px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-content-link {
|
||||
padding: 3px 5px;
|
||||
overflow: hidden;
|
||||
font-size: smaller;
|
||||
text-decoration: none;
|
||||
font-family: Arial;
|
||||
font-size: small;
|
||||
color: #428bca;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-content-note {
|
||||
text-align: left;
|
||||
font-family: Arial;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid #fff;
|
||||
bottom: 100%;
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid rgb(247, 247, 247);
|
||||
bottom: calc(1px + 100%);
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
}
|
||||
`;
|
||||
|
||||
export default mindplotStyles;
|
@ -1,154 +0,0 @@
|
||||
/*
|
||||
* 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 '../../Options';
|
||||
import { $msg } from '../../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(event) {
|
||||
throw new Error('Unsupported operation');
|
||||
}
|
||||
|
||||
onDialogShown(event) {
|
||||
// Overwrite default behaviour ...
|
||||
}
|
||||
|
||||
onRemoveClick(event) {
|
||||
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;
|
@ -31,7 +31,19 @@ import Exporter from './components/export/Exporter';
|
||||
import Importer from './components/import/Importer';
|
||||
import DesignerKeyboard from './components/DesignerKeyboard';
|
||||
import EditorRenderMode from './components/EditorRenderMode';
|
||||
|
||||
import ImageIcon from './components/ImageIcon';
|
||||
import MindplotWebComponent, {
|
||||
MindplotWebComponentInterface,
|
||||
} from './components/MindplotWebComponent';
|
||||
import LinkIcon from './components/LinkIcon';
|
||||
import NoteIcon from './components/NoteIcon';
|
||||
import Topic from './components/Topic';
|
||||
|
||||
import LinkModel from './components/model/LinkModel';
|
||||
import NoteModel from './components/model/NoteModel';
|
||||
|
||||
import WidgetManager from './components/WidgetManager';
|
||||
|
||||
import { buildDesigner } from './components/DesignerBuilder';
|
||||
|
||||
@ -39,10 +51,15 @@ import { $notify } from './components/widget/ToolbarNotifier';
|
||||
|
||||
import { $msg } from './components/Messages';
|
||||
|
||||
// This hack is required to initialize Bootstrap. In future, this should be removed.
|
||||
import './mindplot-styles.css';
|
||||
|
||||
const globalAny: any = global;
|
||||
globalAny.jQuery = jquery;
|
||||
require('../../../libraries/bootstrap/js/bootstrap.min');
|
||||
// WebComponent registration
|
||||
// The if statement is the fix for doble registration problem. Can be deleted wen webapp-mindplot dependency be dead.
|
||||
if (!customElements.get('mindplot-component')) {
|
||||
customElements.define('mindplot-component', MindplotWebComponent);
|
||||
}
|
||||
|
||||
export {
|
||||
Mindmap,
|
||||
@ -64,4 +81,12 @@ export {
|
||||
$notify,
|
||||
$msg,
|
||||
DesignerKeyboard,
|
||||
MindplotWebComponent,
|
||||
MindplotWebComponentInterface,
|
||||
LinkIcon,
|
||||
LinkModel,
|
||||
NoteIcon,
|
||||
NoteModel,
|
||||
WidgetManager,
|
||||
Topic,
|
||||
};
|
||||
|
@ -17,42 +17,30 @@
|
||||
*/
|
||||
import jquery from 'jquery';
|
||||
import {} from './components/widget/ToolbarNotifier';
|
||||
import { buildDesigner } from './components/DesignerBuilder';
|
||||
import PersistenceManager from './components/PersistenceManager';
|
||||
import LocalStorageManager from './components/LocalStorageManager';
|
||||
import DesignerOptionsBuilder from './components/DesignerOptionsBuilder';
|
||||
import MindplotWebComponent from './components/MindplotWebComponent';
|
||||
|
||||
console.log('loading static mindmap in read-only');
|
||||
|
||||
// This hack is required to initialize Bootstrap. In future, this should be removed.
|
||||
const globalAny: any = global;
|
||||
globalAny.jQuery = jquery;
|
||||
require('../../../libraries/bootstrap/js/bootstrap.min');
|
||||
|
||||
// WebComponent registration
|
||||
customElements.define('mindplot-component', MindplotWebComponent);
|
||||
// Configure designer options ...
|
||||
const historyId = global.historyId ? `${global.historyId}/` : '';
|
||||
const persistence: PersistenceManager = new LocalStorageManager(
|
||||
`/c/restful/maps/{id}/${historyId}document/xml${!global.isAuth ? '-pub' : ''}`,
|
||||
true,
|
||||
);
|
||||
|
||||
// Obtain map zoom from query param if it was specified...
|
||||
const params = new URLSearchParams(window.location.search.substring(1));
|
||||
|
||||
const zoomParam = Number.parseFloat(params.get('zoom'));
|
||||
const options = DesignerOptionsBuilder.buildOptions({
|
||||
persistenceManager: persistence,
|
||||
mode: 'viewonly',
|
||||
mapId: global.mapId,
|
||||
container: 'mindplot',
|
||||
zoom: zoomParam || global.userOptions.zoom,
|
||||
locale: global.locale,
|
||||
});
|
||||
|
||||
// Build designer ...
|
||||
const designer = buildDesigner(options);
|
||||
|
||||
// Load map from XML file persisted on disk...
|
||||
const instance = PersistenceManager.getInstance();
|
||||
const mindmap = instance.load(global.mapId);
|
||||
designer.loadMap(mindmap);
|
||||
const webComponent: MindplotWebComponent = document.getElementById(
|
||||
'mindmap-comp',
|
||||
) as MindplotWebComponent;
|
||||
webComponent.buildDesigner(persistence);
|
||||
webComponent.loadMap(global.mapId);
|
||||
|
110
packages/mindplot/src/mindplot-styles.css
Normal file
110
packages/mindplot/src/mindplot-styles.css
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
DO NOT USE THIS FILE until we resolve how to import .css files into shadow dom
|
||||
As a workaround, use the file mindplot-styles.js instead
|
||||
*/
|
||||
.mindplot-svg-tooltip {
|
||||
display: none;
|
||||
color: rgb(51, 51, 51);
|
||||
text-align: center;
|
||||
padding: 1px;
|
||||
border-radius: 6px;
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
background-color: rgb(255, 255, 255);
|
||||
animation: fadeIn 0.4s;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn ease 0.4s;
|
||||
-webkit-animation: fadeIn ease 0.4s;
|
||||
-moz-animation: fadeIn ease 0.4s;
|
||||
-o-animation: fadeIn ease 0.4s;
|
||||
-ms-animation: fadeIn ease 0.4s;
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-moz-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-o-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-ms-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-title {
|
||||
background-color: rgb(247, 247, 247);
|
||||
border-bottom-color: rgb(235, 235, 235);
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
color: rgb(51, 51, 51);
|
||||
cursor: default;
|
||||
display: block;
|
||||
font-family: Arial;
|
||||
padding: 8px 14px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-content {
|
||||
background-color: rgb(255, 255, 255);
|
||||
padding: 6px 4px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-content-link {
|
||||
padding: 3px 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip-content-note {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid #fff;
|
||||
bottom: 100%;
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.mindplot-svg-tooltip:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid rgb(247, 247, 247);
|
||||
bottom: calc(1px + 100%);
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
}
|
@ -14,8 +14,10 @@
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
, "../editor/src/classes/menu/AccountSettingsPanel.js", "../editor/src/classes/menu/IMenu.ts", "../editor/src/classes/bootstrap" ],
|
||||
"src/**/*",
|
||||
"../editor/src/classes/menu/AccountSettingsPanel.js",
|
||||
"../editor/src/classes/menu/IMenu.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
|
@ -35,6 +35,10 @@ module.exports = {
|
||||
test: /\.(png|svg)$/i,
|
||||
type: 'asset/inline',
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: 'css-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
|
@ -20,21 +20,12 @@ const playgroundConfig = {
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
port: 8083,
|
||||
open: false,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: ['style-loader', 'css-loader?url=false'],
|
||||
},
|
||||
],
|
||||
open: false
|
||||
},
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{ from: '../../libraries/bootstrap', to: 'bootstrap' },
|
||||
{ from: 'test/playground/index.html', to: 'index.html' },
|
||||
],
|
||||
}),
|
||||
|
@ -64,7 +64,6 @@
|
||||
"@mui/styles": "^5.3.0",
|
||||
"@reduxjs/toolkit": "^1.5.0",
|
||||
"@wisemapping/editor": "^0.4.0",
|
||||
"@wisemapping/mindplot": "^5.0.2",
|
||||
"axios": "^0.21.0",
|
||||
"dayjs": "^1.10.7",
|
||||
"react": "^17.0.2",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { EditorRenderMode, Mindmap, PersistenceManager } from '@wisemapping/mindplot';
|
||||
import { EditorRenderMode, Mindmap, PersistenceManager } from '@wisemapping/editor';
|
||||
import Client, {
|
||||
AccountInfo,
|
||||
BasicMapInfo,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { EditorRenderMode, Mindmap, PersistenceManager } from '@wisemapping/mindplot';
|
||||
import { EditorRenderMode, Mindmap, PersistenceManager } from '@wisemapping/editor';
|
||||
import { Locale, LocaleCode } from '../app-i18n';
|
||||
|
||||
export type NewUser = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Mindmap, MockPersistenceManager, PersistenceManager } from '@wisemapping/mindplot';
|
||||
import XMLSerializerTango from '@wisemapping/mindplot/src/components/persistence/XMLSerializerTango';
|
||||
import { Mindmap, MockPersistenceManager, PersistenceManager } from '@wisemapping/editor';
|
||||
import XMLSerializerTango from '@wisemapping/editor';
|
||||
import Client, {
|
||||
AccountInfo,
|
||||
BasicMapInfo,
|
||||
|
@ -4,8 +4,8 @@ import {
|
||||
Mindmap,
|
||||
PersistenceManager,
|
||||
RESTPersistenceManager,
|
||||
} from '@wisemapping/mindplot';
|
||||
import { PersistenceError } from '@wisemapping/mindplot/src/components/PersistenceManager';
|
||||
} from '@wisemapping/editor';
|
||||
import { PersistenceError } from '@wisemapping/editor';
|
||||
import axios, { AxiosInstance, AxiosResponse } from 'axios';
|
||||
import Client, {
|
||||
ErrorInfo,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { EditorOptions } from '@wisemapping/editor';
|
||||
import { EditorRenderMode } from '@wisemapping/mindplot';
|
||||
import { EditorRenderMode } from '@wisemapping/editor';
|
||||
import AppConfig from '../../classes/app-config';
|
||||
|
||||
class EditorOptionsBuilder {
|
||||
|
@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
|
||||
import ActionDispatcher from '../maps-page/action-dispatcher';
|
||||
import { ActionType } from '../maps-page/action-chooser';
|
||||
import Editor from '@wisemapping/editor';
|
||||
import { EditorRenderMode, PersistenceManager } from '@wisemapping/mindplot';
|
||||
import { EditorRenderMode, PersistenceManager } from '@wisemapping/editor';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import AppI18n, { Locales } from '../../classes/app-i18n';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
@ -16,12 +16,12 @@ import {
|
||||
ImageExporterFactory,
|
||||
Exporter,
|
||||
Mindmap,
|
||||
} from '@wisemapping/mindplot';
|
||||
} from '@wisemapping/editor';
|
||||
import Client from '../../../../classes/client';
|
||||
import { activeInstance } from '../../../../redux/clientSlice';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
import SizeType from '@wisemapping/mindplot/src/components/SizeType';
|
||||
import SizeType from '@wisemapping/editor';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
|
||||
type ExportFormat = 'svg' | 'jpg' | 'png' | 'txt' | 'mm' | 'wxml' | 'xls' | 'md';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Alert } from '@mui/material';
|
||||
import Button from '@mui/material/Button';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import { Importer, TextImporterFactory } from '@wisemapping/mindplot';
|
||||
import { Importer, TextImporterFactory } from '@wisemapping/editor';
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage, useIntl } from 'react-intl';
|
||||
|
@ -34,6 +34,10 @@ module.exports = {
|
||||
test: /\.wxml$/i,
|
||||
type: 'asset/source',
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: 'css-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
|
Loading…
Reference in New Issue
Block a user