refactor AppStorage

This commit is contained in:
Bowen Tan 2021-11-30 15:44:04 +08:00
parent a1e998702f
commit dcd448965c
4 changed files with 67 additions and 72 deletions

View File

@ -1,32 +1,18 @@
import { Application, ApplicationComponent } from '@sunmao-ui/core'; import { Application, ApplicationComponent } from '@sunmao-ui/core';
import { ImplementedRuntimeModule, Registry } from '@sunmao-ui/runtime'; import { ImplementedRuntimeModule } from '@sunmao-ui/runtime';
import { produce } from 'immer'; import { produce } from 'immer';
import { eventBus } from './eventBus';
import { DefaultNewModule, EmptyAppSchema } from './constants'; import { DefaultNewModule, EmptyAppSchema } from './constants';
export class AppStorage { export class AppStorage {
components: ApplicationComponent[] = [];
app: Application; app: Application;
modules: ImplementedRuntimeModule[]; modules: ImplementedRuntimeModule[];
// this is current editing Model // this is current editing Model
private currentEditingName: string | undefined;
private currentEditingType: 'app' | 'module' = 'app';
static AppLSKey = 'schema'; static AppLSKey = 'schema';
static ModulesLSKey = 'modules'; static ModulesLSKey = 'modules';
constructor() { constructor() {
this.app = this.getDefaultAppFromLS(); this.app = this.getDefaultAppFromLS();
this.setApp(this.app);
this.modules = this.getModulesFromLS(); this.modules = this.getModulesFromLS();
this.setModules(this.modules);
this.updateCurrentId('app', this.app.metadata.name);
this.refreshComponents();
eventBus.on('componentsChange', (components: ApplicationComponent[]) => {
this.components = components;
this.saveComponentsInLS();
});
} }
getDefaultAppFromLS(): Application { getDefaultAppFromLS(): Application {
@ -53,20 +39,14 @@ export class AppStorage {
} }
} }
updateCurrentId(type: 'app' | 'module', name: string) {
this.currentEditingType = type;
this.currentEditingName = name;
this.refreshComponents();
}
createModule() { createModule() {
this.setModules([...this.modules, DefaultNewModule]); this.setModules([...this.modules, DefaultNewModule]);
this.saveModulesInLS(); this.saveModulesInLS();
} }
removeModule(v: string, n: string) { removeModule(v: string, n: string) {
console.log(v, n) console.log(v, n);
console.log(this.modules) console.log(this.modules);
this.setModules( this.setModules(
this.modules.filter( this.modules.filter(
({ version, metadata: { name } }) => version !== v && name !== n ({ version, metadata: { name } }) => version !== v && name !== n
@ -75,21 +55,24 @@ export class AppStorage {
this.saveModulesInLS(); this.saveModulesInLS();
} }
saveComponentsInLS() { // name is `${module.version}/${module.metadata.name}`
switch (this.currentEditingType) { saveComponentsInLS(
type: 'app' | 'module',
name: string,
components: ApplicationComponent[]
) {
switch (type) {
case 'app': case 'app':
const newApp = produce(this.app, draft => { const newApp = produce(this.app, draft => {
draft.spec.components = this.components; draft.spec.components = components;
}); });
this.setApp(newApp); this.setApp(newApp);
this.saveAppInLS(); this.saveAppInLS();
break; break;
case 'module': case 'module':
const i = this.modules.findIndex( const i = this.modules.findIndex(m => m.metadata.name === name);
m => m.metadata.name === this.currentEditingName
);
const newModules = produce(this.modules, draft => { const newModules = produce(this.modules, draft => {
draft[i].components = this.components; draft[i].components = components;
}); });
this.setModules(newModules); this.setModules(newModules);
this.saveModulesInLS(); this.saveModulesInLS();
@ -99,12 +82,10 @@ export class AppStorage {
private setApp(app: Application) { private setApp(app: Application) {
this.app = app; this.app = app;
eventBus.send('appChange', app);
} }
private setModules(modules: ImplementedRuntimeModule[]) { private setModules(modules: ImplementedRuntimeModule[]) {
this.modules = modules; this.modules = modules;
eventBus.send('modulesChange', modules);
} }
private saveAppInLS() { private saveAppInLS() {
@ -114,27 +95,4 @@ export class AppStorage {
private saveModulesInLS() { private saveModulesInLS() {
localStorage.setItem(AppStorage.ModulesLSKey, JSON.stringify(this.modules)); localStorage.setItem(AppStorage.ModulesLSKey, JSON.stringify(this.modules));
} }
// update components by currentEditingType & cache
private refreshComponents() {
switch (this.currentEditingType) {
case 'module':
const module = this.modules.find(
m => m.metadata.name === this.currentEditingName
);
const componentsOfModule = module?.components || [];
this.components = componentsOfModule;
break;
case 'app':
const componentsOfApp = this.app.spec.components;
this.components = componentsOfApp;
break;
}
this.emitComponentsChange();
}
private emitComponentsChange() {
eventBus.send('componentsReload', this.components);
}
} }

View File

@ -1,4 +1,4 @@
import { makeAutoObservable } from 'mobx'; import { makeAutoObservable, autorun, observable } from 'mobx';
import { Application, ApplicationComponent } from '@sunmao-ui/core'; import { Application, ApplicationComponent } from '@sunmao-ui/core';
import { ImplementedRuntimeModule } from '@sunmao-ui/runtime'; import { ImplementedRuntimeModule } from '@sunmao-ui/runtime';
import { eventBus } from './eventBus'; import { eventBus } from './eventBus';
@ -11,34 +11,70 @@ class EditorStore {
components: ApplicationComponent[] = []; components: ApplicationComponent[] = [];
modules: ImplementedRuntimeModule[]; modules: ImplementedRuntimeModule[];
// it could be app or module's name // it could be app or module's name
currentEditingName: string | undefined; // name is `${module.version}/${module.metadata.name}`
currentEditingName: string = '';
currentEditingType: 'app' | 'module' = 'app'; currentEditingType: 'app' | 'module' = 'app';
app: Application; app: Application;
appStorage = new AppStorage(); appStorage = new AppStorage();
constructor() { constructor() {
makeAutoObservable(this, {
components: observable.shallow,
app: observable.shallow,
modules: observable.shallow,
});
this.app = this.appStorage.app; this.app = this.appStorage.app;
this.modules = this.appStorage.modules; this.modules = this.appStorage.modules;
this.setApp(this.appStorage.app);
this.setModules(this.appStorage.modules);
eventBus.on('selectComponent', id => { eventBus.on('selectComponent', id => {
this.setSelectedComponentId(id); this.setSelectedComponentId(id);
}); });
eventBus.on('componentsChange', components => { eventBus.on('appChange', app => {
this.setComponents(components); this.setApp(app);
}); });
eventBus.on('modulesChange', modules => { eventBus.on('modulesChange', modules => {
this.setModules(modules); this.setModules(modules);
// reregister modules to activate immediately // reregister modules to activate immediately
this.modules.forEach(m => registry.registerModule(m, true)); this.modules.forEach(m => registry.registerModule(m, true));
}); });
makeAutoObservable(this); // listen the change by operations, and save newComponents
eventBus.on('componentsChange', components => {
this.setComponents(components);
this.appStorage.saveComponentsInLS(
this.currentEditingType,
this.currentEditingName,
components
);
});
autorun(() => {
console.log('componentsReload', this.originComponents)
eventBus.send('componentsReload', this.originComponents)
this.setComponents(this.originComponents);
})
}
// init components of app of module
get originComponents(): ApplicationComponent[] {
switch (this.currentEditingType) {
case 'module':
const module = this.modules.find(
m => m.metadata.name === this.currentEditingName
);
return module?.components || [];
case 'app':
console.log('this.app', this.app)
return this.app.spec.components;
}
} }
updateCurrentEditingTarget = (type: 'app' | 'module', name: string) => { updateCurrentEditingTarget = (type: 'app' | 'module', name: string) => {
this.appStorage.updateCurrentId(type, name); this.setCurrentEditingType(type);
// this.setCurrentEditingType(type); this.setCurrentEditingName(name);
// this.setCurrentEditingName(name); };
}
setSelectedComponentId(val: string) { setSelectedComponentId(val: string) {
this.selectedComponentId = val; this.selectedComponentId = val;
@ -49,12 +85,15 @@ class EditorStore {
private setCurrentEditingType(val: 'app' | 'module') { private setCurrentEditingType(val: 'app' | 'module') {
this.currentEditingType = val; this.currentEditingType = val;
} }
setComponents(val: ApplicationComponent[]) { private setComponents(val: ApplicationComponent[]) {
this.components = val; this.components = val;
} }
setModules(val: ImplementedRuntimeModule[]) { private setModules(val: ImplementedRuntimeModule[]) {
this.modules = val; this.modules = val;
} }
private setApp(val: Application) {
this.app = val;
}
} }
export const editorStore = new EditorStore(); export const editorStore = new EditorStore();

View File

@ -6,14 +6,13 @@ export class AppModelManager implements IUndoRedoManager {
components: ApplicationComponent[] = []; components: ApplicationComponent[] = [];
operationStack: OperationList<IOperation> = new OperationList(); operationStack: OperationList<IOperation> = new OperationList();
constructor(components: ApplicationComponent[]) { constructor() {
this.components = components;
this.updateComponents(components);
eventBus.on('undo', () => this.undo()); eventBus.on('undo', () => this.undo());
eventBus.on('redo', () => this.redo()); eventBus.on('redo', () => this.redo());
eventBus.on('operation', o => this.do(o)); eventBus.on('operation', o => this.do(o));
eventBus.on('componentsReload', components => { eventBus.on('componentsReload', components => {
this.updateComponents(components); this.components = components;
this.operationStack = new OperationList();
}); });
} }

View File

@ -1,5 +1,4 @@
import { initSunmaoUI } from '@sunmao-ui/runtime'; import { initSunmaoUI } from '@sunmao-ui/runtime';
import { editorStore } from './EditorStore';
import { AppModelManager } from './operations/AppModelManager'; import { AppModelManager } from './operations/AppModelManager';
const ui = initSunmaoUI(); const ui = initSunmaoUI();
@ -8,7 +7,7 @@ const App = ui.App;
const registry = ui.registry; const registry = ui.registry;
const apiService = ui.apiService; const apiService = ui.apiService;
const stateStore = ui.stateManager.store; const stateStore = ui.stateManager.store;
const appModelManager = new AppModelManager(editorStore.appStorage.components); const appModelManager = new AppModelManager();
export { export {
ui, ui,