add datasource and support edit trait properties

This commit is contained in:
Bowen Tan 2021-10-13 15:35:04 +08:00
parent 040b778229
commit 09129a2ab0
6 changed files with 113 additions and 6 deletions

View File

@ -1,8 +1,13 @@
import { FormControl, FormLabel, Input } from '@chakra-ui/react';
import { Application } from '@meta-ui/core';
import React from 'react';
import { parseType } from '../../../../runtime/lib';
import { eventBus } from '../../eventBus';
import { ModifyComponentPropertyOperation } from '../../operations/Operations';
import { registry } from '../../metaUI';
import {
ModifyComponentPropertyOperation,
ModifyTraitPropertyOperation,
} from '../../operations/Operations';
type Props = { selectedId: string; app: Application };
@ -11,7 +16,14 @@ export const ComponentForm: React.FC<Props> = props => {
const selectedComponent = app.spec.components.find(c => c.id === selectedId);
const properties = selectedComponent?.properties;
if (!selectedComponent) {
return <div>cannot find component with id: {selectedId}</div>;
}
const properties = selectedComponent.properties;
const { name, version } = parseType(selectedComponent.type);
const spec = registry.getComponent(version, name).spec;
const fields = Object.keys(properties || []).map(key => {
const value = properties![key];
@ -30,11 +42,39 @@ export const ComponentForm: React.FC<Props> = props => {
);
});
const traitForms = selectedComponent.traits.map(t => {
const traitForm = Object.keys(t.properties || []).map(key => {
const value = t.properties[key];
const ref = React.createRef<HTMLInputElement>();
const onBlur = () => {
eventBus.send(
'operation',
new ModifyTraitPropertyOperation(selectedId, t.type, key, ref.current?.value)
);
};
return (
<FormControl key={key}>
<FormLabel>{key}</FormLabel>
<Input ref={ref} onBlur={onBlur} defaultValue={value as string} />
</FormControl>
);
});
return (
<form key={t.type}>
<strong>{t.type}</strong>
{traitForm}
</form>
);
});
return (
<div>
<div>Component Form</div>
<strong>Component Fields</strong>
<div>ID: {selectedComponent?.id}</div>
<form>{fields}</form>
<strong>Trait Fields</strong>
<div>{traitForms}</div>
</div>
);
};

View File

@ -24,8 +24,11 @@ export const StructureTree: React.FC<Props> = props => {
const topLevelComponents: Component[] = [];
const childrenMap: ChildrenMap = new Map();
const components = app.spec.components.filter(c => c.type !== 'core/v1/dummy');
const dataSources = app.spec.components.filter(c => c.type === 'core/v1/dummy');
// parse components array to slotsMap
app.spec.components.forEach(c => {
components.forEach(c => {
const slotTrait = c.traits.find(t => t.type === 'core/v1/slot');
if (slotTrait) {
const { id: parentId, slot } = slotTrait.properties.container as any;
@ -88,6 +91,14 @@ export const StructureTree: React.FC<Props> = props => {
}
const topEles = topLevelComponents.map(genTreeItem);
const dataSourcesEles = dataSources.map(genTreeItem);
return <div>{topEles}</div>;
return (
<div>
<strong>Components</strong>
{topEles}
<strong>DataSources</strong>
{dataSourcesEles}
</div>
);
};

View File

@ -6,6 +6,22 @@ export const DefaultAppSchema: Application = {
metadata: { name: 'basic_grid_layout', description: 'basic grid layout example' },
spec: {
components: [
{
id: 'fetchVolumes',
type: 'core/v1/dummy',
properties: {},
traits: [
{
type: 'core/v1/fetch',
properties: {
name: 'query',
url: 'https://61373521eac1410017c18209.mockapi.io/Volume',
method: 'get',
lazy: false,
},
},
],
},
{
id: 'grid',
type: 'core/v1/grid_layout',

View File

@ -5,6 +5,7 @@ import {
CreateComponentOperation,
RemoveComponentOperation,
ModifyComponentPropertyOperation,
ModifyTraitPropertyOperation,
} from './Operations';
import { produce } from 'immer';
import { registry } from '../metaUI';
@ -127,6 +128,31 @@ export class AppModelManager {
this.undoStack.push(undoOperation);
}
break;
case 'modifyTraitProperty':
const mto = o as ModifyTraitPropertyOperation;
let oldValue;
newApp = produce(this.app, draft => {
draft.spec.components.forEach(c => {
if (c.id === mto.componentId) {
c.traits.forEach(t => {
if (t.type === mto.traitType) {
oldValue = t.properties[mto.propertyKey];
t.properties[mto.propertyKey] = mto.propertyValue;
}
});
}
});
});
if (!noEffect) {
const undoOperation = new ModifyTraitPropertyOperation(
mto.componentId,
mto.traitType,
mto.propertyKey,
oldValue
);
this.undoStack.push(undoOperation);
}
break;
}
this.updateApp(newApp);
}

View File

@ -26,3 +26,13 @@ export class ModifyComponentPropertyOperation {
public propertyValue: unknown
) {}
}
export class ModifyTraitPropertyOperation {
kind = 'modifyTraitProperty';
constructor(
public componentId: string,
public traitType: string,
public propertyKey: string,
public propertyValue: unknown
) {}
}

View File

@ -171,7 +171,11 @@ export const ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>(
);
// wrap component, but grid_layout is root component and cannot be chosen, so don't wrap it
if (ComponentWrapper && c.parsedType.name !== 'grid_layout') {
if (
ComponentWrapper &&
c.parsedType.name !== 'dummy' &&
c.parsedType.name !== 'grid_layout'
) {
result = <ComponentWrapper id={c.id}>{result}</ComponentWrapper>;
}