mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-21 22:27:56 +01:00
WIP
This commit is contained in:
parent
bccd26aad6
commit
506797b8a7
@ -48,7 +48,12 @@ abstract class ActionDispatcher extends Events {
|
||||
|
||||
abstract deleteEntities(topicsIds: number[], relIds: number[]): void;
|
||||
|
||||
abstract dragTopic(topicId: number, position: Point, order: number, parentTopic: Topic): void;
|
||||
abstract dragTopic(
|
||||
topicId: number,
|
||||
position: Point,
|
||||
order: number | null,
|
||||
parentTopic: Topic | null,
|
||||
): void;
|
||||
|
||||
abstract moveTopic(topicId: number, position: Point): void;
|
||||
|
||||
|
@ -53,7 +53,6 @@ class CentralTopic extends Topic {
|
||||
this.setPosition(zeroPoint);
|
||||
}
|
||||
|
||||
/** */
|
||||
getShrinkConnector() {
|
||||
return null;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class Designer extends Events {
|
||||
|
||||
// Set up i18n location ...
|
||||
console.log(`Editor location: ${options.locale}`);
|
||||
Messages.init(options.locale);
|
||||
Messages.init(options.locale ? options.locale : 'en');
|
||||
|
||||
this._options = options;
|
||||
|
||||
@ -263,7 +263,10 @@ class Designer extends Events {
|
||||
} else {
|
||||
$assert(targetTopic, 'Could not find a topic to connect');
|
||||
}
|
||||
topic.connectTo(targetTopic, this._workspace);
|
||||
|
||||
if (targetTopic) {
|
||||
topic.connectTo(targetTopic, this._workspace);
|
||||
}
|
||||
}
|
||||
|
||||
topic.addEvent('ontblur', () => {
|
||||
@ -521,7 +524,7 @@ class Designer extends Events {
|
||||
const parentTopic = topic.getOutgoingConnectedTopic();
|
||||
const siblingModel = this._createSiblingModel(topic);
|
||||
|
||||
if (siblingModel) {
|
||||
if (siblingModel && parentTopic) {
|
||||
// Hack: if parent is central topic, add node below not on opposite side.
|
||||
// This should be done in the layout
|
||||
if (parentTopic.getType() === 'CentralTopic') {
|
||||
@ -724,7 +727,7 @@ class Designer extends Events {
|
||||
);
|
||||
|
||||
// Build relationship line ....
|
||||
const result = new Relationship(sourceTopic, targetTopic, model);
|
||||
const result = new Relationship(sourceTopic!, targetTopic!, model);
|
||||
const me = this;
|
||||
|
||||
result.addEvent('ontblur', () => {
|
||||
|
@ -37,8 +37,7 @@ export function buildDesigner(options: DesignerOptions): Designer {
|
||||
|
||||
// Configure default persistence manager ...
|
||||
const persistence = options.persistenceManager;
|
||||
$assert(persistence, 'persistence must be defined');
|
||||
PersistenceManager.init(persistence);
|
||||
PersistenceManager.init(persistence!);
|
||||
|
||||
// If not manager was specifed, use the readonly one.
|
||||
const widgetManager = options.widgetManager ? options.widgetManager : new ReadOnlyWidgetManager();
|
||||
|
@ -24,7 +24,7 @@ export type DesignerOptions = {
|
||||
zoom: number;
|
||||
mode: EditorRenderMode;
|
||||
mapId?: string;
|
||||
divContainer?: HTMLElement;
|
||||
divContainer: HTMLElement;
|
||||
container: string;
|
||||
persistenceManager?: PersistenceManager;
|
||||
widgetManager?: WidgetManager;
|
||||
@ -36,7 +36,7 @@ class OptionsBuilder {
|
||||
static buildOptions(options: DesignerOptions): DesignerOptions {
|
||||
$assert(options.persistenceManager, 'persistence must be defined');
|
||||
|
||||
const defaultOptions: DesignerOptions = {
|
||||
const defaultOptions = {
|
||||
mode: 'edition-owner',
|
||||
zoom: 0.85,
|
||||
saveOnLoad: true,
|
||||
|
@ -108,8 +108,6 @@ class DragTopic {
|
||||
}
|
||||
|
||||
connectTo(parent: Topic) {
|
||||
$assert(parent, 'Parent connection node can not be null.');
|
||||
|
||||
// Where it should be connected ?
|
||||
const predict = this._layoutManager.predict(
|
||||
parent.getId(),
|
||||
@ -178,8 +176,8 @@ class DragTopic {
|
||||
const position = this.getPosition();
|
||||
|
||||
if (!this.isFreeLayoutOn()) {
|
||||
let order = null;
|
||||
let parent = null;
|
||||
let order: number | null = null;
|
||||
let parent: Topic | null = null;
|
||||
const isDragConnected = this.isConnected();
|
||||
if (isDragConnected) {
|
||||
const targetTopic = this.getConnectedToTopic();
|
||||
|
@ -23,9 +23,9 @@ import ActionDispatcher from './ActionDispatcher';
|
||||
import Topic from './Topic';
|
||||
|
||||
class MultilineTextEditor extends Events {
|
||||
private _topic: Topic;
|
||||
private _topic: Topic | null;
|
||||
|
||||
private _containerElem: JQuery;
|
||||
private _containerElem: JQuery<HTMLElement> | null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -54,7 +54,7 @@ class MultilineTextEditor extends Events {
|
||||
|
||||
private _registerEvents(containerElem: JQuery) {
|
||||
const textareaElem = this._getTextareaElem();
|
||||
textareaElem.on('keydown', (event) => {
|
||||
textareaElem?.on('keydown', (event) => {
|
||||
switch (event.code) {
|
||||
case 'Escape':
|
||||
this.close(false);
|
||||
@ -85,12 +85,12 @@ class MultilineTextEditor extends Events {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
textareaElem.on('keypress', (event) => {
|
||||
textareaElem?.on('keypress', (event) => {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
textareaElem.on('keyup', (event) => {
|
||||
const text = this._getTextareaElem().val();
|
||||
textareaElem?.on('keyup', (event) => {
|
||||
const text = this._getTextareaElem()?.val();
|
||||
this.fireEvent('input', [event, text]);
|
||||
this._adjustEditorSize();
|
||||
});
|
||||
@ -117,22 +117,22 @@ class MultilineTextEditor extends Events {
|
||||
maxLineLength = Math.max(line.length, maxLineLength);
|
||||
});
|
||||
|
||||
textElem.attr('cols', maxLineLength);
|
||||
textElem.attr('rows', lines.length);
|
||||
textElem?.attr('cols', maxLineLength);
|
||||
textElem?.attr('rows', lines.length);
|
||||
|
||||
this._containerElem.css({
|
||||
this._containerElem?.css({
|
||||
width: `${maxLineLength + 2}em`,
|
||||
height: textElem.height(),
|
||||
height: textElem?.height() || 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isVisible(): boolean {
|
||||
return $defined(this._containerElem) && this._containerElem.css('display') === 'block';
|
||||
return this._containerElem !== null && this._containerElem.css('display') === 'block';
|
||||
}
|
||||
|
||||
private _updateModel() {
|
||||
if (this._topic.getText() !== this._getTextAreaText()) {
|
||||
if (this._topic && this._topic.getText() !== this._getTextAreaText()) {
|
||||
const text = this._getTextAreaText();
|
||||
const topicId = this._topic.getId();
|
||||
|
||||
@ -167,36 +167,39 @@ class MultilineTextEditor extends Events {
|
||||
|
||||
private _showEditor(defaultText: string) {
|
||||
const topic = this._topic;
|
||||
if (topic && this._containerElem) {
|
||||
// Hide topic text ...
|
||||
topic.getTextShape().setVisibility(false);
|
||||
|
||||
// Hide topic text ...
|
||||
topic.getTextShape().setVisibility(false);
|
||||
// Set Editor Style
|
||||
const nodeText = topic.getTextShape();
|
||||
const fontStyle = nodeText.getFontStyle();
|
||||
fontStyle.size = nodeText.getHtmlFontSize();
|
||||
fontStyle.color = nodeText.getColor();
|
||||
this._setStyle(fontStyle);
|
||||
|
||||
// Set Editor Style
|
||||
const nodeText = topic.getTextShape();
|
||||
const fontStyle = nodeText.getFontStyle();
|
||||
fontStyle.size = nodeText.getHtmlFontSize();
|
||||
fontStyle.color = nodeText.getColor();
|
||||
this._setStyle(fontStyle);
|
||||
// Set editor's initial size
|
||||
// Position the editor and set the size...
|
||||
const textShape = topic.getTextShape();
|
||||
|
||||
// Set editor's initial size
|
||||
// Position the editor and set the size...
|
||||
const textShape = topic.getTextShape();
|
||||
this._containerElem.css('display', 'block');
|
||||
|
||||
this._containerElem.css('display', 'block');
|
||||
let { top, left } = textShape.getNativePosition();
|
||||
// Adjust padding top position ...
|
||||
top -= 4;
|
||||
left -= 4;
|
||||
this._containerElem.offset({ top, left });
|
||||
|
||||
let { top, left } = textShape.getNativePosition();
|
||||
// Adjust padding top position ...
|
||||
top -= 4;
|
||||
left -= 4;
|
||||
this._containerElem.offset({ top, left });
|
||||
// Set editor's initial text ...
|
||||
const text = $defined(defaultText) ? defaultText : topic.getText();
|
||||
this._setText(text);
|
||||
|
||||
// Set editor's initial text ...
|
||||
const text = $defined(defaultText) ? defaultText : topic.getText();
|
||||
this._setText(text);
|
||||
|
||||
// Set the element focus and select the current text ...
|
||||
const inputElem = this._getTextareaElem();
|
||||
this._positionCursor(inputElem, !$defined(defaultText));
|
||||
// Set the element focus and select the current text ...
|
||||
const inputElem = this._getTextareaElem();
|
||||
if (inputElem) {
|
||||
this._positionCursor(inputElem, !$defined(defaultText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _setStyle(fontStyle) {
|
||||
@ -223,22 +226,22 @@ class MultilineTextEditor extends Events {
|
||||
fontWeight: fontStyle.weight,
|
||||
color: fontStyle.color,
|
||||
};
|
||||
inputField.css(style);
|
||||
this._containerElem.css(style);
|
||||
inputField?.css(style);
|
||||
this._containerElem?.css(style);
|
||||
}
|
||||
|
||||
private _setText(text: string): void {
|
||||
const textareaElem = this._getTextareaElem();
|
||||
textareaElem.val(text);
|
||||
textareaElem?.val(text);
|
||||
this._adjustEditorSize();
|
||||
}
|
||||
|
||||
private _getTextAreaText(): string {
|
||||
return this._getTextareaElem().val() as string;
|
||||
return this._getTextareaElem()?.val() as string;
|
||||
}
|
||||
|
||||
private _getTextareaElem(): JQuery<HTMLTextAreaElement> {
|
||||
return this._containerElem.find('textarea');
|
||||
private _getTextareaElem(): JQuery<HTMLTextAreaElement> | null {
|
||||
return this._containerElem ? this._containerElem.find('textarea') : null;
|
||||
}
|
||||
|
||||
private _positionCursor(textareaElem: JQuery<HTMLTextAreaElement>, selectText: boolean) {
|
||||
@ -259,7 +262,7 @@ class MultilineTextEditor extends Events {
|
||||
}
|
||||
|
||||
// Remove it form the screen ...
|
||||
this._containerElem.remove();
|
||||
this._containerElem?.remove();
|
||||
this._containerElem = null;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ abstract class PersistenceManager {
|
||||
|
||||
protected getCSRFToken(): string | null {
|
||||
const meta = document.head.querySelector('meta[name="_csrf"]');
|
||||
let result = null;
|
||||
let result: string | null = null;
|
||||
if (meta) {
|
||||
result = meta.getAttribute('content');
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class ScreenManager {
|
||||
}
|
||||
}
|
||||
|
||||
fireEvent(type: string, event: UIEvent = null) {
|
||||
fireEvent(type: string, event?: UIEvent): void {
|
||||
if (type === 'click') {
|
||||
this._clickEvents.forEach((listener) => {
|
||||
listener(type, event);
|
||||
|
@ -15,7 +15,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import { $assert, $defined } from '@wisemapping/core-js';
|
||||
|
||||
import { Rect, Image, Line, Text, Group, ElementClass, Point } from '@wisemapping/web2d';
|
||||
@ -147,7 +146,7 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
// Move connector to front
|
||||
const connector = this.getShrinkConnector();
|
||||
if ($defined(connector)) {
|
||||
if (connector) {
|
||||
connector.moveToFront();
|
||||
}
|
||||
}
|
||||
@ -508,7 +507,7 @@ abstract class Topic extends NodeGraph {
|
||||
}
|
||||
}
|
||||
|
||||
private _setText(text: string, updateModel?: boolean) {
|
||||
private _setText(text: string | null, updateModel?: boolean) {
|
||||
const textShape = this.getTextShape();
|
||||
textShape.setText(text == null ? TopicStyle.defaultText(this) : text);
|
||||
|
||||
@ -520,7 +519,7 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
setText(text: string) {
|
||||
// Avoid empty nodes ...
|
||||
if (!text || $.trim(text).length === 0) {
|
||||
if (!text || text.trim().length === 0) {
|
||||
this._setText(null, true);
|
||||
} else {
|
||||
this._setText(text, true);
|
||||
@ -531,11 +530,8 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
getText(): string {
|
||||
const model = this.getModel();
|
||||
let result = model.getText();
|
||||
if (!$defined(result)) {
|
||||
result = TopicStyle.defaultText(this);
|
||||
}
|
||||
return result;
|
||||
const text = model.getText();
|
||||
return text || TopicStyle.defaultText(this);
|
||||
}
|
||||
|
||||
setBackgroundColor(color: string): void {
|
||||
@ -622,7 +618,7 @@ abstract class Topic extends NodeGraph {
|
||||
}
|
||||
|
||||
const shrinkConnector = this.getShrinkConnector();
|
||||
if ($defined(shrinkConnector)) {
|
||||
if (shrinkConnector) {
|
||||
shrinkConnector.addToWorkspace(group);
|
||||
}
|
||||
|
||||
@ -706,7 +702,7 @@ abstract class Topic extends NodeGraph {
|
||||
EventBus.instance.fireEvent('childShrinked', model);
|
||||
}
|
||||
|
||||
getShrinkConnector(): ShirinkConnector | undefined {
|
||||
getShrinkConnector(): ShirinkConnector | null {
|
||||
let result = this._connector;
|
||||
if (this._connector == null) {
|
||||
this._connector = new ShirinkConnector(this);
|
||||
@ -849,10 +845,10 @@ abstract class Topic extends NodeGraph {
|
||||
.map((node) => node.getOutgoingLine());
|
||||
}
|
||||
|
||||
getOutgoingConnectedTopic(): Topic {
|
||||
getOutgoingConnectedTopic(): Topic | null {
|
||||
let result = null;
|
||||
const line = this.getOutgoingLine();
|
||||
if ($defined(line)) {
|
||||
if (line) {
|
||||
result = line.getTargetTopic();
|
||||
}
|
||||
return result;
|
||||
@ -875,7 +871,7 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
setBranchVisibility(value: boolean): void {
|
||||
let current: Topic = this;
|
||||
let parent: Topic = this;
|
||||
let parent: Topic | null = this;
|
||||
while (parent != null && !parent.isCentralTopic()) {
|
||||
current = parent;
|
||||
parent = current.getParent();
|
||||
@ -905,7 +901,7 @@ abstract class Topic extends NodeGraph {
|
||||
this._relationships.forEach((r) => r.moveToBack());
|
||||
|
||||
const connector = this.getShrinkConnector();
|
||||
if ($defined(connector)) {
|
||||
if (connector) {
|
||||
connector.moveToBack();
|
||||
}
|
||||
|
||||
@ -916,7 +912,7 @@ abstract class Topic extends NodeGraph {
|
||||
moveToFront(): void {
|
||||
this.get2DElement().moveToFront();
|
||||
const connector = this.getShrinkConnector();
|
||||
if ($defined(connector)) {
|
||||
if (connector) {
|
||||
connector.moveToFront();
|
||||
}
|
||||
// Update relationship lines
|
||||
@ -951,7 +947,7 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
if (this.getIncomingLines().length > 0) {
|
||||
const connector = this.getShrinkConnector();
|
||||
if ($defined(connector)) {
|
||||
if (connector) {
|
||||
connector.setVisibility(value, fade);
|
||||
}
|
||||
}
|
||||
@ -970,7 +966,7 @@ abstract class Topic extends NodeGraph {
|
||||
elem.setOpacity(opacity);
|
||||
|
||||
const connector = this.getShrinkConnector();
|
||||
if ($defined(connector)) {
|
||||
if (connector) {
|
||||
connector.setOpacity(opacity);
|
||||
}
|
||||
const textShape = this.getTextShape();
|
||||
@ -1132,7 +1128,7 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
// Display connection node...
|
||||
const connector = targetTopic.getShrinkConnector();
|
||||
if ($defined(connector)) {
|
||||
if (connector) {
|
||||
connector.setVisibility(true);
|
||||
}
|
||||
|
||||
@ -1190,9 +1186,10 @@ abstract class Topic extends NodeGraph {
|
||||
EventBus.instance.fireEvent('topicAdded', this.getModel());
|
||||
}
|
||||
|
||||
if (this.getModel().isConnected()) {
|
||||
const outgoingTopic = this.getOutgoingConnectedTopic();
|
||||
if (this.getModel().isConnected() && outgoingTopic) {
|
||||
EventBus.instance.fireEvent('topicConnected', {
|
||||
parentNode: this.getOutgoingConnectedTopic().getModel(),
|
||||
parentNode: outgoingTopic.getModel(),
|
||||
childNode: this.getModel(),
|
||||
});
|
||||
}
|
||||
@ -1212,7 +1209,7 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
// Is the node already connected ?
|
||||
const targetTopic = this.getOutgoingConnectedTopic();
|
||||
if ($defined(targetTopic)) {
|
||||
if (targetTopic) {
|
||||
result.connectTo(targetTopic);
|
||||
result.setVisibility(false);
|
||||
}
|
||||
@ -1265,19 +1262,18 @@ abstract class Topic extends NodeGraph {
|
||||
}
|
||||
|
||||
private _flatten2DElements(topic: Topic): (Topic | Relationship)[] {
|
||||
let result = [];
|
||||
|
||||
const result: (Topic | Relationship)[] = [];
|
||||
const children = topic.getChildren();
|
||||
children.forEach((child) => {
|
||||
result.push(child);
|
||||
result.push(child.getOutgoingLine());
|
||||
|
||||
const relationships = child.getRelationships();
|
||||
result = result.concat(relationships);
|
||||
result.push(...relationships);
|
||||
|
||||
if (!child.areChildrenShrunken()) {
|
||||
const innerChilds = this._flatten2DElements(child);
|
||||
result = result.concat(innerChilds);
|
||||
result.push(...innerChilds);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
|
@ -18,7 +18,12 @@ abstract class WidgetManager {
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
private createTooltip(mindmapElement, title: string, linkModel: LinkModel, noteModel: NoteModel) {
|
||||
private createTooltip(
|
||||
mindmapElement,
|
||||
title: string,
|
||||
linkModel?: LinkModel,
|
||||
noteModel?: NoteModel,
|
||||
) {
|
||||
const webcomponentShadowRoot = $($('#mindmap-comp')[0].shadowRoot);
|
||||
let tooltip = webcomponentShadowRoot.find('#mindplot-svg-tooltip');
|
||||
if (!tooltip.length) {
|
||||
@ -97,7 +102,11 @@ abstract class WidgetManager {
|
||||
|
||||
abstract showEditorForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon): void;
|
||||
|
||||
abstract showEditorForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon): void;
|
||||
abstract showEditorForNote(
|
||||
topic: Topic,
|
||||
noteModel: NoteModel | null,
|
||||
noteIcon: NoteIcon | null,
|
||||
): void;
|
||||
}
|
||||
|
||||
export default WidgetManager;
|
||||
|
@ -137,10 +137,10 @@ class DeleteCommand extends Command {
|
||||
this._deletedRelModel = [];
|
||||
}
|
||||
|
||||
private _filterChildren(topicIds: number[], commandContext: CommandContext) {
|
||||
private _filterChildren(topicIds: number[], commandContext: CommandContext): Topic[] {
|
||||
const topics = commandContext.findTopics(topicIds);
|
||||
|
||||
const result = [];
|
||||
const result: Topic[] = [];
|
||||
topics.forEach((topic: Topic) => {
|
||||
let parent = topic.getParent();
|
||||
let found = false;
|
||||
|
@ -28,7 +28,7 @@ abstract class ChildrenSorterStrategy {
|
||||
|
||||
abstract detach(treeSet: RootedTreeSet, node: Node): void;
|
||||
|
||||
abstract predict(treeSet: RootedTreeSet, parent, node: Node, position: PositionType);
|
||||
abstract predict(treeSet: RootedTreeSet, parent, node: Node | null, position: PositionType);
|
||||
|
||||
abstract verify(treeSet: RootedTreeSet, node: Node);
|
||||
|
||||
|
@ -128,8 +128,8 @@ class LayoutManager extends Events {
|
||||
|
||||
predict(
|
||||
parentId: number,
|
||||
nodeId: number,
|
||||
position: PositionType,
|
||||
nodeId: number | null,
|
||||
position: PositionType | null,
|
||||
): { order: number; position: PositionType } {
|
||||
$assert($defined(parentId), 'parentId can not be null');
|
||||
|
||||
@ -194,7 +194,7 @@ class LayoutManager extends Events {
|
||||
if (node.hasOrderChanged() || node.hasPositionChanged()) {
|
||||
// Find or create a event ...
|
||||
const id = node.getId();
|
||||
let event: ChangeEvent = this._events.find((e) => e.getId() === id);
|
||||
let event: ChangeEvent | undefined = this._events.find((e) => e.getId() === id);
|
||||
if (!event) {
|
||||
event = new ChangeEvent(id);
|
||||
}
|
||||
|
@ -66,11 +66,11 @@ abstract class INodeModel {
|
||||
this.putProperty('type', type);
|
||||
}
|
||||
|
||||
setText(text: string): void {
|
||||
setText(text: string | null): void {
|
||||
this.putProperty('text', text);
|
||||
}
|
||||
|
||||
getText(): string | undefined {
|
||||
getText(): string | null {
|
||||
return this.getProperty('text') as string;
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ abstract class INodeModel {
|
||||
|
||||
abstract getProperty(key: string): number | string | boolean;
|
||||
|
||||
abstract putProperty(key: string, value: number | string | boolean): void;
|
||||
abstract putProperty(key: string, value: number | string | boolean | null): void;
|
||||
|
||||
abstract setParent(parent: INodeModel): void;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user