mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-22 06:37:56 +01:00
Merge branch 'develop' of https://bitbucket.org/wisemapping/wisemapping-frontend into feature/testing-editor
This commit is contained in:
commit
d81b68bf33
@ -43,7 +43,10 @@
|
|||||||
"import/resolver": {
|
"import/resolver": {
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"config": "./webpack.common.js"
|
"config": "./webpack.common.js"
|
||||||
}
|
},
|
||||||
|
"node": {
|
||||||
|
"extensions": [".js",".ts"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,6 @@ import LayoutManager from './layout/LayoutManager';
|
|||||||
|
|
||||||
import { TopicShape } from './model/INodeModel';
|
import { TopicShape } from './model/INodeModel';
|
||||||
import { $notify } from './widget/ToolbarNotifier';
|
import { $notify } from './widget/ToolbarNotifier';
|
||||||
import ImageExpoterFactory from './export/ImageExporterFactory';
|
|
||||||
import TextExporterFactory from './export/TextExporterFactory';
|
|
||||||
import RelationshipModel from './model/RelationshipModel';
|
import RelationshipModel from './model/RelationshipModel';
|
||||||
import Mindmap from './model/Mindmap';
|
import Mindmap from './model/Mindmap';
|
||||||
import NodeModel from './model/NodeModel';
|
import NodeModel from './model/NodeModel';
|
||||||
@ -57,8 +55,7 @@ import Topic from './Topic';
|
|||||||
import { DesignerOptions } from './DesignerOptionsBuilder';
|
import { DesignerOptions } from './DesignerOptionsBuilder';
|
||||||
import MainTopic from './MainTopic';
|
import MainTopic from './MainTopic';
|
||||||
import DragTopic from './DragTopic';
|
import DragTopic from './DragTopic';
|
||||||
|
import CentralTopic from './CentralTopic';
|
||||||
export type ExportFormat = 'png' | 'svg' | 'jpg' | 'wxml';
|
|
||||||
|
|
||||||
class Designer extends Events {
|
class Designer extends Events {
|
||||||
private _mindmap: Mindmap;
|
private _mindmap: Mindmap;
|
||||||
@ -94,7 +91,9 @@ class Designer extends Events {
|
|||||||
this._options = options;
|
this._options = options;
|
||||||
|
|
||||||
// Set full div elem render area ...
|
// Set full div elem render area ...
|
||||||
divElement.css(options.containerSize);
|
if (options.containerSize) {
|
||||||
|
divElement.css(options.containerSize);
|
||||||
|
}
|
||||||
|
|
||||||
// Dispatcher manager ...
|
// Dispatcher manager ...
|
||||||
const commandContext = new CommandContext(this);
|
const commandContext = new CommandContext(this);
|
||||||
@ -180,14 +179,16 @@ class Designer extends Events {
|
|||||||
|
|
||||||
// Deselect on click ...
|
// Deselect on click ...
|
||||||
screenManager.addEvent('click', (event: UIEvent) => {
|
screenManager.addEvent('click', (event: UIEvent) => {
|
||||||
me.onObjectFocusEvent(null, event);
|
me.onObjectFocusEvent(undefined, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create nodes on double click...
|
// Create nodes on double click...
|
||||||
screenManager.addEvent('dblclick', (event: MouseEvent) => {
|
screenManager.addEvent('dblclick', (event: MouseEvent) => {
|
||||||
if (workspace.isWorkspaceEventsEnabled()) {
|
if (workspace.isWorkspaceEventsEnabled()) {
|
||||||
const mousePos = screenManager.getWorkspaceMousePosition(event);
|
const mousePos = screenManager.getWorkspaceMousePosition(event);
|
||||||
const centralTopic = me.getModel().getCentralTopic();
|
const centralTopic:CentralTopic = me.getModel()
|
||||||
|
.getCentralTopic();
|
||||||
|
|
||||||
const model = me._createChildModel(centralTopic, mousePos);
|
const model = me._createChildModel(centralTopic, mousePos);
|
||||||
this._actionDispatcher.addTopics([model], [centralTopic.getId()]);
|
this._actionDispatcher.addTopics([model], [centralTopic.getId()]);
|
||||||
}
|
}
|
||||||
@ -282,13 +283,7 @@ class Designer extends Events {
|
|||||||
return topic;
|
return topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
onObjectFocusEvent(currentObject?: Topic, event?): void {
|
||||||
* @param {?mindplot.Topic} currentObject
|
|
||||||
* @param {Event=} event
|
|
||||||
* sets focus to the given currentObject and removes it from any other objects if not
|
|
||||||
* triggered with Ctrl pressed
|
|
||||||
*/
|
|
||||||
onObjectFocusEvent(currentObject: Topic = null, event = null): void {
|
|
||||||
// Close node editors ..
|
// Close node editors ..
|
||||||
const topics = this.getModel().getTopics();
|
const topics = this.getModel().getTopics();
|
||||||
topics.forEach((topic) => topic.closeEditors());
|
topics.forEach((topic) => topic.closeEditors());
|
||||||
@ -347,32 +342,6 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SUPPORTED_FORMATS: ExportFormat[] = ['png', 'svg', 'jpg', 'wxml'];
|
|
||||||
|
|
||||||
export(formatType: ExportFormat): Promise<string> {
|
|
||||||
const workspace = this._workspace;
|
|
||||||
const svgElement = workspace.getSVGElement();
|
|
||||||
const size = workspace.getSize();
|
|
||||||
|
|
||||||
let exporter;
|
|
||||||
switch (formatType) {
|
|
||||||
case 'png':
|
|
||||||
case 'jpg':
|
|
||||||
case 'svg': {
|
|
||||||
exporter = ImageExpoterFactory.create(formatType, this._mindmap, svgElement, size.width, size.height);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'wxml': {
|
|
||||||
exporter = TextExporterFactory.create(formatType, this._mindmap);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new Error('Unsupported encoding');
|
|
||||||
}
|
|
||||||
|
|
||||||
return exporter.export();
|
|
||||||
}
|
|
||||||
|
|
||||||
zoomIn(factor = 1.2): void {
|
zoomIn(factor = 1.2): void {
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
const scale = model.getZoom() / factor;
|
const scale = model.getZoom() / factor;
|
||||||
@ -530,21 +499,24 @@ class Designer extends Events {
|
|||||||
const parentTopic = topic.getOutgoingConnectedTopic();
|
const parentTopic = topic.getOutgoingConnectedTopic();
|
||||||
const siblingModel = this._createSiblingModel(topic);
|
const siblingModel = this._createSiblingModel(topic);
|
||||||
|
|
||||||
// Hack: if parent is central topic, add node below not on opposite side.
|
if (siblingModel) {
|
||||||
// This should be done in the layout
|
// Hack: if parent is central topic, add node below not on opposite side.
|
||||||
if (parentTopic.getType() === 'CentralTopic') {
|
// This should be done in the layout
|
||||||
siblingModel.setOrder(topic.getOrder() + 2);
|
if (parentTopic.getType() === 'CentralTopic') {
|
||||||
}
|
siblingModel.setOrder(topic.getOrder() + 2);
|
||||||
|
}
|
||||||
|
|
||||||
const parentTopicId = parentTopic.getId();
|
const parentTopicId = parentTopic.getId();
|
||||||
this._actionDispatcher.addTopics([siblingModel], [parentTopicId]);
|
this._actionDispatcher.addTopics([siblingModel], [parentTopicId]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createSiblingModel(topic: Topic): NodeModel {
|
private _createSiblingModel(topic: Topic): NodeModel | undefined {
|
||||||
let result = null;
|
let result: NodeModel | undefined;
|
||||||
let model = null;
|
let model: NodeModel;
|
||||||
const parentTopic = topic.getOutgoingConnectedTopic();
|
const parentTopic = topic.getOutgoingConnectedTopic();
|
||||||
|
|
||||||
if (parentTopic != null) {
|
if (parentTopic != null) {
|
||||||
// Create a new node ...
|
// Create a new node ...
|
||||||
model = topic.getModel();
|
model = topic.getModel();
|
||||||
@ -555,9 +527,9 @@ class Designer extends Events {
|
|||||||
const order = topic.getOrder() + 1;
|
const order = topic.getOrder() + 1;
|
||||||
result.setOrder(order);
|
result.setOrder(order);
|
||||||
result.setPosition(10, 10); // Set a dummy position ...
|
result.setPosition(10, 10); // Set a dummy position ...
|
||||||
}
|
|
||||||
|
|
||||||
this._copyNodeProps(model, result);
|
this._copyNodeProps(model, result);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -598,8 +570,10 @@ class Designer extends Events {
|
|||||||
layoutManager.addEvent('change', (event) => {
|
layoutManager.addEvent('change', (event) => {
|
||||||
const id = event.getId();
|
const id = event.getId();
|
||||||
const topic = me.getModel().findTopicById(id);
|
const topic = me.getModel().findTopicById(id);
|
||||||
topic.setPosition(event.getPosition());
|
if (topic) {
|
||||||
topic.setOrder(event.getOrder());
|
topic.setPosition(event.getPosition());
|
||||||
|
topic.setOrder(event.getOrder());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this._eventBussDispatcher.setLayoutManager(layoutManager);
|
this._eventBussDispatcher.setLayoutManager(layoutManager);
|
||||||
|
|
||||||
@ -636,9 +610,8 @@ class Designer extends Events {
|
|||||||
this._actionDispatcher.actionRunner.redo();
|
this._actionDispatcher.actionRunner.redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
|
||||||
isReadOnly(): boolean {
|
isReadOnly(): boolean {
|
||||||
return this._options.readOnly;
|
return Boolean(this._options?.readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeModelToTopic(nodeModel: NodeModel): Topic {
|
nodeModelToTopic(nodeModel: NodeModel): Topic {
|
||||||
@ -825,15 +798,14 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
|
||||||
changeFontFamily(font: string) {
|
changeFontFamily(font: string) {
|
||||||
const topicsIds = this.getModel().filterTopicsIds();
|
const topicsIds = this.getModel()
|
||||||
|
.filterTopicsIds();
|
||||||
if (topicsIds.length > 0) {
|
if (topicsIds.length > 0) {
|
||||||
this._actionDispatcher.changeFontFamilyToTopic(topicsIds, font);
|
this._actionDispatcher.changeFontFamilyToTopic(topicsIds, font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
|
||||||
changeFontStyle(): void {
|
changeFontStyle(): void {
|
||||||
const topicsIds = this.getModel()
|
const topicsIds = this.getModel()
|
||||||
.filterTopicsIds();
|
.filterTopicsIds();
|
||||||
@ -842,7 +814,6 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
|
||||||
changeFontColor(color: string) {
|
changeFontColor(color: string) {
|
||||||
$assert(color, 'color can not be null');
|
$assert(color, 'color can not be null');
|
||||||
|
|
||||||
@ -883,9 +854,8 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
changeTopicShape(shape: string) {
|
||||||
changeTopicShape(shape) {
|
const validateFunc = (topic: Topic) => !(
|
||||||
const validateFunc = (topic) => !(
|
|
||||||
topic.getType() === 'CentralTopic' && shape === TopicShape.LINE
|
topic.getType() === 'CentralTopic' && shape === TopicShape.LINE
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -896,16 +866,14 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
changeFontWeight(): void {
|
||||||
changeFontWeight() {
|
|
||||||
const topicsIds = this.getModel().filterTopicsIds();
|
const topicsIds = this.getModel().filterTopicsIds();
|
||||||
if (topicsIds.length > 0) {
|
if (topicsIds.length > 0) {
|
||||||
this._actionDispatcher.changeFontWeightToTopic(topicsIds);
|
this._actionDispatcher.changeFontWeightToTopic(topicsIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
addIconType(iconType: string): void {
|
||||||
addIconType(iconType) {
|
|
||||||
const topicsIds = this.getModel().filterTopicsIds();
|
const topicsIds = this.getModel().filterTopicsIds();
|
||||||
if (topicsIds.length > 0) {
|
if (topicsIds.length > 0) {
|
||||||
this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeatureFactory.Icon.id, {
|
this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeatureFactory.Icon.id, {
|
||||||
@ -915,9 +883,9 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lets the selected topic open the link editor where the user can define or modify an
|
* lets the selected topic open the link editor where the user can define or modify an
|
||||||
* existing link
|
* existing link
|
||||||
*/
|
*/
|
||||||
addLink() {
|
addLink() {
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
const topic = model.selectedTopic();
|
const topic = model.selectedTopic();
|
||||||
@ -937,19 +905,22 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
goToNode(node: Topic): void {
|
||||||
* @param {mindplot.Topic} node
|
|
||||||
* sets the focus to the given node
|
|
||||||
*/
|
|
||||||
goToNode(node) {
|
|
||||||
node.setOnFocus(true);
|
node.setOnFocus(true);
|
||||||
this.onObjectFocusEvent(node);
|
this.onObjectFocusEvent(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return {mindplot.Workspace} */
|
getWorkSpace(): Workspace {
|
||||||
getWorkSpace() {
|
|
||||||
return this._workspace;
|
return this._workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get cleanScreen(): () => void {
|
||||||
|
return this._cleanScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set cleanScreen(value: () => void) {
|
||||||
|
this._cleanScreen = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Designer;
|
export default Designer;
|
||||||
|
@ -24,7 +24,7 @@ import { $notifyModal } from './widget/ModalDialogNotifier';
|
|||||||
import { $msg } from './Messages';
|
import { $msg } from './Messages';
|
||||||
import { DesignerOptions } from './DesignerOptionsBuilder';
|
import { DesignerOptions } from './DesignerOptionsBuilder';
|
||||||
|
|
||||||
let designer = null;
|
let designer: Designer;
|
||||||
|
|
||||||
export function buildDesigner(options: DesignerOptions): Designer {
|
export function buildDesigner(options: DesignerOptions): Designer {
|
||||||
const divContainer = $(`#${options.container}`);
|
const divContainer = $(`#${options.container}`);
|
||||||
@ -38,7 +38,7 @@ export function buildDesigner(options: DesignerOptions): Designer {
|
|||||||
console.log('Map loadded successfully');
|
console.log('Map loadded successfully');
|
||||||
});
|
});
|
||||||
|
|
||||||
const onerrorFn = (message:string, url, lineNo) => {
|
const onerrorFn = (message: string, url, lineNo) => {
|
||||||
// Close loading dialog ...
|
// Close loading dialog ...
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (window.waitDialog) {
|
if (window.waitDialog) {
|
||||||
@ -64,10 +64,10 @@ export function buildDesigner(options: DesignerOptions): Designer {
|
|||||||
|
|
||||||
// Register toolbar event ...
|
// Register toolbar event ...
|
||||||
if ($('#toolbar').length) {
|
if ($('#toolbar').length) {
|
||||||
const menu = new Menu(designer, 'toolbar', options.mapId);
|
const menu = new Menu(designer, 'toolbar', options.mapId ? options.mapId : 'unknown');
|
||||||
|
|
||||||
// If a node has focus, focus can be move to another node using the keys.
|
// If a node has focus, focus can be move to another node using the keys.
|
||||||
designer._cleanScreen = function _cleanScreen() {
|
designer.cleanScreen = () => {
|
||||||
menu.clear();
|
menu.clear();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import CentralTopic from './CentralTopic';
|
import CentralTopic from './CentralTopic';
|
||||||
import { DesignerOptions } from './DesignerOptionsBuilder';
|
import { DesignerOptions } from './DesignerOptionsBuilder';
|
||||||
import Events from './Events';
|
import Events from './Events';
|
||||||
@ -24,11 +24,11 @@ import Topic from './Topic';
|
|||||||
import { $notify } from './widget/ToolbarNotifier';
|
import { $notify } from './widget/ToolbarNotifier';
|
||||||
|
|
||||||
class DesignerModel extends Events {
|
class DesignerModel extends Events {
|
||||||
_zoom: number;
|
private _zoom: number;
|
||||||
|
|
||||||
_topics: Topic[];
|
private _topics: Topic[];
|
||||||
|
|
||||||
_relationships: Relationship[];
|
private _relationships: Relationship[];
|
||||||
|
|
||||||
constructor(options: DesignerOptions) {
|
constructor(options: DesignerOptions) {
|
||||||
super();
|
super();
|
||||||
@ -37,11 +37,11 @@ class DesignerModel extends Events {
|
|||||||
this._relationships = [];
|
this._relationships = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getZoom():number {
|
getZoom(): number {
|
||||||
return this._zoom;
|
return this._zoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
setZoom(zoom: number):void {
|
setZoom(zoom: number): void {
|
||||||
this._zoom = zoom;
|
this._zoom = zoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,12 +55,11 @@ class DesignerModel extends Events {
|
|||||||
|
|
||||||
getCentralTopic(): CentralTopic {
|
getCentralTopic(): CentralTopic {
|
||||||
const topics = this.getTopics();
|
const topics = this.getTopics();
|
||||||
return topics[0] as CentralTopic;
|
return topics[0] as unknown as CentralTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return {mindplot.Topic[]} selected topics */
|
|
||||||
filterSelectedTopics(): Topic[] {
|
filterSelectedTopics(): Topic[] {
|
||||||
const result = [];
|
const result: Topic[] = [];
|
||||||
for (let i = 0; i < this._topics.length; i++) {
|
for (let i = 0; i < this._topics.length; i++) {
|
||||||
if (this._topics[i].isOnFocus()) {
|
if (this._topics[i].isOnFocus()) {
|
||||||
result.push(this._topics[i]);
|
result.push(this._topics[i]);
|
||||||
@ -70,7 +69,7 @@ class DesignerModel extends Events {
|
|||||||
}
|
}
|
||||||
|
|
||||||
filterSelectedRelationships(): Relationship[] {
|
filterSelectedRelationships(): Relationship[] {
|
||||||
const result = [];
|
const result:Relationship[] = [];
|
||||||
for (let i = 0; i < this._relationships.length; i++) {
|
for (let i = 0; i < this._relationships.length; i++) {
|
||||||
if (this._relationships[i].isOnFocus()) {
|
if (this._relationships[i].isOnFocus()) {
|
||||||
result.push(this._relationships[i]);
|
result.push(this._relationships[i]);
|
||||||
@ -80,17 +79,18 @@ class DesignerModel extends Events {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getEntities(): (Relationship | Topic)[] {
|
getEntities(): (Relationship | Topic)[] {
|
||||||
let result = [].concat(this._topics);
|
let result:(Relationship|Topic)[] = [];
|
||||||
|
result = result.concat(this._topics);
|
||||||
result = result.concat(this._relationships);
|
result = result.concat(this._relationships);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeTopic(topic:Topic):void {
|
removeTopic(topic: Topic): void {
|
||||||
$assert(topic, 'topic can not be null');
|
$assert(topic, 'topic can not be null');
|
||||||
this._topics = this._topics.filter((t) => t !== topic);
|
this._topics = this._topics.filter((t) => t !== topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeRelationship(rel:Relationship):void {
|
removeRelationship(rel: Relationship): void {
|
||||||
$assert(rel, 'rel can not be null');
|
$assert(rel, 'rel can not be null');
|
||||||
this._relationships = this._relationships.filter((r) => r !== rel);
|
this._relationships = this._relationships.filter((r) => r !== rel);
|
||||||
}
|
}
|
||||||
@ -106,13 +106,13 @@ class DesignerModel extends Events {
|
|||||||
this._relationships.push(rel);
|
this._relationships.push(rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
filterTopicsIds(validate: (topic: Topic) => boolean = null, errorMsg = null): number[] {
|
filterTopicsIds(validate?: (topic: Topic) => boolean, errorMsg?: string): number[] {
|
||||||
const result = [];
|
const result: number[] = [];
|
||||||
const topics = this.filterSelectedTopics();
|
const topics = this.filterSelectedTopics();
|
||||||
|
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
topics.forEach((topic) => {
|
topics.forEach((topic) => {
|
||||||
if ($defined(validate)) {
|
if (validate) {
|
||||||
isValid = validate(topic);
|
isValid = validate(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,13 +127,13 @@ class DesignerModel extends Events {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedTopic(): Topic {
|
selectedTopic(): Topic | undefined {
|
||||||
const topics = this.filterSelectedTopics();
|
const topics = this.filterSelectedTopics();
|
||||||
return (topics.length > 0) ? topics[0] : null;
|
return (topics.length > 0) ? topics[0] : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
findTopicById(id: number): Topic {
|
findTopicById(id: number): Topic | undefined {
|
||||||
let result = null;
|
let result: Topic | undefined;
|
||||||
for (let i = 0; i < this._topics.length; i++) {
|
for (let i = 0; i < this._topics.length; i++) {
|
||||||
const topic = this._topics[i];
|
const topic = this._topics[i];
|
||||||
if (topic.getId() === id) {
|
if (topic.getId() === id) {
|
||||||
|
@ -38,13 +38,13 @@ abstract class IMindmap {
|
|||||||
|
|
||||||
abstract setVersion(version: string): void;
|
abstract setVersion(version: string): void;
|
||||||
|
|
||||||
abstract addBranch(nodeModel: INodeModel): void;
|
abstract addBranch(nodeModel): void;
|
||||||
|
|
||||||
abstract getBranches(): Array<INodeModel>;
|
abstract getBranches();
|
||||||
|
|
||||||
abstract removeBranch(node: INodeModel): void;
|
abstract removeBranch(node): void;
|
||||||
|
|
||||||
abstract getRelationships(): Array<RelationshipModel>;
|
abstract getRelationships(): RelationshipModel[];
|
||||||
|
|
||||||
connect(parent: INodeModel, child: INodeModel): void {
|
connect(parent: INodeModel, child: INodeModel): void {
|
||||||
// Child already has a parent ?
|
// Child already has a parent ?
|
||||||
@ -71,9 +71,9 @@ abstract class IMindmap {
|
|||||||
this.addBranch(child);
|
this.addBranch(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract hasAlreadyAdded(node: INodeModel): boolean;
|
abstract hasAlreadyAdded(node): boolean;
|
||||||
|
|
||||||
abstract createNode(type: NodeType, id: number): INodeModel
|
abstract createNode(type: NodeType, id: number)
|
||||||
|
|
||||||
abstract createRelationship(fromNodeId: number, toNodeId: number): void;
|
abstract createRelationship(fromNodeId: number, toNodeId: number): void;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ const parseJsObject = (str: string) => JSON.parse(str.replace(/(['"])?([a-z0-9A-
|
|||||||
abstract class INodeModel {
|
abstract class INodeModel {
|
||||||
static MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE = 220;
|
static MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE = 220;
|
||||||
|
|
||||||
static _next_uuid = 0;
|
private static _next_uuid = 0;
|
||||||
|
|
||||||
protected _mindmap: Mindmap;
|
protected _mindmap: Mindmap;
|
||||||
|
|
||||||
@ -43,8 +43,7 @@ abstract class INodeModel {
|
|||||||
|
|
||||||
abstract getFeatures(): FeatureModel[];
|
abstract getFeatures(): FeatureModel[];
|
||||||
|
|
||||||
/** */
|
setId(id?: number): void {
|
||||||
setId(id: number): void {
|
|
||||||
if (!$defined(id)) {
|
if (!$defined(id)) {
|
||||||
const newId = INodeModel._nextUUID();
|
const newId = INodeModel._nextUUID();
|
||||||
this.putProperty('id', newId);
|
this.putProperty('id', newId);
|
||||||
@ -79,7 +78,7 @@ abstract class INodeModel {
|
|||||||
|
|
||||||
getPosition(): { x: number, y: number } {
|
getPosition(): { x: number, y: number } {
|
||||||
const value = this.getProperty('position') as string;
|
const value = this.getProperty('position') as string;
|
||||||
let result = null;
|
let result;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result = parseJsObject(value);
|
result = parseJsObject(value);
|
||||||
}
|
}
|
||||||
@ -92,7 +91,7 @@ abstract class INodeModel {
|
|||||||
|
|
||||||
getImageSize(): {width: number, height: number} {
|
getImageSize(): {width: number, height: number} {
|
||||||
const value = this.getProperty('imageSize') as string;
|
const value = this.getProperty('imageSize') as string;
|
||||||
let result = null;
|
let result;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result = parseJsObject(value);
|
result = parseJsObject(value);
|
||||||
}
|
}
|
||||||
@ -261,7 +260,7 @@ abstract class INodeModel {
|
|||||||
const tmindmap = target.getMindmap();
|
const tmindmap = target.getMindmap();
|
||||||
|
|
||||||
children.forEach((snode) => {
|
children.forEach((snode) => {
|
||||||
const tnode = tmindmap.createNode(snode.getType(), snode.getId());
|
const tnode:INodeModel = tmindmap.createNode(snode.getType(), snode.getId());
|
||||||
snode.copyTo(tnode);
|
snode.copyTo(tnode);
|
||||||
target.append(tnode);
|
target.append(tnode);
|
||||||
});
|
});
|
||||||
@ -276,16 +275,14 @@ abstract class INodeModel {
|
|||||||
deleteNode(): void {
|
deleteNode(): void {
|
||||||
const mindmap = this.getMindmap();
|
const mindmap = this.getMindmap();
|
||||||
|
|
||||||
// console.log("Before:" + mindmap.inspect());
|
|
||||||
const parent = this.getParent();
|
const parent = this.getParent();
|
||||||
if ($defined(parent)) {
|
if (parent) {
|
||||||
parent.removeChild(this);
|
parent.removeChild(this);
|
||||||
} else {
|
} else {
|
||||||
// If it has not parent, it must be an isolate topic ...
|
// If it has not parent, it must be an isolate topic ...
|
||||||
|
// @ts-ignore
|
||||||
mindmap.removeBranch(this);
|
mindmap.removeBranch(this);
|
||||||
}
|
}
|
||||||
// It's an isolated node. It must be a hole branch ...
|
|
||||||
// console.log("After:" + mindmap.inspect());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract getPropertiesKeys(): string[];
|
abstract getPropertiesKeys(): string[];
|
||||||
@ -298,7 +295,7 @@ abstract class INodeModel {
|
|||||||
|
|
||||||
abstract getChildren(): INodeModel[];
|
abstract getChildren(): INodeModel[];
|
||||||
|
|
||||||
abstract getParent(): INodeModel;
|
abstract getParent(): INodeModel | null;
|
||||||
|
|
||||||
abstract clone(): INodeModel;
|
abstract clone(): INodeModel;
|
||||||
|
|
||||||
@ -321,7 +318,7 @@ abstract class INodeModel {
|
|||||||
|
|
||||||
findNodeById(id: number): INodeModel {
|
findNodeById(id: number): INodeModel {
|
||||||
$assert(Number.isFinite(id));
|
$assert(Number.isFinite(id));
|
||||||
let result = null;
|
let result;
|
||||||
if (this.getId() === id) {
|
if (this.getId() === id) {
|
||||||
result = this;
|
result = this;
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,7 +38,7 @@ class Mindmap extends IMindmap {
|
|||||||
$assert(id, 'Id can not be null');
|
$assert(id, 'Id can not be null');
|
||||||
|
|
||||||
this._branches = [];
|
this._branches = [];
|
||||||
this._description = null;
|
this._description = '';
|
||||||
this._relationships = [];
|
this._relationships = [];
|
||||||
this._version = version;
|
this._version = version;
|
||||||
this._id = id;
|
this._id = id;
|
||||||
@ -79,7 +79,7 @@ class Mindmap extends IMindmap {
|
|||||||
* @throws will throw an error if nodeModel is null, undefined or not a node model object
|
* @throws will throw an error if nodeModel is null, undefined or not a node model object
|
||||||
* @throws will throw an error if
|
* @throws will throw an error if
|
||||||
*/
|
*/
|
||||||
addBranch(nodeModel: NodeModel): void {
|
addBranch(nodeModel: INodeModel): void {
|
||||||
$assert(nodeModel && nodeModel.isNodeModel(), 'Add node must be invoked with model objects');
|
$assert(nodeModel && nodeModel.isNodeModel(), 'Add node must be invoked with model objects');
|
||||||
const branches = this.getBranches();
|
const branches = this.getBranches();
|
||||||
if (branches.length === 0) {
|
if (branches.length === 0) {
|
||||||
@ -89,18 +89,18 @@ class Mindmap extends IMindmap {
|
|||||||
$assert(nodeModel.getType() !== 'CentralTopic', 'Mindmaps only have one cental topic');
|
$assert(nodeModel.getType() !== 'CentralTopic', 'Mindmaps only have one cental topic');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._branches.push(nodeModel);
|
this._branches.push(nodeModel as NodeModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param nodeModel
|
* @param nodeModel
|
||||||
*/
|
*/
|
||||||
removeBranch(nodeModel: INodeModel): void {
|
removeBranch(nodeModel: NodeModel): void {
|
||||||
$assert(nodeModel && nodeModel.isNodeModel(), 'Remove node must be invoked with model objects');
|
$assert(nodeModel && nodeModel.isNodeModel(), 'Remove node must be invoked with model objects');
|
||||||
this._branches = this._branches.filter((b) => b !== nodeModel);
|
this._branches = this._branches.filter((b) => b !== nodeModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBranches() {
|
getBranches():NodeModel[] {
|
||||||
return this._branches;
|
return this._branches;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,11 +122,11 @@ class Mindmap extends IMindmap {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
createNode(type: NodeModelType = 'MainTopic', id: number) {
|
createNode(type: NodeModelType = 'MainTopic', id?: number):NodeModel {
|
||||||
return new NodeModel(type, this, id);
|
return new NodeModel(type, this, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
createRelationship(sourceNodeId: number, targetNodeId: number):RelationshipModel {
|
createRelationship(sourceNodeId: number, targetNodeId: number): RelationshipModel {
|
||||||
$assert($defined(sourceNodeId), 'from node cannot be null');
|
$assert($defined(sourceNodeId), 'from node cannot be null');
|
||||||
$assert($defined(targetNodeId), 'to node cannot be null');
|
$assert($defined(targetNodeId), 'to node cannot be null');
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ class Mindmap extends IMindmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findNodeById(id: number) {
|
findNodeById(id: number) {
|
||||||
let result = null;
|
let result;
|
||||||
for (let i = 0; i < this._branches.length; i++) {
|
for (let i = 0; i < this._branches.length; i++) {
|
||||||
const branch = this._branches[i];
|
const branch = this._branches[i];
|
||||||
result = branch.findNodeById(id);
|
result = branch.findNodeById(id);
|
||||||
|
@ -31,9 +31,9 @@ class NodeModel extends INodeModel {
|
|||||||
private _features: FeatureModel[];
|
private _features: FeatureModel[];
|
||||||
|
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
private _parent: NodeModel;
|
private _parent: NodeModel | null;
|
||||||
|
|
||||||
constructor(type: NodeModelType, mindmap: Mindmap, id: number) {
|
constructor(type: NodeModelType, mindmap: Mindmap, id?: number) {
|
||||||
$assert(type, 'Node type can not be null');
|
$assert(type, 'Node type can not be null');
|
||||||
$assert(mindmap, 'mindmap can not be null');
|
$assert(mindmap, 'mindmap can not be null');
|
||||||
super(mindmap);
|
super(mindmap);
|
||||||
@ -121,10 +121,9 @@ class NodeModel extends INodeModel {
|
|||||||
return this._properties;
|
return this._properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
getProperty(key: string) {
|
getProperty(key: string): number | string | boolean {
|
||||||
$defined(key, 'key can not be null');
|
$defined(key, 'key can not be null');
|
||||||
const result = this._properties[key];
|
return this._properties[key];
|
||||||
return !$defined(result) ? null : result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,7 +186,7 @@ class NodeModel extends INodeModel {
|
|||||||
return this._children;
|
return this._children;
|
||||||
}
|
}
|
||||||
|
|
||||||
getParent(): NodeModel {
|
getParent(): NodeModel | null {
|
||||||
return this._parent;
|
return this._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ class Menu extends IMenu {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
setValue(value) {
|
setValue(value:string) {
|
||||||
designer.changeTopicShape(value);
|
designer.changeTopicShape(value);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -121,7 +121,7 @@ class Menu extends IMenu {
|
|||||||
getValue() {
|
getValue() {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
setValue(value) {
|
setValue(value: string) {
|
||||||
designer.addIconType(value);
|
designer.addIconType(value);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -146,7 +146,7 @@ class Menu extends IMenu {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
setValue(hex) {
|
setValue(hex:string) {
|
||||||
designer.changeBackgroundColor(hex);
|
designer.changeBackgroundColor(hex);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,10 @@ import LocalStorageManager from './components/LocalStorageManager';
|
|||||||
import RESTPersistenceManager from './components/RestPersistenceManager';
|
import RESTPersistenceManager from './components/RestPersistenceManager';
|
||||||
import Menu from './components/widget/Menu';
|
import Menu from './components/widget/Menu';
|
||||||
import DesignerOptionsBuilder from './components/DesignerOptionsBuilder';
|
import DesignerOptionsBuilder from './components/DesignerOptionsBuilder';
|
||||||
|
import ImageExporterFactory from './components/export/ImageExporterFactory';
|
||||||
|
import TextExporterFactory from './components/export/TextExporterFactory';
|
||||||
|
import Exporter from './components/export/Exporter';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
buildDesigner,
|
buildDesigner,
|
||||||
} from './components/DesignerBuilder';
|
} from './components/DesignerBuilder';
|
||||||
@ -32,6 +36,7 @@ import {
|
|||||||
} from './components/widget/ToolbarNotifier';
|
} from './components/widget/ToolbarNotifier';
|
||||||
|
|
||||||
// This hack is required to initialize Bootstrap. In future, this should be removed.
|
// This hack is required to initialize Bootstrap. In future, this should be removed.
|
||||||
|
// @ts-ignore
|
||||||
global.jQuery = jquery;
|
global.jQuery = jquery;
|
||||||
require('@libraries/bootstrap/js/bootstrap');
|
require('@libraries/bootstrap/js/bootstrap');
|
||||||
|
|
||||||
@ -45,5 +50,8 @@ export {
|
|||||||
LocalStorageManager,
|
LocalStorageManager,
|
||||||
DesignerOptionsBuilder,
|
DesignerOptionsBuilder,
|
||||||
buildDesigner,
|
buildDesigner,
|
||||||
|
TextExporterFactory,
|
||||||
|
ImageExporterFactory,
|
||||||
|
Exporter,
|
||||||
$notify,
|
$notify,
|
||||||
};
|
};
|
@ -7,7 +7,10 @@
|
|||||||
"moduleResolution": "Node",
|
"moduleResolution": "Node",
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true,
|
||||||
|
"rootDirs": [
|
||||||
|
"src",
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules"],
|
"exclude": ["node_modules"],
|
||||||
"files": ["mindplot.d.ts"]
|
"files": ["mindplot.d.ts"]
|
||||||
|
@ -10,7 +10,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
entry: {
|
entry: {
|
||||||
mindplot: './src/index.js',
|
mindplot: './src/index.ts',
|
||||||
loader: './src/indexLoader.ts',
|
loader: './src/indexLoader.ts',
|
||||||
},
|
},
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.57",
|
"@material-ui/lab": "^4.0.0-alpha.57",
|
||||||
"@reduxjs/toolkit": "^1.5.0",
|
"@reduxjs/toolkit": "^1.5.0",
|
||||||
"@wisemapping/editor": "^0.1.0",
|
"@wisemapping/editor": "^0.4.0",
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
"dayjs": "^1.10.4",
|
"dayjs": "^1.10.4",
|
||||||
"react": "^17.0.0",
|
"react": "^17.0.0",
|
||||||
|
@ -10,8 +10,9 @@ import FormControlLabel from '@material-ui/core/FormControlLabel';
|
|||||||
import Radio from '@material-ui/core/Radio';
|
import Radio from '@material-ui/core/Radio';
|
||||||
import Select from '@material-ui/core/Select';
|
import Select from '@material-ui/core/Select';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
import { Designer, TextExporterFactory, ImageExpoterFactory, Exporter, MindMap, RESTPersistenceManager } from '@wisemapping/mindplot';
|
||||||
|
|
||||||
type ExportFormat = 'pdf' | 'svg' | 'jpg' | 'png' | 'txt' | 'mm' | 'wxml' | 'xls' | 'txt';
|
type ExportFormat = 'svg' | 'jpg' | 'png' | 'txt' | 'mm' | 'wxml' | 'xls' | 'md';
|
||||||
type ExportGroup = 'image' | 'document' | 'mindmap-tool';
|
type ExportGroup = 'image' | 'document' | 'mindmap-tool';
|
||||||
|
|
||||||
type ExportDialogProps = {
|
type ExportDialogProps = {
|
||||||
@ -24,15 +25,11 @@ type ExportDialogProps = {
|
|||||||
const ExportDialog = ({
|
const ExportDialog = ({
|
||||||
mapId,
|
mapId,
|
||||||
onClose,
|
onClose,
|
||||||
enableImgExport,
|
enableImgExport
|
||||||
svgXml,
|
|
||||||
}: ExportDialogProps): React.ReactElement => {
|
}: ExportDialogProps): React.ReactElement => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [submit, setSubmit] = React.useState<boolean>(false);
|
const [submit, setSubmit] = React.useState<boolean>(false);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const [formExportRef, setExportFormRef] = React.useState<any>();
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const [formTransformtRef, setTransformFormRef] = React.useState<any>();
|
|
||||||
const [exportGroup, setExportGroup] = React.useState<ExportGroup>(
|
const [exportGroup, setExportGroup] = React.useState<ExportGroup>(
|
||||||
enableImgExport ? 'image' : 'document'
|
enableImgExport ? 'image' : 'document'
|
||||||
);
|
);
|
||||||
@ -52,7 +49,7 @@ const ExportDialog = ({
|
|||||||
let defaultFormat: ExportFormat;
|
let defaultFormat: ExportFormat;
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 'document':
|
case 'document':
|
||||||
defaultFormat = 'pdf';
|
defaultFormat = 'txt';
|
||||||
break;
|
break;
|
||||||
case 'image':
|
case 'image':
|
||||||
defaultFormat = 'svg';
|
defaultFormat = 'svg';
|
||||||
@ -72,41 +69,75 @@ const ExportDialog = ({
|
|||||||
setSubmit(true);
|
setSubmit(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const exporter = (formatType: ExportFormat) => {
|
||||||
if (submit) {
|
let svgElement: Element | null = null;
|
||||||
// TODO: Remove usage of global "designer"
|
let size;
|
||||||
const designer = global.designer;
|
let mindmap: MindMap;
|
||||||
|
|
||||||
|
const designer: Designer = global.designer;
|
||||||
|
if (designer != null) {
|
||||||
// Depending on the type of export. It will require differt POST.
|
// Depending on the type of export. It will require differt POST.
|
||||||
if (
|
const workspace = designer.getWorkspace();
|
||||||
designer &&
|
svgElement = workspace.getSVGElement();
|
||||||
designer.EXPORT_SUPPORTED_FORMATS.includes(exportFormat)
|
size = workspace.getSize();
|
||||||
) {
|
mindmap = designer.getMindmap();
|
||||||
designer.export(exportFormat)
|
} else {
|
||||||
.then((url: string) => {
|
// Load mindmap ...
|
||||||
// Create hidden anchor to force download ...
|
const persistence = new RESTPersistenceManager({
|
||||||
const anchor: HTMLAnchorElement = document.createElement('a');
|
documentUrl: '/c/restful/maps/{id}/document',
|
||||||
anchor.style.display = 'display: none';
|
revertUrl: '/c/restful/maps/{id}/history/latest',
|
||||||
anchor.download = `${mapId}.${exportFormat}`;
|
lockUrl: '/c/restful/maps/{id}/lock',
|
||||||
anchor.href = url;
|
timestamp: global.lockTimestamp,
|
||||||
document.body.appendChild(anchor);
|
session: global.lockSession,
|
||||||
|
});
|
||||||
|
mindmap = persistence.load(global.mapId)
|
||||||
|
|
||||||
// Trigger click ...
|
}
|
||||||
anchor.click();
|
|
||||||
|
|
||||||
// Clean up ...
|
let exporter: Exporter;
|
||||||
URL.revokeObjectURL(url);
|
switch (formatType) {
|
||||||
document.body.removeChild(anchor);
|
case 'png':
|
||||||
});
|
case 'jpg':
|
||||||
} else if (exportFormat === 'pdf') {
|
case 'svg': {
|
||||||
formTransformtRef?.submit();
|
exporter = ImageExpoterFactory.create(formatType, mindmap, svgElement, size.width, size.height);
|
||||||
} else {
|
break;
|
||||||
formExportRef?.submit();
|
|
||||||
}
|
}
|
||||||
|
case 'wxml':
|
||||||
|
case 'md':
|
||||||
|
case 'txt': {
|
||||||
|
exporter = TextExporterFactory.create(formatType, mindmap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported encoding');
|
||||||
|
}
|
||||||
|
|
||||||
|
return exporter.export();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const { map } = fetchMapById(mapId);
|
||||||
|
if (submit) {
|
||||||
|
exporter(exportFormat)
|
||||||
|
.then((url: string) => {
|
||||||
|
// Create hidden anchor to force download ...
|
||||||
|
const anchor: HTMLAnchorElement = document.createElement('a');
|
||||||
|
anchor.style.display = 'display: none';
|
||||||
|
anchor.download = `${map?.title}.${exportFormat}`;
|
||||||
|
anchor.href = url;
|
||||||
|
document.body.appendChild(anchor);
|
||||||
|
|
||||||
|
// Trigger click ...
|
||||||
|
anchor.click();
|
||||||
|
|
||||||
|
// Clean up ...
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
document.body.removeChild(anchor);
|
||||||
|
});
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
}, [submit]);
|
}, [submit]);
|
||||||
|
|
||||||
const { map } = fetchMapById(mapId);
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<BaseDialog
|
<BaseDialog
|
||||||
@ -151,9 +182,6 @@ const ExportDialog = ({
|
|||||||
<MenuItem value="svg" className={classes.menu}>
|
<MenuItem value="svg" className={classes.menu}>
|
||||||
Scalable Vector Graphics (SVG)
|
Scalable Vector Graphics (SVG)
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value="pdf" className={classes.menu}>
|
|
||||||
Portable Document Format (PDF)
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value="png" className={classes.menu}>
|
<MenuItem value="png" className={classes.menu}>
|
||||||
Portable Network Graphics (PNG)
|
Portable Network Graphics (PNG)
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
@ -189,6 +217,9 @@ const ExportDialog = ({
|
|||||||
<MenuItem className={classes.select} value="txt">
|
<MenuItem className={classes.select} value="txt">
|
||||||
Plain Text File (TXT)
|
Plain Text File (TXT)
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem className={classes.select} value="md">
|
||||||
|
Markdown (MD)
|
||||||
|
</MenuItem>
|
||||||
</Select>
|
</Select>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -227,26 +258,6 @@ const ExportDialog = ({
|
|||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
|
||||||
{/* Hidden form for the purpose of summit */}
|
|
||||||
<form
|
|
||||||
action={`/c/restful/maps/${mapId}.${exportFormat}`}
|
|
||||||
ref={setExportFormRef}
|
|
||||||
method="GET"
|
|
||||||
>
|
|
||||||
<input name="download" type="hidden" value={exportFormat} />
|
|
||||||
<input name="filename" type="hidden" value={map?.title} />
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form
|
|
||||||
action={`/c/restful/transform.${exportFormat}`}
|
|
||||||
ref={setTransformFormRef}
|
|
||||||
method="POST"
|
|
||||||
>
|
|
||||||
<input name="download" type="hidden" value={exportFormat} />
|
|
||||||
<input name="filename" type="hidden" value={map?.title} />
|
|
||||||
<input name="svgXml" id="svgXml" value={svgXml} type="hidden" />
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -3294,6 +3294,18 @@
|
|||||||
jquery "3.6.0"
|
jquery "3.6.0"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
|
|
||||||
|
"@wisemapping/mindplot@^0.4.15":
|
||||||
|
version "0.4.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/@wisemapping/mindplot/-/mindplot-0.4.15.tgz#d4a7aa3a96bd5a91ec7f800eb392be820d97510b"
|
||||||
|
integrity sha512-4buCwA9VezQylHkZ4c7JB+MBqGAOzOnBUZEjeqkg5hZMSt0mobMD3inp+tStJbZtQQbt7p6KJ/04+ewHmGlBag==
|
||||||
|
dependencies:
|
||||||
|
"@types/jquery" "^3.5.11"
|
||||||
|
"@wisemapping/core-js" "^0.4.0"
|
||||||
|
"@wisemapping/web2d" "^0.4.0"
|
||||||
|
jest "^27.4.5"
|
||||||
|
jquery "3.6.0"
|
||||||
|
lodash "^4.17.21"
|
||||||
|
|
||||||
"@xtuc/ieee754@^1.2.0":
|
"@xtuc/ieee754@^1.2.0":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||||
|
Loading…
Reference in New Issue
Block a user