mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-10 17:33:24 +01:00
Add delay render support.
This commit is contained in:
parent
a1f0fa6281
commit
046215898e
@ -11,10 +11,16 @@ context('Relationship Topics', () => {
|
|||||||
cy.contains('Try it Now!').first().click();
|
cy.contains('Try it Now!').first().click();
|
||||||
|
|
||||||
cy.get('[test-id="11-15-relationship"]').first().click({ force: true });
|
cy.get('[test-id="11-15-relationship"]').first().click({ force: true });
|
||||||
|
cy.get('[test-id="11-15-relationship"]').should('exist');
|
||||||
|
|
||||||
cy.matchImageSnapshot('addRelationship');
|
cy.matchImageSnapshot('addRelationship');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Delete Relationship', () => {
|
it('Delete Relationship', () => {
|
||||||
|
cy.contains('Features').first().click();
|
||||||
|
cy.get(`[aria-label="Add Relationship"]`).first().click();
|
||||||
|
cy.contains('Try it Now!').first().click();
|
||||||
|
|
||||||
cy.get('[test-id="11-15-relationship"]').click({ force: true });
|
cy.get('[test-id="11-15-relationship"]').click({ force: true });
|
||||||
cy.get('body').type('{backspace}');
|
cy.get('body').type('{backspace}');
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isMapLoadded(): boolean {
|
isMapLoadded(): boolean {
|
||||||
return this.component?.getDesigner()?.getMindmap() != null;
|
return this.component.isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
save(minor: boolean): void {
|
save(minor: boolean): void {
|
||||||
@ -57,9 +57,9 @@ class Editor {
|
|||||||
mapId: string,
|
mapId: string,
|
||||||
persistenceManager: PersistenceManager,
|
persistenceManager: PersistenceManager,
|
||||||
widgetManager: WidgetManager,
|
widgetManager: WidgetManager,
|
||||||
): void {
|
): Promise<void> {
|
||||||
this.component.buildDesigner(persistenceManager, widgetManager);
|
this.component.buildDesigner(persistenceManager, widgetManager);
|
||||||
this.component.loadMap(mapId);
|
return this.component.loadMap(mapId);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerEvents(canvasUpdate: (timestamp: number) => void, capability: Capability): void {
|
registerEvents(canvasUpdate: (timestamp: number) => void, capability: Capability): void {
|
||||||
|
@ -79,10 +79,12 @@ const Editor = ({
|
|||||||
const capability = new Capability(options.mode, mapInfo.isLocked());
|
const capability = new Capability(options.mode, mapInfo.isLocked());
|
||||||
|
|
||||||
const mindplotRef = useCallback((component: MindplotWebComponent) => {
|
const mindplotRef = useCallback((component: MindplotWebComponent) => {
|
||||||
// Initialized model ...
|
|
||||||
const model = new Model(component);
|
const model = new Model(component);
|
||||||
model.loadMindmap(mapInfo.getId(), persistenceManager, widgetManager);
|
|
||||||
model.registerEvents(setCanvasUpdate, capability);
|
// Force refresh after map load ...
|
||||||
|
model.loadMindmap(mapInfo.getId(), persistenceManager, widgetManager).then(() => {
|
||||||
|
setCanvasUpdate(Date.now());
|
||||||
|
});
|
||||||
setModel(model);
|
setModel(model);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -137,7 +139,7 @@ const Editor = ({
|
|||||||
message={mapInfo.isLocked() ? mapInfo.getLockedMessage() : ''}
|
message={mapInfo.isLocked() ? mapInfo.getLockedMessage() : ''}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!model && (
|
{!model?.isMapLoadded() && (
|
||||||
<SpinnerCentered>
|
<SpinnerCentered>
|
||||||
<Vortex
|
<Vortex
|
||||||
visible={true}
|
visible={true}
|
||||||
|
@ -42,9 +42,10 @@ const container = document.getElementById('root');
|
|||||||
const root = createRoot(container!);
|
const root = createRoot(container!);
|
||||||
root.render(
|
root.render(
|
||||||
<Editor
|
<Editor
|
||||||
mapInfo={new MapInfoImpl('welcome', 'Develop Map Title', false)}
|
mapInfo={new MapInfoImpl(mapId, 'Develop Map Title', false)}
|
||||||
options={options}
|
options={options}
|
||||||
persistenceManager={persistence}
|
persistenceManager={persistence}
|
||||||
onAction={(action) => console.log('action called:', action)}
|
onAction={(action) => console.log('action called:', action)}
|
||||||
onLoad={initialization}
|
onLoad={initialization}
|
||||||
/>);
|
/>,
|
||||||
|
);
|
||||||
|
File diff suppressed because one or more lines are too long
@ -577,14 +577,12 @@ class Designer extends Events {
|
|||||||
return { zoom: model.getZoom() };
|
return { zoom: model.getZoom() };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
loadMap(mindmap: Mindmap): Promise<void> {
|
||||||
* @param {mindplot.Mindmap} mindmap
|
|
||||||
* @throws will throw an error if mindmapModel is null or undefined
|
|
||||||
*/
|
|
||||||
loadMap(mindmap: Mindmap): void {
|
|
||||||
$assert(mindmap, 'mindmapModel can not be null');
|
$assert(mindmap, 'mindmapModel can not be null');
|
||||||
this._mindmap = mindmap;
|
this._mindmap = mindmap;
|
||||||
|
|
||||||
|
this._workspace.enableQueueRender(true);
|
||||||
|
|
||||||
// Init layout manager ...
|
// Init layout manager ...
|
||||||
const size = { width: 25, height: 25 };
|
const size = { width: 25, height: 25 };
|
||||||
const layoutManager = new LayoutManager(mindmap.getCentralTopic().getId(), size);
|
const layoutManager = new LayoutManager(mindmap.getCentralTopic().getId(), size);
|
||||||
@ -601,23 +599,29 @@ class Designer extends Events {
|
|||||||
|
|
||||||
// Building node graph ...
|
// Building node graph ...
|
||||||
const branches = mindmap.getBranches();
|
const branches = mindmap.getBranches();
|
||||||
|
|
||||||
|
const nodesGraph: Topic[] = [];
|
||||||
branches.forEach((branch) => {
|
branches.forEach((branch) => {
|
||||||
const nodeGraph = this.nodeModelToTopic(branch);
|
const nodeGraph = this.nodeModelToTopic(branch);
|
||||||
nodeGraph.setBranchVisibility(true);
|
nodesGraph.push(nodeGraph);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Connect relationships ...
|
|
||||||
const relationships = mindmap.getRelationships();
|
|
||||||
relationships.forEach((relationship) => this._relationshipModelToRelationship(relationship));
|
|
||||||
|
|
||||||
// Place the focus on the Central Topic
|
// Place the focus on the Central Topic
|
||||||
const centralTopic = this.getModel().getCentralTopic();
|
const centralTopic = this.getModel().getCentralTopic();
|
||||||
this.goToNode(centralTopic);
|
this.goToNode(centralTopic);
|
||||||
|
|
||||||
// Finally, sort the map ...
|
return this._workspace.enableQueueRender(false).then(() => {
|
||||||
EventBus.instance.fireEvent('forceLayout');
|
// Connect relationships ...
|
||||||
|
const relationships = mindmap.getRelationships();
|
||||||
|
relationships.forEach((relationship) => this._relationshipModelToRelationship(relationship));
|
||||||
|
|
||||||
this.fireEvent('loadSuccess');
|
// Render nodes ...
|
||||||
|
nodesGraph.forEach((topic) => topic.setVisibility(true));
|
||||||
|
|
||||||
|
// Finally, sort the map ...
|
||||||
|
EventBus.instance.fireEvent('forceLayout');
|
||||||
|
this.fireEvent('loadSuccess');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getMindmap(): Mindmap {
|
getMindmap(): Mindmap {
|
||||||
|
@ -3,7 +3,6 @@ import buildDesigner from './DesignerBuilder';
|
|||||||
import DesignerOptionsBuilder from './DesignerOptionsBuilder';
|
import DesignerOptionsBuilder from './DesignerOptionsBuilder';
|
||||||
import EditorRenderMode from './EditorRenderMode';
|
import EditorRenderMode from './EditorRenderMode';
|
||||||
import LocalStorageManager from './LocalStorageManager';
|
import LocalStorageManager from './LocalStorageManager';
|
||||||
import Mindmap from './model/Mindmap';
|
|
||||||
import PersistenceManager from './PersistenceManager';
|
import PersistenceManager from './PersistenceManager';
|
||||||
import WidgetManager from './WidgetManager';
|
import WidgetManager from './WidgetManager';
|
||||||
import mindplotStyles from './styles/mindplot-styles';
|
import mindplotStyles from './styles/mindplot-styles';
|
||||||
@ -27,12 +26,12 @@ export type MindplotWebComponentInterface = {
|
|||||||
class MindplotWebComponent extends HTMLElement {
|
class MindplotWebComponent extends HTMLElement {
|
||||||
private _shadowRoot: ShadowRoot;
|
private _shadowRoot: ShadowRoot;
|
||||||
|
|
||||||
private _mindmap: Mindmap;
|
|
||||||
|
|
||||||
private _designer: Designer;
|
private _designer: Designer;
|
||||||
|
|
||||||
private saveRequired: boolean;
|
private saveRequired: boolean;
|
||||||
|
|
||||||
|
private _isLoaded: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||||
@ -77,6 +76,16 @@ class MindplotWebComponent extends HTMLElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.registerShortcuts();
|
this.registerShortcuts();
|
||||||
|
|
||||||
|
this._designer.addEvent('loadSuccess', (): void => {
|
||||||
|
this._isLoaded = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return this._designer;
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoaded(): boolean {
|
||||||
|
return this._isLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerShortcuts() {
|
private registerShortcuts() {
|
||||||
@ -100,10 +109,9 @@ class MindplotWebComponent extends HTMLElement {
|
|||||||
* Load map in designer throught persistence manager instance
|
* Load map in designer throught persistence manager instance
|
||||||
* @param id the map id to be loaded.
|
* @param id the map id to be loaded.
|
||||||
*/
|
*/
|
||||||
async loadMap(id: string): Promise<void> {
|
loadMap(id: string): Promise<void> {
|
||||||
const instance = PersistenceManager.getInstance();
|
const instance = PersistenceManager.getInstance();
|
||||||
this._mindmap = await instance.load(id);
|
return instance.load(id).then((mindmap) => this._designer.loadMap(mindmap));
|
||||||
this._designer.loadMap(this._mindmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,12 +61,11 @@ abstract class PersistenceManager {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
load(mapId: string): Promise<Mindmap> {
|
async load(mapId: string): Promise<Mindmap> {
|
||||||
$assert(mapId, 'mapId can not be null');
|
$assert(mapId, 'mapId can not be null');
|
||||||
return this.loadMapDom(mapId).then((document) => {
|
// eslint-disable-next-line arrow-body-style
|
||||||
console.log(`Loading map with is ${mapId}}`);
|
const document = await this.loadMapDom(mapId);
|
||||||
return PersistenceManager.loadFromDom(mapId, document);
|
return PersistenceManager.loadFromDom(mapId, document);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerError(error: PersistenceError) {
|
triggerError(error: PersistenceError) {
|
||||||
|
@ -35,6 +35,10 @@ class Workspace {
|
|||||||
|
|
||||||
private _visibleAreaSize: SizeType;
|
private _visibleAreaSize: SizeType;
|
||||||
|
|
||||||
|
private _renderQueue: Element2D[];
|
||||||
|
|
||||||
|
private queueRenderEnabled: boolean;
|
||||||
|
|
||||||
constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) {
|
constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) {
|
||||||
// Create a suitable container ...
|
// Create a suitable container ...
|
||||||
$assert(screenManager, 'Div container can not be null');
|
$assert(screenManager, 'Div container can not be null');
|
||||||
@ -66,6 +70,8 @@ class Workspace {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.setZoom(zoom, true);
|
this.setZoom(zoom, true);
|
||||||
|
|
||||||
|
this._renderQueue = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private _adjustWorkspace(): void {
|
private _adjustWorkspace(): void {
|
||||||
@ -97,6 +103,14 @@ class Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
append(shape: Element2D): void {
|
append(shape: Element2D): void {
|
||||||
|
if (this.queueRenderEnabled) {
|
||||||
|
this._renderQueue.push(shape);
|
||||||
|
} else {
|
||||||
|
this.appendInternal(shape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private appendInternal(shape: Element2D): void {
|
||||||
if ($defined(shape.addToWorkspace)) {
|
if ($defined(shape.addToWorkspace)) {
|
||||||
shape.addToWorkspace(this);
|
shape.addToWorkspace(this);
|
||||||
} else {
|
} else {
|
||||||
@ -104,6 +118,37 @@ class Workspace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableQueueRender(value: boolean): Promise<void> {
|
||||||
|
this.queueRenderEnabled = value;
|
||||||
|
|
||||||
|
let result = Promise.resolve();
|
||||||
|
if (!value) {
|
||||||
|
result = this.processRenderQueue(this._renderQueue.reverse(), 300);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private processRenderQueue(renderQueue: Element2D[], batch: number): Promise<void> {
|
||||||
|
function delay(t: number) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, t));
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: Promise<void>;
|
||||||
|
if (renderQueue.length > 0) {
|
||||||
|
result = new Promise((resolve: (queue: Element2D[]) => void) => {
|
||||||
|
for (let i = 0; i < batch && renderQueue.length > 0; i++) {
|
||||||
|
const elem = renderQueue.pop();
|
||||||
|
this.appendInternal(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(renderQueue);
|
||||||
|
}).then((queue) => delay(30).then(() => this.processRenderQueue(queue, batch)));
|
||||||
|
} else {
|
||||||
|
result = Promise.resolve();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
removeChild(shape: Element2D): void {
|
removeChild(shape: Element2D): void {
|
||||||
// Element is a node, not a web2d element?
|
// Element is a node, not a web2d element?
|
||||||
if ($defined(shape.removeFromWorkspace)) {
|
if ($defined(shape.removeFromWorkspace)) {
|
||||||
|
@ -159,12 +159,7 @@ class TextPeer extends ElementPeer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getWidth() {
|
getWidth() {
|
||||||
let computedWidth = this._native.getBBox().width;
|
const computedWidth = this._native.getBBox().width;
|
||||||
if (computedWidth === 0) {
|
|
||||||
const bbox = this._native.getBBox();
|
|
||||||
computedWidth = bbox.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
let width = parseInt(computedWidth, 10);
|
let width = parseInt(computedWidth, 10);
|
||||||
width += this._font.getWidthMargin();
|
width += this._font.getWidthMargin();
|
||||||
return width;
|
return width;
|
||||||
|
Loading…
Reference in New Issue
Block a user