working version

This commit is contained in:
Srinath Narayanan 2020-11-23 17:46:59 -08:00
parent 84017660c1
commit 88d71d7070
5 changed files with 143 additions and 49 deletions

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { Descriptor, InputType, SmartUiComponent } from "../../../SmartUi/SmartUiComponent"; import { Descriptor, InputType, SmartUiComponent } from "../../../SmartUi/SmartUiComponent";
import { SqlX } from "./SelfServeTypes"; import { SqlX } from "./SqlX";
interface SelfServeComponentProps { interface SelfServeComponentProps {
propertyNames: string[] propertyNames: string[]
@ -33,8 +33,8 @@ export class SelfServeCmponent extends React.Component<SelfServeComponentProps>
text: "More Details" text: "More Details"
} }
}, },
children: [ children: {
{ "instanceCount" : {
id: "instanceCount", id: "instanceCount",
input: { input: {
label: "Instance Count", label: "Instance Count",
@ -47,7 +47,7 @@ export class SelfServeCmponent extends React.Component<SelfServeComponentProps>
inputType: "slider" inputType: "slider"
} }
}, },
{ "instanceSize": {
id: "instanceSize", id: "instanceSize",
input: { input: {
label: "Instance Size", label: "Instance Size",
@ -61,7 +61,7 @@ export class SelfServeCmponent extends React.Component<SelfServeComponentProps>
defaultKey: "1Core4Gb" defaultKey: "1Core4Gb"
} }
} }
] }
} }
}; };
@ -80,8 +80,8 @@ export class SelfServeCmponent extends React.Component<SelfServeComponentProps>
}; };
public render() : JSX.Element { public render() : JSX.Element {
console.log('keys: ', SqlX.toJson()); const data : Descriptor = {root: SqlX.toJson()}
//return <SmartUiComponent descriptor={this.selfServeData} onChange={this.exampleCallbacks} />
return <SmartUiComponent descriptor={this.selfServeData} onChange={this.exampleCallbacks} /> return <SmartUiComponent descriptor={data} onChange={this.exampleCallbacks} />
} }
} }

View File

@ -1,55 +1,112 @@
import "reflect-metadata"; import "reflect-metadata";
import { EnumItem, Info, InputTypeValue } from "../../../SmartUi/SmartUiComponent";
const SqlXPropertiesKey = 'SqlXPropertiesKey'; const modifyParentProperty = (children: {[key: string]: any}, parentProperty: string, property: string | symbol) : any => {
if (parentProperty in children) {
const modifyParentProperty = (context: any, parentProperty: string, property: string | symbol) : any => { children[parentProperty][property] ={id: property, input: {}}
if (parentProperty in context) { return children
context[parentProperty][property] ={}
return context
} else { } else {
const keys = Object.keys(context) const keys = Object.keys(children)
for(var i =0; i< keys.length; i++) { for(var i =0; i< keys.length; i++) {
context[keys[i]] = modifyParentProperty(context[keys[i]], parentProperty, property) children[keys[i]] = modifyParentProperty(children[keys[i]], parentProperty, property)
return context return children
} }
} }
return context return children
} }
export const Property = (parentProperty?: string): PropertyDecorator => { export const InfoBar = (metadataKey: string, info: Info) => {
return (target, property) => { return (target: any) => {
let context = Reflect.getMetadata(SqlXPropertiesKey, target) let context = Reflect.getMetadata(metadataKey, target)
if(!context) { if(!context) {
context = {} context = {id: "root", info: info, input: undefined, children: {} }
} else {
context.info = info
}
console.log("class context:" + JSON.stringify(context))
Reflect.defineMetadata(metadataKey, context, target)
};
};
export const Property = (metadataKey: string, parentProperty?: string): PropertyDecorator => {
return (target, property) => {
let context = Reflect.getMetadata(metadataKey, target)
if(!context) {
context = {id: "root", info: undefined, input: undefined, children: {} }
context.children[property] = {id: property, input: {}}
} }
if (parentProperty) { if (parentProperty) {
const prevContextValue = JSON.stringify(context) const prevContextValue = JSON.stringify(context)
context = modifyParentProperty(context, parentProperty, property) context.children = modifyParentProperty(context.children, parentProperty, property)
if (JSON.stringify(context) === prevContextValue) { if (JSON.stringify(context) === prevContextValue) {
throw new Error(`${parentProperty} not defined. declare it before the child property with @Property decorator.`) throw new Error(`${parentProperty} not defined. declare it before the child property with @Property decorator.`)
} }
} else { } else {
context[property] = {} context.children[property] = {id: property, input: {}}
} }
console.log("context:" + JSON.stringify(context)) console.log("props context:" + JSON.stringify(context))
Reflect.defineMetadata(SqlXPropertiesKey, context, target) Reflect.defineMetadata(metadataKey, context, target)
}; };
}; };
export class SqlX { export const modifyInputTypes = (metadataKey: string, fieldName: string, value: any) : PropertyDecorator => {
@Property() return (target, property) => {
static prop1: any; let context = Reflect.getMetadata(metadataKey, target)
if(!context) {
@Property() throw new Error("Incorrect order")
static prop2: any;
@Property("prop1")
static prop11: any;
public static toJson = () : any => {
return Reflect.getMetadata(SqlXPropertiesKey, SqlX)
} }
context.children[property].input[fieldName] = value
//context = modifyType(property)
console.log("props context:" + JSON.stringify(context))
Reflect.defineMetadata(metadataKey, context, target)
};
} }
export const Type = (metadataKey: string, type: InputTypeValue): PropertyDecorator => {
return modifyInputTypes(metadataKey, "type", type)
};
export const Label = (metadataKey: string, label: string): PropertyDecorator => {
return modifyInputTypes(metadataKey, "label", label)
};
export const DataFieldName = (metadataKey: string, dataFieldName: string): PropertyDecorator => {
return modifyInputTypes(metadataKey, "dataFieldName", dataFieldName)
};
export const Min = (metadataKey: string, min: number): PropertyDecorator => {
return modifyInputTypes(metadataKey, "min", min)
};
export const Max = (metadataKey: string, max: number): PropertyDecorator => {
return modifyInputTypes(metadataKey, "max", max)
};
export const Step = (metadataKey: string, step: number): PropertyDecorator => {
return modifyInputTypes(metadataKey, "step", step)
};
export const DefaultValue = (metadataKey: string, defaultValue: any): PropertyDecorator => {
return modifyInputTypes(metadataKey, "defaultValue", defaultValue)
};
export const TrueLabel = (metadataKey: string, trueLabel: string): PropertyDecorator => {
return modifyInputTypes(metadataKey, "trueLabel", trueLabel)
};
export const FalseLabel = (metadataKey: string, falseLabel: string): PropertyDecorator => {
return modifyInputTypes(metadataKey, "falseLabel", falseLabel)
};
export const Choices = (metadataKey: string, choices: EnumItem[]): PropertyDecorator => {
return modifyInputTypes(metadataKey, "choices", choices)
};
export const DefaultKey = (metadataKey: string, defaultKey: string): PropertyDecorator => {
return modifyInputTypes(metadataKey, "defaultKey", defaultKey)
};
export const NumberInputType = (metadataKey: string, numberInputType: string): PropertyDecorator => {
return modifyInputTypes(metadataKey, "inputType", numberInputType)
};

View File

@ -0,0 +1,34 @@
import { DataFieldName, Label, Min, Max, Step, DefaultKey, DefaultValue, Property, Type, NumberInputType, Choices } from "./SelfServeTypes";
import { EnumItem } from "../../../SmartUi/SmartUiComponent";
const SqlXRoot = 'SqlXRoot';
export class SqlX {
@Label(SqlXRoot, "Instance Count")
@DataFieldName(SqlXRoot, "instanceCount")
@Min(SqlXRoot, 1)
@Max(SqlXRoot, 5)
@Step(SqlXRoot, 1)
@DefaultValue(SqlXRoot, 1)
@NumberInputType(SqlXRoot, "slider")
@Type(SqlXRoot, "number")
@Property(SqlXRoot)
static instanceCount: any;
@Label(SqlXRoot, "Instance Size")
@DataFieldName(SqlXRoot, "instanceSize")
@Choices(SqlXRoot, SqlX.instanceTypeOptions)
@DefaultKey(SqlXRoot, "1Core4Gb")
@Type(SqlXRoot, "enum")
@Property(SqlXRoot)
static instanceType: any;
static instanceTypeOptions : EnumItem[] = [
{ label: "1Core4Gb", key: "1Core4Gb", value: "1Core4Gb" },
{ label: "2Core8Gb", key: "2Core8Gb", value: "2Core8Gb" },
{ label: "4Core16Gb", key: "4Core16Gb", value: "4Core16Gb" }
]
public static toJson = () : any => {
return Reflect.getMetadata(SqlXRoot, SqlX)
}
}

View File

@ -13,8 +13,8 @@ describe("SmartUiComponent", () => {
text: "More Details" text: "More Details"
} }
}, },
children: [ children: {
{ "throughput": {
id: "throughput", id: "throughput",
input: { input: {
label: "Throughput (input)", label: "Throughput (input)",
@ -27,7 +27,7 @@ describe("SmartUiComponent", () => {
inputType: "spin" inputType: "spin"
} }
}, },
{ "throughput2": {
id: "throughput2", id: "throughput2",
input: { input: {
label: "Throughput (Slider)", label: "Throughput (Slider)",
@ -40,7 +40,7 @@ describe("SmartUiComponent", () => {
inputType: "slider" inputType: "slider"
} }
}, },
{ "containerId": {
id: "containerId", id: "containerId",
input: { input: {
label: "Container id", label: "Container id",
@ -48,7 +48,7 @@ describe("SmartUiComponent", () => {
type: "string" type: "string"
} }
}, },
{ "analyticalStore": {
id: "analyticalStore", id: "analyticalStore",
input: { input: {
label: "Analytical Store", label: "Analytical Store",
@ -59,7 +59,7 @@ describe("SmartUiComponent", () => {
type: "boolean" type: "boolean"
} }
}, },
{ "database": {
id: "database", id: "database",
input: { input: {
label: "Database", label: "Database",
@ -73,7 +73,7 @@ describe("SmartUiComponent", () => {
defaultKey: "db2" defaultKey: "db2"
} }
} }
] }
} }
}; };

View File

@ -75,7 +75,7 @@ export interface Node {
id: string; id: string;
info?: Info; info?: Info;
input?: AnyInput; input?: AnyInput;
children?: Node[]; children?: { [id: string]: Node} ;
} }
export interface Descriptor { export interface Descriptor {
@ -324,7 +324,10 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
<Stack tokens={containerStackTokens} className="widgetRendererContainer"> <Stack tokens={containerStackTokens} className="widgetRendererContainer">
{node.info && this.renderInfo(node.info)} {node.info && this.renderInfo(node.info)}
{node.input && this.renderInput(node.input)} {node.input && this.renderInput(node.input)}
{node.children && node.children.map(child => <div key={child.id}>{this.renderNode(child)}</div>)} {node.children && Object.entries(node.children).map(([key, value]) => {
return <div key={key}>{this.renderNode(value as Node)}</div>
})
}
</Stack> </Stack>
); );
} }