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.get('[test-id="11-15-relationship"]').first().click({ force: true });
|
||||
cy.get('[test-id="11-15-relationship"]').should('exist');
|
||||
|
||||
cy.matchImageSnapshot('addRelationship');
|
||||
});
|
||||
|
||||
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('body').type('{backspace}');
|
||||
|
||||
|
@ -32,7 +32,7 @@ class Editor {
|
||||
}
|
||||
|
||||
isMapLoadded(): boolean {
|
||||
return this.component?.getDesigner()?.getMindmap() != null;
|
||||
return this.component.isLoaded();
|
||||
}
|
||||
|
||||
save(minor: boolean): void {
|
||||
@ -57,9 +57,9 @@ class Editor {
|
||||
mapId: string,
|
||||
persistenceManager: PersistenceManager,
|
||||
widgetManager: WidgetManager,
|
||||
): void {
|
||||
): Promise<void> {
|
||||
this.component.buildDesigner(persistenceManager, widgetManager);
|
||||
this.component.loadMap(mapId);
|
||||
return this.component.loadMap(mapId);
|
||||
}
|
||||
|
||||
registerEvents(canvasUpdate: (timestamp: number) => void, capability: Capability): void {
|
||||
|
@ -79,10 +79,12 @@ const Editor = ({
|
||||
const capability = new Capability(options.mode, mapInfo.isLocked());
|
||||
|
||||
const mindplotRef = useCallback((component: MindplotWebComponent) => {
|
||||
// Initialized model ...
|
||||
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);
|
||||
}, []);
|
||||
|
||||
@ -137,7 +139,7 @@ const Editor = ({
|
||||
message={mapInfo.isLocked() ? mapInfo.getLockedMessage() : ''}
|
||||
/>
|
||||
|
||||
{!model && (
|
||||
{!model?.isMapLoadded() && (
|
||||
<SpinnerCentered>
|
||||
<Vortex
|
||||
visible={true}
|
||||
|
@ -42,9 +42,10 @@ const container = document.getElementById('root');
|
||||
const root = createRoot(container!);
|
||||
root.render(
|
||||
<Editor
|
||||
mapInfo={new MapInfoImpl('welcome', 'Develop Map Title', false)}
|
||||
mapInfo={new MapInfoImpl(mapId, 'Develop Map Title', false)}
|
||||
options={options}
|
||||
persistenceManager={persistence}
|
||||
onAction={(action) => console.log('action called:', action)}
|
||||
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() };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {mindplot.Mindmap} mindmap
|
||||
* @throws will throw an error if mindmapModel is null or undefined
|
||||
*/
|
||||
loadMap(mindmap: Mindmap): void {
|
||||
loadMap(mindmap: Mindmap): Promise<void> {
|
||||
$assert(mindmap, 'mindmapModel can not be null');
|
||||
this._mindmap = mindmap;
|
||||
|
||||
this._workspace.enableQueueRender(true);
|
||||
|
||||
// Init layout manager ...
|
||||
const size = { width: 25, height: 25 };
|
||||
const layoutManager = new LayoutManager(mindmap.getCentralTopic().getId(), size);
|
||||
@ -601,23 +599,29 @@ class Designer extends Events {
|
||||
|
||||
// Building node graph ...
|
||||
const branches = mindmap.getBranches();
|
||||
|
||||
const nodesGraph: Topic[] = [];
|
||||
branches.forEach((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
|
||||
const centralTopic = this.getModel().getCentralTopic();
|
||||
this.goToNode(centralTopic);
|
||||
|
||||
return this._workspace.enableQueueRender(false).then(() => {
|
||||
// Connect relationships ...
|
||||
const relationships = mindmap.getRelationships();
|
||||
relationships.forEach((relationship) => this._relationshipModelToRelationship(relationship));
|
||||
|
||||
// Render nodes ...
|
||||
nodesGraph.forEach((topic) => topic.setVisibility(true));
|
||||
|
||||
// Finally, sort the map ...
|
||||
EventBus.instance.fireEvent('forceLayout');
|
||||
|
||||
this.fireEvent('loadSuccess');
|
||||
});
|
||||
}
|
||||
|
||||
getMindmap(): Mindmap {
|
||||
|
@ -3,7 +3,6 @@ import buildDesigner from './DesignerBuilder';
|
||||
import DesignerOptionsBuilder from './DesignerOptionsBuilder';
|
||||
import EditorRenderMode from './EditorRenderMode';
|
||||
import LocalStorageManager from './LocalStorageManager';
|
||||
import Mindmap from './model/Mindmap';
|
||||
import PersistenceManager from './PersistenceManager';
|
||||
import WidgetManager from './WidgetManager';
|
||||
import mindplotStyles from './styles/mindplot-styles';
|
||||
@ -27,12 +26,12 @@ export type MindplotWebComponentInterface = {
|
||||
class MindplotWebComponent extends HTMLElement {
|
||||
private _shadowRoot: ShadowRoot;
|
||||
|
||||
private _mindmap: Mindmap;
|
||||
|
||||
private _designer: Designer;
|
||||
|
||||
private saveRequired: boolean;
|
||||
|
||||
private _isLoaded: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
@ -77,6 +76,16 @@ class MindplotWebComponent extends HTMLElement {
|
||||
});
|
||||
|
||||
this.registerShortcuts();
|
||||
|
||||
this._designer.addEvent('loadSuccess', (): void => {
|
||||
this._isLoaded = true;
|
||||
});
|
||||
|
||||
return this._designer;
|
||||
}
|
||||
|
||||
isLoaded(): boolean {
|
||||
return this._isLoaded;
|
||||
}
|
||||
|
||||
private registerShortcuts() {
|
||||
@ -100,10 +109,9 @@ class MindplotWebComponent extends HTMLElement {
|
||||
* Load map in designer throught persistence manager instance
|
||||
* @param id the map id to be loaded.
|
||||
*/
|
||||
async loadMap(id: string): Promise<void> {
|
||||
loadMap(id: string): Promise<void> {
|
||||
const instance = PersistenceManager.getInstance();
|
||||
this._mindmap = await instance.load(id);
|
||||
this._designer.loadMap(this._mindmap);
|
||||
return instance.load(id).then((mindmap) => this._designer.loadMap(mindmap));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,12 +61,11 @@ abstract class PersistenceManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
load(mapId: string): Promise<Mindmap> {
|
||||
async load(mapId: string): Promise<Mindmap> {
|
||||
$assert(mapId, 'mapId can not be null');
|
||||
return this.loadMapDom(mapId).then((document) => {
|
||||
console.log(`Loading map with is ${mapId}}`);
|
||||
// eslint-disable-next-line arrow-body-style
|
||||
const document = await this.loadMapDom(mapId);
|
||||
return PersistenceManager.loadFromDom(mapId, document);
|
||||
});
|
||||
}
|
||||
|
||||
triggerError(error: PersistenceError) {
|
||||
|
@ -35,6 +35,10 @@ class Workspace {
|
||||
|
||||
private _visibleAreaSize: SizeType;
|
||||
|
||||
private _renderQueue: Element2D[];
|
||||
|
||||
private queueRenderEnabled: boolean;
|
||||
|
||||
constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) {
|
||||
// Create a suitable container ...
|
||||
$assert(screenManager, 'Div container can not be null');
|
||||
@ -66,6 +70,8 @@ class Workspace {
|
||||
});
|
||||
|
||||
this.setZoom(zoom, true);
|
||||
|
||||
this._renderQueue = [];
|
||||
}
|
||||
|
||||
private _adjustWorkspace(): void {
|
||||
@ -97,6 +103,14 @@ class Workspace {
|
||||
}
|
||||
|
||||
append(shape: Element2D): void {
|
||||
if (this.queueRenderEnabled) {
|
||||
this._renderQueue.push(shape);
|
||||
} else {
|
||||
this.appendInternal(shape);
|
||||
}
|
||||
}
|
||||
|
||||
private appendInternal(shape: Element2D): void {
|
||||
if ($defined(shape.addToWorkspace)) {
|
||||
shape.addToWorkspace(this);
|
||||
} 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 {
|
||||
// Element is a node, not a web2d element?
|
||||
if ($defined(shape.removeFromWorkspace)) {
|
||||
|
@ -159,12 +159,7 @@ class TextPeer extends ElementPeer {
|
||||
}
|
||||
|
||||
getWidth() {
|
||||
let computedWidth = this._native.getBBox().width;
|
||||
if (computedWidth === 0) {
|
||||
const bbox = this._native.getBBox();
|
||||
computedWidth = bbox.width;
|
||||
}
|
||||
|
||||
const computedWidth = this._native.getBBox().width;
|
||||
let width = parseInt(computedWidth, 10);
|
||||
width += this._font.getWidthMargin();
|
||||
return width;
|
||||
|
Loading…
Reference in New Issue
Block a user