Skip to content

Commit

Permalink
feat: array structured control editor
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed May 7, 2020
1 parent 4c1eceb commit 1608bb7
Show file tree
Hide file tree
Showing 45 changed files with 1,448 additions and 642 deletions.
1 change: 1 addition & 0 deletions core/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"license": "MIT",
"dependencies": {
"@component-controls/specification": "^1.0.1",
"deepmerge": "^4.2.2",
"escape-html": "^1.0.3",
"faker": "^4.1.0",
"typescript": "^3.8.3"
Expand Down
50 changes: 50 additions & 0 deletions core/core/src/randomizeData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import {
ControlTypes,
ComponentControlNumber,
ComponentControlOptions,
ComponentControl,
ComponentControls,
ComponentControlArray,
} from '@component-controls/specification';
import deepmerge from 'deepmerge';
const faker = require('faker/locale/en_US');

const arrayElements = (arr: any[], c?: number) => {
Expand Down Expand Up @@ -112,6 +115,53 @@ export const randomizeData = (controls: ComponentControls): RandomizedData => {
}
return null;
}
case ControlTypes.ARRAY: {
const arrControl = control as ComponentControlArray;
if (Array.isArray(arrControl.value) && arrControl.rowType) {
const randomValues = {
name,
value: arrControl.value.map(row => {
const values = Object.keys(arrControl.rowType).reduce(
(acc, key) => {
const valueType = arrControl.rowType[key];
if (valueType) {
const mockControlType =
valueType.type === ControlTypes.OBJECT
? deepmerge<ComponentControl>(valueType, {
value: row[key]
? Object.keys(row[key]).reduce(
(a, k) => ({
...a,
[k]: { value: row[key][k] },
}),
{},
)
: undefined,
})
: deepmerge<ComponentControl>(valueType, {
value: row[key],
});
const randValue = randomizeData({
[key]: mockControlType,
});
if (randValue) {
return {
...acc,
[key]: randValue[key],
};
}
}
return acc;
},
{},
);
return values;
}),
};
return randomValues;
}
return null;
}
case ControlTypes.OPTIONS: {
const optionsControl = control as ComponentControlOptions;
let value;
Expand Down
181 changes: 169 additions & 12 deletions core/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import escape from 'escape-html';
import {
ComponentControl,
ComponentControls,
ComponentControlArray,
ControlTypes,
} from '@component-controls/specification';
import deepmerge from 'deepmerge';

const mergeValue = (control: ComponentControl, value: any): any => {
if (control && control.type === ControlTypes.OBJECT) {
Expand Down Expand Up @@ -73,27 +75,182 @@ export const getControlValue = (
const control: ComponentControl = controls[propName];
if (control) {
const { value } = control;
if (
control.type === ControlTypes.TEXT &&
control.escapeValue &&
typeof value === 'string'
) {
return escape(value);
} else if (
control.type === ControlTypes.OBJECT &&
typeof value === 'object'
) {
return getControlValues(value as ComponentControls);
switch (control.type) {
case ControlTypes.TEXT: {
if (control.escapeValue && typeof value === 'string') {
return escape(value);
}
break;
}
case ControlTypes.OBJECT: {
if (typeof value === 'object') {
return getControlValues(value as ComponentControls);
}
break;
}
case ControlTypes.ARRAY: {
const arrControl = control as ComponentControlArray;
if (Array.isArray(arrControl.value) && arrControl.rowType) {
const values = arrControl.value.map(row => {
const values = Object.keys(arrControl.rowType).reduce(
(acc, key) => {
const valueType = arrControl.rowType[key];
if (valueType) {
const mockControlType =
valueType.type === ControlTypes.OBJECT
? deepmerge<ComponentControl>(valueType, {
value: row[key]
? Object.keys(row[key]).reduce(
(a, k) => ({
...a,
[k]: { value: row[key][k] },
}),
{},
)
: undefined,
})
: deepmerge<ComponentControl>(valueType, {
value: row[key],
});
const controlValue = getControlValues({
[key]: mockControlType,
});
if (controlValue) {
return {
...acc,
[key]: controlValue[key],
};
}
}
return acc;
},
{},
);
return values;
});
return values;
}
break;
}
}
return value;
}
return undefined;
};

export const getControlValues = (controls: ComponentControls): ControlValues =>
export const getControlValues = (controls?: ComponentControls): ControlValues =>
controls
? Object.keys(controls).reduce((acc, key) => {
const value = getControlValue(controls, key);
return { ...acc, [key]: value };
}, {})
: {};

export const visibleControls = (
controls?: ComponentControls,
): ComponentControls =>
controls && typeof controls == 'object'
? Object.keys(controls)
.filter(key => !controls[key].hidden)
.map((key, index) => ({
name: key,
control: {
...controls[key],
order:
controls[key].order === undefined ? index : controls[key].order,
},
}))
.sort((a, b) => {
const aOrder = a.control.order || 0;
const bOrder = b.control.order || 0;
return aOrder - bOrder;
})
.reduce(
(acc, { name, control }) => ({
...acc,
[name]: { ...control },
}),
{},
)
: {};

export const newControlValues = (
controls: ComponentControls,
): ComponentControls => {
return Object.keys(controls)
.map(name => {
const control = controls[name];
const { data } = control;
if (data === false || data === null) {
return null;
}
const { type } = control;
switch (type) {
case ControlTypes.OBJECT: {
if (typeof control.value === 'object') {
return {
name,
value: {
...newControlValues(control.value as ComponentControls),
},
};
}
return null;
}
case ControlTypes.ARRAY: {
const arrControl = control as ComponentControlArray;
if (Array.isArray(arrControl.value) && arrControl.rowType) {
const randomValues = {
name,
value: arrControl.value.map(row => {
const values = Object.keys(arrControl.rowType).reduce(
(acc, key) => {
const valueType = arrControl.rowType[key];
if (valueType) {
const mockControlType =
valueType.type === ControlTypes.OBJECT
? deepmerge<ComponentControl>(valueType, {
value: row[key]
? Object.keys(row[key]).reduce(
(a, k) => ({
...a,
[k]: { value: row[key][k] },
}),
{},
)
: undefined,
})
: deepmerge<ComponentControl>(valueType, {
value: row[key],
});
const newValue = newControlValues({
[key]: mockControlType,
});
if (newValue) {
return {
...acc,
[key]: newValue[key],
};
}
}
return acc;
},
{},
);
return values;
}),
};
return randomValues;
}
break;
}
default:
break;
}
return {
name,
value: control.defaultValue,
};
})
.reduce((acc, f) => (f ? { ...acc, [f.name]: f.value } : acc), {});
};
Loading

0 comments on commit 1608bb7

Please sign in to comment.