move appStorage in editorStore

This commit is contained in:
Bowen Tan 2021-11-30 14:40:40 +08:00
parent 772ca1d519
commit a1e998702f
7 changed files with 72 additions and 62 deletions

View File

@ -14,12 +14,12 @@ export class AppStorage {
static AppLSKey = 'schema'; static AppLSKey = 'schema';
static ModulesLSKey = 'modules'; static ModulesLSKey = 'modules';
constructor(private registry: Registry) { constructor() {
this.app = this.getDefaultAppFromLS(); this.app = this.getDefaultAppFromLS();
this.setApp(this.app) this.setApp(this.app);
this.modules = this.getModulesFromLS(); this.modules = this.getModulesFromLS();
this.setModules(this.modules) this.setModules(this.modules);
this.updateCurrentId('app', this.app.metadata.name); this.updateCurrentId('app', this.app.metadata.name);
this.refreshComponents(); this.refreshComponents();
@ -64,8 +64,14 @@ export class AppStorage {
this.saveModulesInLS(); this.saveModulesInLS();
} }
removeModule(module: ImplementedRuntimeModule) { removeModule(v: string, n: string) {
this.setModules(this.modules.filter(m => m !== module)); console.log(v, n)
console.log(this.modules)
this.setModules(
this.modules.filter(
({ version, metadata: { name } }) => version !== v && name !== n
)
);
this.saveModulesInLS(); this.saveModulesInLS();
} }
@ -107,8 +113,6 @@ export class AppStorage {
private saveModulesInLS() { private saveModulesInLS() {
localStorage.setItem(AppStorage.ModulesLSKey, JSON.stringify(this.modules)); localStorage.setItem(AppStorage.ModulesLSKey, JSON.stringify(this.modules));
// reregister modules to activate immediately
this.modules.forEach(m => this.registry.registerModule(m, true));
} }
// update components by currentEditingType & cache // update components by currentEditingType & cache

View File

@ -1,27 +1,60 @@
import { makeAutoObservable } from 'mobx'; import { makeAutoObservable } from 'mobx';
import { ApplicationComponent } from '../../core/lib'; import { Application, ApplicationComponent } from '@sunmao-ui/core';
import { ImplementedRuntimeModule } from '@sunmao-ui/runtime';
import { eventBus } from './eventBus'; import { eventBus } from './eventBus';
import { AppStorage } from './AppStorage';
import { registry } from './setup';
class EditorStore { class EditorStore {
selectedComponentId = ''; selectedComponentId = '';
// currentEditingComponents, it could be app's or module's components
components: ApplicationComponent[] = []; components: ApplicationComponent[] = [];
modules: ImplementedRuntimeModule[];
// it could be app or module's name
currentEditingName: string | undefined;
currentEditingType: 'app' | 'module' = 'app';
app: Application;
appStorage = new AppStorage();
constructor() { constructor() {
this.app = this.appStorage.app;
this.modules = this.appStorage.modules;
eventBus.on('selectComponent', id => { eventBus.on('selectComponent', id => {
this.setSelectedComponentId(id); this.setSelectedComponentId(id);
}); });
eventBus.on('componentsChange', (components: ApplicationComponent[]) => { eventBus.on('componentsChange', components => {
this.setComponents(components); this.setComponents(components);
}); });
eventBus.on('modulesChange', modules => {
this.setModules(modules);
// reregister modules to activate immediately
this.modules.forEach(m => registry.registerModule(m, true));
});
makeAutoObservable(this); makeAutoObservable(this);
} }
updateCurrentEditingTarget = (type: 'app' | 'module', name: string) => {
this.appStorage.updateCurrentId(type, name);
// this.setCurrentEditingType(type);
// this.setCurrentEditingName(name);
}
setSelectedComponentId(val: string) { setSelectedComponentId(val: string) {
this.selectedComponentId = val; this.selectedComponentId = val;
} }
private setCurrentEditingName(val: string) {
this.currentEditingName = val;
}
private setCurrentEditingType(val: 'app' | 'module') {
this.currentEditingType = val;
}
setComponents(val: ApplicationComponent[]) { setComponents(val: ApplicationComponent[]) {
this.components = val; this.components = val;
} }
setModules(val: ImplementedRuntimeModule[]) {
this.modules = val;
}
} }
export const editorStore = new EditorStore() export const editorStore = new EditorStore();

View File

@ -13,7 +13,6 @@ import { KeyboardEventWrapper } from './KeyboardEventWrapper';
import { ComponentWrapper } from './ComponentWrapper'; import { ComponentWrapper } from './ComponentWrapper';
import { StateEditor, SchemaEditor } from './CodeEditor'; import { StateEditor, SchemaEditor } from './CodeEditor';
import { Explorer } from './Explorer'; import { Explorer } from './Explorer';
import { AppStorage } from '../AppStorage';
import { import {
ModifyComponentPropertiesLeafOperation, ModifyComponentPropertiesLeafOperation,
ReplaceAppLeafOperation, ReplaceAppLeafOperation,
@ -28,11 +27,10 @@ type Props = {
registry: ReturnOfInit['registry']; registry: ReturnOfInit['registry'];
stateStore: ReturnOfInit['stateManager']['store']; stateStore: ReturnOfInit['stateManager']['store'];
apiService: ReturnOfInit['apiService']; apiService: ReturnOfInit['apiService'];
appStorage: AppStorage;
}; };
export const Editor: React.FC<Props> = observer( export const Editor: React.FC<Props> = observer(
({ App, registry, stateStore, appStorage }) => { ({ App, registry, stateStore }) => {
const { components, selectedComponentId } = editorStore; const { components, selectedComponentId } = editorStore;
const [scale, setScale] = useState(100); const [scale, setScale] = useState(100);
@ -144,7 +142,7 @@ export const Editor: React.FC<Props> = observer(
</TabList> </TabList>
<TabPanels flex="1" overflow="auto"> <TabPanels flex="1" overflow="auto">
<TabPanel> <TabPanel>
<Explorer appStorage={appStorage} /> <Explorer />
</TabPanel> </TabPanel>
<TabPanel p={0}> <TabPanel p={0}>
<StructureTree <StructureTree

View File

@ -1,36 +1,18 @@
import { Divider, HStack, IconButton, Text, VStack } from '@chakra-ui/react'; import { Divider, HStack, IconButton, Text, VStack } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { AppStorage } from '../../AppStorage'; import { observer } from 'mobx-react-lite';
import { AddIcon, DeleteIcon } from '@chakra-ui/icons'; import { AddIcon, DeleteIcon } from '@chakra-ui/icons';
import { eventBus } from '../../eventBus';
import { ImplementedRuntimeModule } from '@sunmao-ui/runtime'; import { ImplementedRuntimeModule } from '@sunmao-ui/runtime';
import { editorStore } from '../../EditorStore';
type ExplorerProps = { export const Explorer: React.FC = observer(() => {
appStorage: AppStorage; const { app, modules, updateCurrentEditingTarget } = editorStore;
};
const useAppStorage = (appStorage: AppStorage) => {
const [modules, setModules] = React.useState<ImplementedRuntimeModule[]>(
appStorage.modules
);
eventBus.on('modulesChange', newModules => {
setModules(newModules);
});
return {
modules,
};
};
export const Explorer: React.FC<ExplorerProps> = ({ appStorage }) => {
const app = appStorage.app;
const appItemId = `app_${app.metadata.name}`; const appItemId = `app_${app.metadata.name}`;
const [selectedItem, setSelectedItem] = React.useState<string | undefined>(appItemId); const [selectedItem, setSelectedItem] = React.useState<string | undefined>(appItemId);
const onClickApp = (id: string) => { const onClickApp = (id: string) => {
setSelectedItem(id); setSelectedItem(id);
appStorage.updateCurrentId('app', app.metadata.name); updateCurrentEditingTarget('app', app.metadata.name);
}; };
const appItem = ( const appItem = (
@ -43,15 +25,15 @@ export const Explorer: React.FC<ExplorerProps> = ({ appStorage }) => {
/> />
); );
const { modules } = useAppStorage(appStorage); console.log('modules', modules);
const moduleItems = modules.map((module: ImplementedRuntimeModule) => { const moduleItems = modules.map((module: ImplementedRuntimeModule) => {
const moduleItemId = `module_${module.metadata.name}`; const moduleItemId = `module_${module.metadata.name}`;
const onClickModule = (id: string) => { const onClickModule = (id: string) => {
setSelectedItem(id); setSelectedItem(id);
appStorage.updateCurrentId('module', module.metadata.name); updateCurrentEditingTarget('module', module.metadata.name);
}; };
const onRemove = () => { const onRemove = () => {
appStorage.removeModule(module); editorStore.appStorage.removeModule(module.version, module.metadata.name);
}; };
return ( return (
<ExplorerItem <ExplorerItem
@ -80,13 +62,13 @@ export const Explorer: React.FC<ExplorerProps> = ({ appStorage }) => {
aria-label="create module" aria-label="create module"
size="xs" size="xs"
icon={<AddIcon />} icon={<AddIcon />}
onClick={() => appStorage.createModule()} onClick={() => editorStore.appStorage.createModule()}
/> />
</HStack> </HStack>
{moduleItems} {moduleItems}
</VStack> </VStack>
); );
}; });
type ExplorerItemProps = { type ExplorerItemProps = {
id: string; id: string;

View File

@ -6,7 +6,8 @@ import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css'; import 'react-resizable/css/styles.css';
import { Editor } from './components/Editor'; import { Editor } from './components/Editor';
import { apiService, App, appModelManager, appStorage, registry, stateStore } from './setup'; import { editorStore } from './EditorStore';
import { apiService, App, registry, stateStore } from './setup';
type Options = Partial<{ type Options = Partial<{
components: Parameters<Registry['registerComponent']>[0][]; components: Parameters<Registry['registerComponent']>[0][];
@ -19,7 +20,7 @@ export default function renderApp(options: Options = {}) {
components.forEach(c => registry.registerComponent(c)); components.forEach(c => registry.registerComponent(c));
traits.forEach(t => registry.registerTrait(t)); traits.forEach(t => registry.registerTrait(t));
modules.forEach(m => registry.registerModule(m)); modules.forEach(m => registry.registerModule(m));
appStorage.modules.forEach(m => registry.registerModule(m)); editorStore.appStorage.modules.forEach(m => registry.registerModule(m));
ReactDOM.render( ReactDOM.render(
<StrictMode> <StrictMode>
@ -29,8 +30,6 @@ export default function renderApp(options: Options = {}) {
registry={registry} registry={registry}
stateStore={stateStore} stateStore={stateStore}
apiService={apiService} apiService={apiService}
appStorage={appStorage}
appModelManager={appModelManager}
/> />
</ChakraProvider> </ChakraProvider>
</StrictMode>, </StrictMode>,

View File

@ -8,7 +8,6 @@ import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css'; import 'react-resizable/css/styles.css';
import { Editor } from './components/Editor'; import { Editor } from './components/Editor';
import { appStorage } from './setup';
type Example = { type Example = {
name: string; name: string;
@ -79,16 +78,13 @@ const Playground: React.FC<{ examples: Example[] }> = ({ examples }) => {
</Box> </Box>
</Box> </Box>
<Box flex="1"> <Box flex="1">
{appModelManager && ( <Editor
<Editor key={example!.name}
key={example!.name} App={App!}
App={App!} registry={registry!}
registry={registry!} stateStore={stateStore!}
stateStore={stateStore!} apiService={apiService!}
apiService={apiService!} />
appStorage={appStorage}
/>
)}
</Box> </Box>
</Flex> </Flex>
); );

View File

@ -1,5 +1,5 @@
import { initSunmaoUI } from '@sunmao-ui/runtime'; import { initSunmaoUI } from '@sunmao-ui/runtime';
import { AppStorage } from './AppStorage'; import { editorStore } from './EditorStore';
import { AppModelManager } from './operations/AppModelManager'; import { AppModelManager } from './operations/AppModelManager';
const ui = initSunmaoUI(); const ui = initSunmaoUI();
@ -8,8 +8,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 appStorage = new AppStorage(registry); const appModelManager = new AppModelManager(editorStore.appStorage.components);
const appModelManager = new AppModelManager(appStorage.components);
export { export {
ui, ui,
@ -17,6 +16,5 @@ export {
registry, registry,
apiService, apiService,
stateStore, stateStore,
appStorage,
appModelManager, appModelManager,
}; };