mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-14 03:07:57 +01:00
Improve copy paste support.
This commit is contained in:
parent
57934487f7
commit
e54d4ff543
19
packages/editor/cypress/e2e/copyAndPaste.cy.ts
Normal file
19
packages/editor/cypress/e2e/copyAndPaste.cy.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
describe('Edit Topic', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Remove storage for autosave ...
|
||||||
|
cy.visit('/editor.html');
|
||||||
|
cy.waitEditorLoaded();
|
||||||
|
cy.get('[test-id=2]').click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Copy and Paste', () => {
|
||||||
|
cy.get(`[aria-label="Topic Style"]`).first().trigger('mouseover');
|
||||||
|
cy.get('body').type('{meta}c');
|
||||||
|
|
||||||
|
// Copy & Paste require permissions. More reseach needed.
|
||||||
|
// cy.get('body').type('{meta}v');
|
||||||
|
// cy.get('[test-id=50]').click();
|
||||||
|
// cy.matchImageSnapshot('copyandpaste');
|
||||||
|
});
|
||||||
|
});
|
@ -56,6 +56,7 @@ import FeatureType from './model/FeatureType';
|
|||||||
import WidgetManager from './WidgetManager';
|
import WidgetManager from './WidgetManager';
|
||||||
import { TopicShapeType } from './model/INodeModel';
|
import { TopicShapeType } from './model/INodeModel';
|
||||||
import { LineType } from './ConnectionLine';
|
import { LineType } from './ConnectionLine';
|
||||||
|
import XMLSerializerFactory from './persistence/XMLSerializerFactory';
|
||||||
|
|
||||||
class Designer extends Events {
|
class Designer extends Events {
|
||||||
private _mindmap: Mindmap | null;
|
private _mindmap: Mindmap | null;
|
||||||
@ -74,8 +75,6 @@ class Designer extends Events {
|
|||||||
|
|
||||||
private _relPivot: RelationshipPivot;
|
private _relPivot: RelationshipPivot;
|
||||||
|
|
||||||
private _clipboard: NodeModel[];
|
|
||||||
|
|
||||||
private _cleanScreen!: () => void;
|
private _cleanScreen!: () => void;
|
||||||
|
|
||||||
constructor(options: DesignerOptions, divElement: JQuery) {
|
constructor(options: DesignerOptions, divElement: JQuery) {
|
||||||
@ -129,7 +128,6 @@ class Designer extends Events {
|
|||||||
this._relPivot = new RelationshipPivot(this._workspace, this);
|
this._relPivot = new RelationshipPivot(this._workspace, this);
|
||||||
|
|
||||||
TopicEventDispatcher.configure(this.isReadOnly());
|
TopicEventDispatcher.configure(this.isReadOnly());
|
||||||
this._clipboard = [];
|
|
||||||
|
|
||||||
// Hack: There are static reference to designer variable. Needs to be reviewed.
|
// Hack: There are static reference to designer variable. Needs to be reviewed.
|
||||||
globalThis.designer = this;
|
globalThis.designer = this;
|
||||||
@ -381,44 +379,79 @@ class Designer extends Events {
|
|||||||
|
|
||||||
copyToClipboard(): void {
|
copyToClipboard(): void {
|
||||||
let topics = this.getModel().filterSelectedTopics();
|
let topics = this.getModel().filterSelectedTopics();
|
||||||
if (topics.length <= 0) {
|
if (topics.length > 0) {
|
||||||
// If there are more than one node selected,
|
const mindmap = new Mindmap();
|
||||||
$notify($msg('AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED'));
|
const central: NodeModel = new NodeModel('CentralTopic', mindmap);
|
||||||
return;
|
mindmap.addBranch(central);
|
||||||
|
|
||||||
|
// Exclude central topic ..
|
||||||
|
topics = topics.filter((topic) => !topic.isCentralTopic());
|
||||||
|
topics.forEach((topic) => {
|
||||||
|
const nodeModel: NodeModel = topic.getModel().deepCopy();
|
||||||
|
nodeModel.connectTo(central);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Serialize to mindmap ...
|
||||||
|
const serializer = XMLSerializerFactory.createFromMindmap(mindmap);
|
||||||
|
const document = serializer.toXML(mindmap);
|
||||||
|
const xmmStr: string = new XMLSerializer().serializeToString(document);
|
||||||
|
|
||||||
|
// Convert to node, only text/html is supported...
|
||||||
|
const type = 'text/plain';
|
||||||
|
const blob = new Blob([xmmStr], { type });
|
||||||
|
const clipboard = new ClipboardItem({
|
||||||
|
[blob.type]: blob,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Copy to clipboard ...
|
||||||
|
navigator.clipboard.write([clipboard]).then(
|
||||||
|
() => console.log('Copy of node success'),
|
||||||
|
(e) => console.error(e),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exclude central topic ..
|
|
||||||
topics = topics.filter((topic) => !topic.isCentralTopic());
|
|
||||||
|
|
||||||
this._clipboard = topics.map((topic) => {
|
|
||||||
const nodeModel = topic.getModel().deepCopy();
|
|
||||||
|
|
||||||
// Change position to make the new topic evident...
|
|
||||||
const pos = nodeModel.getPosition();
|
|
||||||
nodeModel.setPosition(pos.x + 60 * Math.sign(pos.x), pos.y + 30);
|
|
||||||
|
|
||||||
return nodeModel;
|
|
||||||
});
|
|
||||||
|
|
||||||
$notify($msg('SELECTION_COPIED_TO_CLIPBOARD'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteClipboard(): void {
|
async pasteClipboard(): Promise<void> {
|
||||||
// If the no selection has been made, update with the text on the clipboard.
|
const type = 'text/plain';
|
||||||
if (this._clipboard.length !== 0) {
|
const clipboardItems = await navigator.clipboard.read();
|
||||||
this._actionDispatcher.addTopics(this._clipboard, null);
|
clipboardItems.forEach(async (item) => {
|
||||||
this._clipboard = [];
|
if (item.types.includes(type)) {
|
||||||
} else {
|
const blob: Blob = await item.getType(type);
|
||||||
const topics = this.getModel().filterSelectedTopics();
|
const text: string = await blob.text();
|
||||||
if (topics.length > 0) {
|
|
||||||
navigator.clipboard.readText().then((text) => {
|
// Is a mindmap ?. Try to infer if it's a text or a map...
|
||||||
|
if (text.indexOf('</map>') !== -1) {
|
||||||
|
const dom = new DOMParser().parseFromString(text, 'application/xml');
|
||||||
|
|
||||||
|
const serializer = XMLSerializerFactory.createFromDocument(dom);
|
||||||
|
const mindmap = serializer.loadFromDom(dom, 'application/xml');
|
||||||
|
|
||||||
|
// Remove reference to the parent mindmap and clean up to support multiple copy of the nodes ...
|
||||||
|
const central = mindmap.getBranches()[0];
|
||||||
|
let children = central.getChildren();
|
||||||
|
children.forEach((c) => c.disconnect());
|
||||||
|
children = children.map((m: NodeModel) => m.deepCopy());
|
||||||
|
|
||||||
|
// Charge position to avoid overlap ...
|
||||||
|
children.forEach((m) => {
|
||||||
|
const pos = m.getPosition();
|
||||||
|
m.setPosition(
|
||||||
|
pos.x * Math.sign(pos.x) + Math.random() * 60,
|
||||||
|
pos.y + Math.random() * 30,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Finally, add the node ...
|
||||||
|
this._actionDispatcher.addTopics(children, null);
|
||||||
|
} else {
|
||||||
|
const topics = this.getModel().filterSelectedTopics();
|
||||||
this._actionDispatcher.changeTextToTopic(
|
this._actionDispatcher.changeTextToTopic(
|
||||||
topics.map((t) => t.getId()),
|
topics.map((t) => t.getId()),
|
||||||
text.trim(),
|
text.trim(),
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getModel(): DesignerModel {
|
getModel(): DesignerModel {
|
||||||
|
@ -173,8 +173,9 @@ class MindplotWebComponent extends HTMLElement {
|
|||||||
const persistenceManager = PersistenceManager.getInstance();
|
const persistenceManager = PersistenceManager.getInstance();
|
||||||
|
|
||||||
// If the map could not be loaded, partial map load could happen.
|
// If the map could not be loaded, partial map load could happen.
|
||||||
if (mindmap) {
|
const mapId = mindmap.getId();
|
||||||
persistenceManager.unlockMap(mindmap.getId());
|
if (mindmap && mapId) {
|
||||||
|
persistenceManager.unlockMap(mapId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,10 +38,10 @@ abstract class PersistenceManager {
|
|||||||
$assert(mindmap, 'mindmap can not be null');
|
$assert(mindmap, 'mindmap can not be null');
|
||||||
$assert(editorProperties, 'editorProperties can not be null');
|
$assert(editorProperties, 'editorProperties can not be null');
|
||||||
|
|
||||||
const mapId = mindmap.getId();
|
const mapId = mindmap.getId() || 'WiseMapping';
|
||||||
$assert(mapId, 'mapId can not be null');
|
$assert(mapId, 'mapId can not be null');
|
||||||
|
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromMindmap(mindmap);
|
const serializer = XMLSerializerFactory.createFromMindmap(mindmap);
|
||||||
const domMap = serializer.toXML(mindmap);
|
const domMap = serializer.toXML(mindmap);
|
||||||
const pref = JSON.stringify(editorProperties);
|
const pref = JSON.stringify(editorProperties);
|
||||||
try {
|
try {
|
||||||
@ -106,7 +106,7 @@ abstract class PersistenceManager {
|
|||||||
$assert(mapId, 'mapId can not be null');
|
$assert(mapId, 'mapId can not be null');
|
||||||
$assert(mapDom, 'mapDom can not be null');
|
$assert(mapDom, 'mapDom can not be null');
|
||||||
|
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromDocument(mapDom);
|
const serializer = XMLSerializerFactory.createFromDocument(mapDom);
|
||||||
return serializer.loadFromDom(mapDom, mapId);
|
return serializer.loadFromDom(mapDom, mapId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class RESTPersistenceManager extends PersistenceManager {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
events.onSuccess();
|
events.onSuccess();
|
||||||
} else {
|
} else {
|
||||||
console.log(`Saving error: ${response.status}`);
|
console.error(`Saving error: ${response.status}`);
|
||||||
let userMsg: PersistenceError | null = null;
|
let userMsg: PersistenceError | null = null;
|
||||||
if (response.status === 405) {
|
if (response.status === 405) {
|
||||||
userMsg = {
|
userMsg = {
|
||||||
|
@ -30,7 +30,6 @@ class AddTopicCommand extends Command {
|
|||||||
* the mindmap.
|
* the mindmap.
|
||||||
*/
|
*/
|
||||||
constructor(models: NodeModel[], parentTopicsId: number[] | null) {
|
constructor(models: NodeModel[], parentTopicsId: number[] | null) {
|
||||||
$assert(models, 'models can not be null');
|
|
||||||
$assert(
|
$assert(
|
||||||
parentTopicsId == null || parentTopicsId.length === models.length,
|
parentTopicsId == null || parentTopicsId.length === models.length,
|
||||||
'parents and models must have the same size',
|
'parents and models must have the same size',
|
||||||
|
@ -29,7 +29,7 @@ class WiseXMLExporter extends Exporter {
|
|||||||
|
|
||||||
export(): Promise<string> {
|
export(): Promise<string> {
|
||||||
const { mindmap } = this;
|
const { mindmap } = this;
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromMindmap(mindmap);
|
const serializer = XMLSerializerFactory.createFromMindmap(mindmap);
|
||||||
const document: Document = serializer.toXML(mindmap);
|
const document: Document = serializer.toXML(mindmap);
|
||||||
|
|
||||||
const xmlStr: string = new XMLSerializer().serializeToString(document);
|
const xmlStr: string = new XMLSerializer().serializeToString(document);
|
||||||
|
@ -77,7 +77,7 @@ export default class FreemindImporter extends Importer {
|
|||||||
this.mindmap.setDescription(description);
|
this.mindmap.setDescription(description);
|
||||||
this.mindmap.addBranch(wiseTopic);
|
this.mindmap.addBranch(wiseTopic);
|
||||||
|
|
||||||
const serialize = XMLSerializerFactory.createInstanceFromMindmap(this.mindmap);
|
const serialize = XMLSerializerFactory.createFromMindmap(this.mindmap);
|
||||||
const domMindmap = serialize.toXML(this.mindmap);
|
const domMindmap = serialize.toXML(this.mindmap);
|
||||||
const xmlToString = new XMLSerializer().serializeToString(domMindmap);
|
const xmlToString = new XMLSerializer().serializeToString(domMindmap);
|
||||||
const formatXml = xmlFormatter(xmlToString, {
|
const formatXml = xmlFormatter(xmlToString, {
|
||||||
|
@ -13,7 +13,7 @@ export default class WisemappingImporter extends Importer {
|
|||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const wiseDoc = parser.parseFromString(this.wisemappingInput, 'application/xml');
|
const wiseDoc = parser.parseFromString(this.wisemappingInput, 'application/xml');
|
||||||
|
|
||||||
const serialize = XMLSerializerFactory.createInstanceFromDocument(wiseDoc);
|
const serialize = XMLSerializerFactory.createFromDocument(wiseDoc);
|
||||||
const mindmap = serialize.loadFromDom(wiseDoc, nameMap);
|
const mindmap = serialize.loadFromDom(wiseDoc, nameMap);
|
||||||
|
|
||||||
mindmap.setDescription(description);
|
mindmap.setDescription(description);
|
||||||
|
@ -13,11 +13,9 @@ const DE = {
|
|||||||
SUB_TOPIC: 'Unterthema',
|
SUB_TOPIC: 'Unterthema',
|
||||||
ISOLATED_TOPIC: 'Isoliertes Thema',
|
ISOLATED_TOPIC: 'Isoliertes Thema',
|
||||||
CENTRAL_TOPIC: 'Zentrales Thema',
|
CENTRAL_TOPIC: 'Zentrales Thema',
|
||||||
AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED: 'Es muss mindestens ein Thema ausgewählt sein.',
|
|
||||||
CLIPBOARD_IS_EMPTY: 'Es gibt nichts zu kopieren. Die Zwischenablage ist leer.',
|
CLIPBOARD_IS_EMPTY: 'Es gibt nichts zu kopieren. Die Zwischenablage ist leer.',
|
||||||
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Das zentrale Thema kann nicht gelöscht werden.',
|
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Das zentrale Thema kann nicht gelöscht werden.',
|
||||||
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Die Beziehung konnte nicht angelegt werden. Es muss erst ein Vater-Thema ausgewählt werden, um die Beziehung herzustellen.',
|
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Die Beziehung konnte nicht angelegt werden. Es muss erst ein Vater-Thema ausgewählt werden, um die Beziehung herzustellen.',
|
||||||
SELECTION_COPIED_TO_CLIPBOARD: 'Themen in der Zwischenablage',
|
|
||||||
SESSION_EXPIRED: 'Deine Sitzung ist abgelaufen, bitte melde dich erneut an.',
|
SESSION_EXPIRED: 'Deine Sitzung ist abgelaufen, bitte melde dich erneut an.',
|
||||||
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'Le style de connexion ne peut pas être modifié pour le sujet central.',
|
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'Le style de connexion ne peut pas être modifié pour le sujet central.',
|
||||||
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Le sujet central ne peut pas être changé en style de ligne.',
|
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Le sujet central ne peut pas être changé en style de ligne.',
|
||||||
|
@ -13,11 +13,9 @@ const EN = {
|
|||||||
ISOLATED_TOPIC: 'Isolated Topic',
|
ISOLATED_TOPIC: 'Isolated Topic',
|
||||||
CENTRAL_TOPIC: 'Central Topic',
|
CENTRAL_TOPIC: 'Central Topic',
|
||||||
ENTITIES_COULD_NOT_BE_DELETED: 'Could not delete topic or relation. At least one map entity must be selected.',
|
ENTITIES_COULD_NOT_BE_DELETED: 'Could not delete topic or relation. At least one map entity must be selected.',
|
||||||
AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED: 'At least one topic must be selected.',
|
|
||||||
CLIPBOARD_IS_EMPTY: 'Nothing to copy. Clipboard is empty.',
|
CLIPBOARD_IS_EMPTY: 'Nothing to copy. Clipboard is empty.',
|
||||||
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Central topic can not be deleted.',
|
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Central topic can not be deleted.',
|
||||||
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Relationship could not be created. A parent relationship topic must be selected first.',
|
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Relationship could not be created. A parent relationship topic must be selected first.',
|
||||||
SELECTION_COPIED_TO_CLIPBOARD: 'Topics copied to the clipboard',
|
|
||||||
SESSION_EXPIRED: 'Your session has expired, please log-in again.',
|
SESSION_EXPIRED: 'Your session has expired, please log-in again.',
|
||||||
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'Connection style can not be changed for central topic.',
|
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'Connection style can not be changed for central topic.',
|
||||||
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Central topic can not be changed to line style.',
|
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Central topic can not be changed to line style.',
|
||||||
|
@ -13,11 +13,9 @@ const ES = {
|
|||||||
ISOLATED_TOPIC: 'Tópico Aislado',
|
ISOLATED_TOPIC: 'Tópico Aislado',
|
||||||
CENTRAL_TOPIC: 'Tópico Central',
|
CENTRAL_TOPIC: 'Tópico Central',
|
||||||
ENTITIES_COULD_NOT_BE_DELETED: 'El tópico o la relación no pudo ser borrada. Debe selecionar al menos una.',
|
ENTITIES_COULD_NOT_BE_DELETED: 'El tópico o la relación no pudo ser borrada. Debe selecionar al menos una.',
|
||||||
AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED: 'Al menos un tópico debe ser seleccionado.',
|
|
||||||
CLIPBOARD_IS_EMPTY: 'Nada que copiar. Clipboard está vacio.',
|
CLIPBOARD_IS_EMPTY: 'Nada que copiar. Clipboard está vacio.',
|
||||||
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'El tópico central no puede ser borrado.',
|
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'El tópico central no puede ser borrado.',
|
||||||
RELATIONSHIP_COULD_NOT_BE_CREATED: 'La relación no pudo ser creada. Una relación padre debe ser seleccionada primero.',
|
RELATIONSHIP_COULD_NOT_BE_CREATED: 'La relación no pudo ser creada. Una relación padre debe ser seleccionada primero.',
|
||||||
SELECTION_COPIED_TO_CLIPBOARD: 'Tópicos copiados al clipboard',
|
|
||||||
SESSION_EXPIRED: 'Su session ha expirado. Por favor, ingrese nuevamente.',
|
SESSION_EXPIRED: 'Su session ha expirado. Por favor, ingrese nuevamente.',
|
||||||
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'El estilo de conexión no se puede cambiar para el tópico central.',
|
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'El estilo de conexión no se puede cambiar para el tópico central.',
|
||||||
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Tópico central no se puede cambiar al estilo de línea.',
|
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Tópico central no se puede cambiar al estilo de línea.',
|
||||||
|
@ -13,11 +13,9 @@ const FR = {
|
|||||||
ISOLATED_TOPIC: 'Noeud isolé',
|
ISOLATED_TOPIC: 'Noeud isolé',
|
||||||
CENTRAL_TOPIC: 'Noeud racine',
|
CENTRAL_TOPIC: 'Noeud racine',
|
||||||
ENTITIES_COULD_NOT_BE_DELETED: "Impossible d'effacer un noeud ou une relation. Au moins un objet de la carte doit être sélectionné.",
|
ENTITIES_COULD_NOT_BE_DELETED: "Impossible d'effacer un noeud ou une relation. Au moins un objet de la carte doit être sélectionné.",
|
||||||
AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED: 'Au moins un objet de la carte doit être sélectionné.',
|
|
||||||
CLIPBOARD_IS_EMPTY: 'Rien à copier. Presse-papier vide.',
|
CLIPBOARD_IS_EMPTY: 'Rien à copier. Presse-papier vide.',
|
||||||
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Le noeud racine ne peut pas être effacé.',
|
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Le noeud racine ne peut pas être effacé.',
|
||||||
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Impossible de créer relation. Un noeud parent doit être sélectionné au préalable.',
|
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Impossible de créer relation. Un noeud parent doit être sélectionné au préalable.',
|
||||||
SELECTION_COPIED_TO_CLIPBOARD: 'Noeuds sélectionnés copiés dans le presse-papiers.',
|
|
||||||
SESSION_EXPIRED: 'Votre session a expiré, veuillez vous reconnecter.',
|
SESSION_EXPIRED: 'Votre session a expiré, veuillez vous reconnecter.',
|
||||||
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'Le style de connexion ne peut pas être modifié pour le sujet central.',
|
CENTRAL_TOPIC_CONNECTION_STYLE_CAN_NOT_BE_CHANGED: 'Le style de connexion ne peut pas être modifié pour le sujet central.',
|
||||||
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Le sujet central ne peut pas être changé en style de ligne.',
|
CENTRAL_TOPIC_STYLE_CAN_NOT_BE_CHANGED: 'Le sujet central ne peut pas être changé en style de ligne.',
|
||||||
|
@ -14,11 +14,9 @@ const RU = {
|
|||||||
ISOLATED_TOPIC: 'Isolated Topic',
|
ISOLATED_TOPIC: 'Isolated Topic',
|
||||||
CENTRAL_TOPIC: 'Central Topic',
|
CENTRAL_TOPIC: 'Central Topic',
|
||||||
ENTITIES_COULD_NOT_BE_DELETED: 'Could not delete topic or relation. At least one map entity must be selected.',
|
ENTITIES_COULD_NOT_BE_DELETED: 'Could not delete topic or relation. At least one map entity must be selected.',
|
||||||
AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED: 'At least one topic must be selected.',
|
|
||||||
CLIPBOARD_IS_EMPTY: 'Nothing to copy. Clipboard is empty.',
|
CLIPBOARD_IS_EMPTY: 'Nothing to copy. Clipboard is empty.',
|
||||||
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Central topic can not be deleted.',
|
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: 'Central topic can not be deleted.',
|
||||||
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Relationship could not be created. A parent relationship topic must be selected first.',
|
RELATIONSHIP_COULD_NOT_BE_CREATED: 'Relationship could not be created. A parent relationship topic must be selected first.',
|
||||||
SELECTION_COPIED_TO_CLIPBOARD: 'Topics copied to the clipboard',
|
|
||||||
SESSION_EXPIRED: 'Your session has expired, please log-in again.',
|
SESSION_EXPIRED: 'Your session has expired, please log-in again.',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,11 +14,9 @@ const ZH = {
|
|||||||
ISOLATED_TOPIC: '独立主题',
|
ISOLATED_TOPIC: '独立主题',
|
||||||
CENTRAL_TOPIC: '中心主题',
|
CENTRAL_TOPIC: '中心主题',
|
||||||
ENTITIES_COULD_NOT_BE_DELETED: '无法删除主题或关系。至少选择一个脑图实体。',
|
ENTITIES_COULD_NOT_BE_DELETED: '无法删除主题或关系。至少选择一个脑图实体。',
|
||||||
AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED: '至少要选择一个主题',
|
|
||||||
CLIPBOARD_IS_EMPTY: '没有东西可以复制。剪贴板是空的。',
|
CLIPBOARD_IS_EMPTY: '没有东西可以复制。剪贴板是空的。',
|
||||||
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: '无法删除中心主题。',
|
CENTRAL_TOPIC_CAN_NOT_BE_DELETED: '无法删除中心主题。',
|
||||||
RELATIONSHIP_COULD_NOT_BE_CREATED: '无法创建关系。必须先选择要建立关系的主题。',
|
RELATIONSHIP_COULD_NOT_BE_CREATED: '无法创建关系。必须先选择要建立关系的主题。',
|
||||||
SELECTION_COPIED_TO_CLIPBOARD: '主题已复制到剪贴板',
|
|
||||||
SESSION_EXPIRED: '您的会话已过期,请重新登录。',
|
SESSION_EXPIRED: '您的会话已过期,请重新登录。',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import INodeModel, { NodeModelType as NodeType } from './INodeModel';
|
import INodeModel, { NodeModelType as NodeType } from './INodeModel';
|
||||||
|
import NodeModel from './NodeModel';
|
||||||
import RelationshipModel from './RelationshipModel';
|
import RelationshipModel from './RelationshipModel';
|
||||||
|
|
||||||
abstract class IMindmap {
|
abstract class IMindmap {
|
||||||
@ -30,7 +31,7 @@ abstract class IMindmap {
|
|||||||
|
|
||||||
abstract setDescription(value: string): void;
|
abstract setDescription(value: string): void;
|
||||||
|
|
||||||
abstract getId(): string;
|
abstract getId(): string | undefined;
|
||||||
|
|
||||||
abstract setId(id: string): void;
|
abstract setId(id: string): void;
|
||||||
|
|
||||||
@ -38,11 +39,11 @@ abstract class IMindmap {
|
|||||||
|
|
||||||
abstract setVersion(version: string): void;
|
abstract setVersion(version: string): void;
|
||||||
|
|
||||||
abstract addBranch(nodeModel): void;
|
abstract addBranch(nodeModel: INodeModel): void;
|
||||||
|
|
||||||
abstract getBranches();
|
abstract getBranches(): NodeModel[];
|
||||||
|
|
||||||
abstract removeBranch(node): void;
|
abstract removeBranch(node: INodeModel): void;
|
||||||
|
|
||||||
abstract getRelationships(): RelationshipModel[];
|
abstract getRelationships(): RelationshipModel[];
|
||||||
|
|
||||||
|
@ -27,16 +27,14 @@ class Mindmap extends IMindmap {
|
|||||||
|
|
||||||
private _version: string;
|
private _version: string;
|
||||||
|
|
||||||
private _id: string;
|
private _id: string | undefined;
|
||||||
|
|
||||||
private _branches: Array<NodeModel>;
|
private _branches: Array<NodeModel>;
|
||||||
|
|
||||||
private _relationships: Array<RelationshipModel>;
|
private _relationships: Array<RelationshipModel>;
|
||||||
|
|
||||||
constructor(id: string, version: string = ModelCodeName.TANGO) {
|
constructor(id?: string, version: string = ModelCodeName.TANGO) {
|
||||||
super();
|
super();
|
||||||
$assert(id, 'Id can not be null');
|
|
||||||
|
|
||||||
this._branches = [];
|
this._branches = [];
|
||||||
this._description = '';
|
this._description = '';
|
||||||
this._relationships = [];
|
this._relationships = [];
|
||||||
@ -54,8 +52,7 @@ class Mindmap extends IMindmap {
|
|||||||
this._description = value;
|
this._description = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
getId(): string | undefined {
|
||||||
getId(): string {
|
|
||||||
return this._id;
|
return this._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class XMLSerializerFactory {
|
|||||||
* @return {mindplot.persistence.XMLSerializer_Beta|mindplot.persistence.XMLSerializer_Pela|
|
* @return {mindplot.persistence.XMLSerializer_Beta|mindplot.persistence.XMLSerializer_Pela|
|
||||||
* mindplot.persistence.XMLSerializer_Tango} serializer corresponding to the mindmap's version
|
* mindplot.persistence.XMLSerializer_Tango} serializer corresponding to the mindmap's version
|
||||||
*/
|
*/
|
||||||
static createInstanceFromMindmap(mindmap: Mindmap) {
|
static createFromMindmap(mindmap: Mindmap): XMLMindmapSerializer {
|
||||||
return XMLSerializerFactory.getSerializer(mindmap.getVersion());
|
return XMLSerializerFactory.getSerializer(mindmap.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ class XMLSerializerFactory {
|
|||||||
* @param domDocument
|
* @param domDocument
|
||||||
* @return serializer corresponding to the mindmap's version
|
* @return serializer corresponding to the mindmap's version
|
||||||
*/
|
*/
|
||||||
static createInstanceFromDocument(domDocument: Document) {
|
static createFromDocument(domDocument: Document): XMLMindmapSerializer {
|
||||||
const rootElem = domDocument.documentElement;
|
const rootElem = domDocument.documentElement;
|
||||||
|
|
||||||
// Legacy version don't have version defined.
|
// Legacy version don't have version defined.
|
||||||
@ -71,8 +71,6 @@ class XMLSerializerFactory {
|
|||||||
* retrieves the serializer for the mindmap's version and migrates to the current version,
|
* retrieves the serializer for the mindmap's version and migrates to the current version,
|
||||||
* e.g. for a Beta mindmap and current version Tango:
|
* e.g. for a Beta mindmap and current version Tango:
|
||||||
* serializer = new Pela2TangoMigrator(new Beta2PelaMigrator(new XMLSerializer_Beta()))
|
* serializer = new Pela2TangoMigrator(new Beta2PelaMigrator(new XMLSerializer_Beta()))
|
||||||
* @param {String} version the version name
|
|
||||||
* @return serializer
|
|
||||||
*/
|
*/
|
||||||
static getSerializer(version = ModelCodeName.TANGO): XMLMindmapSerializer {
|
static getSerializer(version = ModelCodeName.TANGO): XMLMindmapSerializer {
|
||||||
let found = false;
|
let found = false;
|
||||||
|
@ -45,7 +45,7 @@ class XMLSerializerTango implements XMLMindmapSerializer {
|
|||||||
// Store map attributes ...
|
// Store map attributes ...
|
||||||
const mapElem = document.createElement('map');
|
const mapElem = document.createElement('map');
|
||||||
const name = mindmap.getId();
|
const name = mindmap.getId();
|
||||||
if ($defined(name)) {
|
if (name) {
|
||||||
mapElem.setAttribute('name', this._rmXmlInv(name));
|
mapElem.setAttribute('name', this._rmXmlInv(name));
|
||||||
}
|
}
|
||||||
const version = mindmap.getVersion();
|
const version = mindmap.getVersion();
|
||||||
|
@ -20,7 +20,7 @@ describe('WXML export test execution', () => {
|
|||||||
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
||||||
|
|
||||||
// Convert to mindmap ...
|
// Convert to mindmap ...
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromDocument(mapDocument);
|
const serializer = XMLSerializerFactory.createFromDocument(mapDocument);
|
||||||
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
||||||
|
|
||||||
const exporter = TextExporterFactory.create('wxml', mindmap);
|
const exporter = TextExporterFactory.create('wxml', mindmap);
|
||||||
@ -35,7 +35,7 @@ describe('Txt export test execution', () => {
|
|||||||
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
||||||
|
|
||||||
// Convert to mindmap ...
|
// Convert to mindmap ...
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromDocument(mapDocument);
|
const serializer = XMLSerializerFactory.createFromDocument(mapDocument);
|
||||||
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
||||||
|
|
||||||
const exporter = TextExporterFactory.create('txt', mindmap);
|
const exporter = TextExporterFactory.create('txt', mindmap);
|
||||||
@ -50,7 +50,7 @@ describe('MD export test execution', () => {
|
|||||||
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
||||||
|
|
||||||
// Convert to mindmap ...
|
// Convert to mindmap ...
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromDocument(mapDocument);
|
const serializer = XMLSerializerFactory.createFromDocument(mapDocument);
|
||||||
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
||||||
|
|
||||||
const exporter = TextExporterFactory.create('md', mindmap);
|
const exporter = TextExporterFactory.create('md', mindmap);
|
||||||
@ -65,7 +65,7 @@ describe('MM export test execution', () => {
|
|||||||
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
||||||
|
|
||||||
// Convert to mindmap...
|
// Convert to mindmap...
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromDocument(mapDocument);
|
const serializer = XMLSerializerFactory.createFromDocument(mapDocument);
|
||||||
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
const mindmap: Mindmap = serializer.loadFromDom(mapDocument, testName);
|
||||||
|
|
||||||
const exporter = TextExporterFactory.create('mm', mindmap);
|
const exporter = TextExporterFactory.create('mm', mindmap);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('Editor Page', () => {
|
describe('Editor Page', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/c/maps/11/edit');
|
cy.visit('/c/maps/11/edit');
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('Forgot Password Page', () => {
|
describe('Forgot Password Page', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/c/forgot-password');
|
cy.visit('/c/forgot-password');
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('Login Page', () => {
|
describe('Login Page', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/c/login');
|
cy.visit('/c/login');
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('Maps Page', () => {
|
describe('Maps Page', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/c/maps');
|
cy.visit('/c/maps');
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('Registration Page', () => {
|
describe('Registration Page', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/c/registration');
|
cy.visit('/c/registration');
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions" : [
|
"permissions" : [
|
||||||
"http://*/*",
|
|
||||||
"https://*/*",
|
"https://*/*",
|
||||||
"clipboardRead",
|
"clipboardRead",
|
||||||
"clipboardWrite",
|
"clipboardWrite",
|
||||||
|
Loading…
Reference in New Issue
Block a user