mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-30 07:04:12 +00:00
Added more Self Serve functionalities (#401)
* added recursion and inition decorators * working version * added todo comment and removed console.log * Added Recursive add * removed type requirement * proper resolution of promises * added custom element and base class * Made selfServe standalone page * Added custom renderer as async type * Added overall defaults * added inital open from data explorer * removed landingpage * added feature for self serve type * renamed sqlx->example and added invalid type * Added comments for Example * removed unnecessary changes * Resolved PR comments Added tests Moved onSubmt and initialize inside base class Moved testExplorer to separate folder made fields of SelfServe Class non static * fixed lint errors * fixed compilation errors * Removed reactbinding changes * renamed dropdown -> choice * Added SelfServeComponent * Addressed PR comments * added toggle, visibility, text display,commandbar * added sqlx example * added onRefrssh * formatting changes * rmoved radioswitch display * updated smartui tests * Added more tests * onSubmit -> onSave * Resolved PR comments
This commit is contained in:
committed by
GitHub
parent
b0b973b21a
commit
49bf8c60db
133
src/SelfServe/Decorators.tsx
Normal file
133
src/SelfServe/Decorators.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import { ChoiceItem, Description, Info, InputType, NumberUiType, SmartUiInput } from "./SelfServeTypes";
|
||||
import { addPropertyToMap, DecoratorProperties, buildSmartUiDescriptor } from "./SelfServeUtils";
|
||||
|
||||
type ValueOf<T> = T[keyof T];
|
||||
interface Decorator {
|
||||
name: keyof DecoratorProperties;
|
||||
value: ValueOf<DecoratorProperties>;
|
||||
}
|
||||
|
||||
interface InputOptionsBase {
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface NumberInputOptions extends InputOptionsBase {
|
||||
min: (() => Promise<number>) | number;
|
||||
max: (() => Promise<number>) | number;
|
||||
step: (() => Promise<number>) | number;
|
||||
uiType: NumberUiType;
|
||||
}
|
||||
|
||||
export interface StringInputOptions extends InputOptionsBase {
|
||||
placeholder?: (() => Promise<string>) | string;
|
||||
}
|
||||
|
||||
export interface BooleanInputOptions extends InputOptionsBase {
|
||||
trueLabel: (() => Promise<string>) | string;
|
||||
falseLabel: (() => Promise<string>) | string;
|
||||
}
|
||||
|
||||
export interface ChoiceInputOptions extends InputOptionsBase {
|
||||
choices: (() => Promise<ChoiceItem[]>) | ChoiceItem[];
|
||||
placeholder?: (() => Promise<string>) | string;
|
||||
}
|
||||
|
||||
export interface DescriptionDisplayOptions {
|
||||
description?: (() => Promise<Description>) | Description;
|
||||
}
|
||||
|
||||
type InputOptions =
|
||||
| NumberInputOptions
|
||||
| StringInputOptions
|
||||
| BooleanInputOptions
|
||||
| ChoiceInputOptions
|
||||
| DescriptionDisplayOptions;
|
||||
|
||||
const isNumberInputOptions = (inputOptions: InputOptions): inputOptions is NumberInputOptions => {
|
||||
return "min" in inputOptions;
|
||||
};
|
||||
|
||||
const isBooleanInputOptions = (inputOptions: InputOptions): inputOptions is BooleanInputOptions => {
|
||||
return "trueLabel" in inputOptions;
|
||||
};
|
||||
|
||||
const isChoiceInputOptions = (inputOptions: InputOptions): inputOptions is ChoiceInputOptions => {
|
||||
return "choices" in inputOptions;
|
||||
};
|
||||
|
||||
const isDescriptionDisplayOptions = (inputOptions: InputOptions): inputOptions is DescriptionDisplayOptions => {
|
||||
return "description" in inputOptions;
|
||||
};
|
||||
|
||||
const addToMap = (...decorators: Decorator[]): PropertyDecorator => {
|
||||
return (target, property) => {
|
||||
let className = target.constructor.name;
|
||||
const propertyName = property.toString();
|
||||
if (className === "Function") {
|
||||
//eslint-disable-next-line @typescript-eslint/ban-types
|
||||
className = (target as Function).name;
|
||||
throw new Error(`Property '${propertyName}' in class '${className}'should be not be static.`);
|
||||
}
|
||||
|
||||
const propertyType = (Reflect.getMetadata("design:type", target, property)?.name as string)?.toLowerCase();
|
||||
addPropertyToMap(target, propertyName, className, "type", propertyType);
|
||||
addPropertyToMap(target, propertyName, className, "dataFieldName", propertyName);
|
||||
|
||||
decorators.map((decorator: Decorator) =>
|
||||
addPropertyToMap(target, propertyName, className, decorator.name, decorator.value)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export const OnChange = (
|
||||
onChange: (currentState: Map<string, SmartUiInput>, newValue: InputType) => Map<string, SmartUiInput>
|
||||
): PropertyDecorator => {
|
||||
return addToMap({ name: "onChange", value: onChange });
|
||||
};
|
||||
|
||||
export const PropertyInfo = (info: (() => Promise<Info>) | Info): PropertyDecorator => {
|
||||
return addToMap({ name: "info", value: info });
|
||||
};
|
||||
|
||||
export const Values = (inputOptions: InputOptions): PropertyDecorator => {
|
||||
if (isNumberInputOptions(inputOptions)) {
|
||||
return addToMap(
|
||||
{ name: "label", value: inputOptions.label },
|
||||
{ name: "min", value: inputOptions.min },
|
||||
{ name: "max", value: inputOptions.max },
|
||||
{ name: "step", value: inputOptions.step },
|
||||
{ name: "uiType", value: inputOptions.uiType }
|
||||
);
|
||||
} else if (isBooleanInputOptions(inputOptions)) {
|
||||
return addToMap(
|
||||
{ name: "label", value: inputOptions.label },
|
||||
{ name: "trueLabel", value: inputOptions.trueLabel },
|
||||
{ name: "falseLabel", value: inputOptions.falseLabel }
|
||||
);
|
||||
} else if (isChoiceInputOptions(inputOptions)) {
|
||||
return addToMap(
|
||||
{ name: "label", value: inputOptions.label },
|
||||
{ name: "placeholder", value: inputOptions.placeholder },
|
||||
{ name: "choices", value: inputOptions.choices }
|
||||
);
|
||||
} else if (isDescriptionDisplayOptions(inputOptions)) {
|
||||
return addToMap({ name: "description", value: inputOptions.description });
|
||||
} else {
|
||||
return addToMap(
|
||||
{ name: "label", value: inputOptions.label },
|
||||
{ name: "placeholder", value: inputOptions.placeholder }
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const IsDisplayable = (): ClassDecorator => {
|
||||
return (target) => {
|
||||
buildSmartUiDescriptor(target.name, target.prototype);
|
||||
};
|
||||
};
|
||||
|
||||
export const ClassInfo = (info: (() => Promise<Info>) | Info): ClassDecorator => {
|
||||
return (target) => {
|
||||
addPropertyToMap(target.prototype, "root", target.name, "info", info);
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user