* Updated test * updated assertions * Resizing image to take full width of table cell * updated assertion * Stop updating dynamicBindingPathList directly from widget * Fix selectedRow and selectedRows computations * Fix primaryColumns computations * Updated test for derived column * Added tests for computed value * Added check clear data * Reordering of test * updated common method * Made image size as 100% of table cell size * add templating logic * Updated flow and dsl * Clear old primary columns * Updated testname * updated assertion * use evaluated values for children * Fix primary columns update on component mount and component update * add isArray check * remove property pane enhancement reducer * add property pane enhancement reducer * disable items other than template + fix running property enchancment on drop of list widget * disbled drag, resize, settingsControl, drag for items other than template * add grid options * uncomment the widget operation for add child for grid children * handle delete scenario for child widget in list widget * WIP: Use the new delete and update property features * add listdsl.json for testcases * add test cases for correct no. of items being rendered * add test cases currentItem binding in list widget * change dragEnabled to dragDisabled * change resizeEnabled to resizeDisabled * change settingsControlEnabled to settingsControlDisabled * change dropEnabled to dropDisabled * update settingsControlDisabled default value * Use deleteProperties in propertyControls * Fix unsetting of array indices when deleting widget properties * remove old TableWidget.tsx file * Fix derived column property update on primary column property update * Handle undefined primary columns * Fix filepicker immutable prop issue * Fix object.freeze issue when adding ids to the property pane configuration * fix widget issue in grid * Fix column actions dynamicBindingPathList inclusion issue * remove consoles + fix typo around batch update * Remove redundant tests * js binding test for date picker * hydate enhancement map on copy list widget * check for dynamicleaf * fixes * improve check * fix getNextWidgetName * update template in list widget when copying * updating template copy logic when copying widget * update dynamicBindingPathList in copied widget * Add path parameter to hidden functions in property pane configs * fix copy bug when copying list widget * add computed list property control * Remove time column type Fix editor prompt for currentRow Fix undefined derivedColumns scenario Remove validations for primaryColums and derivedColumns Fix section toggle for video, image and button column types * Fix table widget actions and custom column migrations * Add logs for cyclical dependency map ♻️ * Process array differences * add property control for list widget * Fix onClick migrations * Property pane config parity * binding and trigger paths from the property pane config (#2920) * try react virtualized library * Fix unit test * Fix unit test ✅ * Fix minor issues in table widget * Add default meta props to binding paths to ensure eval and validation * Dummy commit 🎉 * Remove unnecessary datepicker test Fix chart data as string issue * Achieve table column sorting and resizing parity with release * handle scenario where last column isn't available to access * Fix for panel config path not existing in the widget * Fix bindings in currentRow (default) Add dummy property pane config for canvas widget * Update canvas widgets with dynamicPathLists on delete of property paths * Add all diffs to change paths and trim later * Add back default properties 🚶🏻♂️ * Use object based paths instead of arrays for primaryColumns and derivedColumns * Fix issue in reordered columns * Fix inccorect update order * add virtualized list * Fix failing property pane tests * minor change * minor list widget change * Remove .vscode from git * Rename ads to alloy Fix isVisible in list widget * move grid component to widget folder * fix import in widget registry * add sticky row in virtualized list * add sticky container * Fix Height of grid widget items container * fix dragging of items in children other than template children * update list widget * update list widget * Fix padding in list widget * hide scrollbar in list widget list * fix copy bug in list widget * regenrate enhancement map on undo delete widget * Use enhancementmap for autocomplete in list widget Basic styles for list widget scrollbar * add custom control in widget config * minor commit * update scrollbar styles * remove unused variable * fix typo in custom control * comment out test cases * remove unused imports * remove unused imports * add JSON stringify in interweave * add noPad styling in dragLayer for noPad prop * implement grid gap * add list item background color prop * add white color in color picker control * fix gap in last list item * remove onBeforeParse in textcomponent * remove virtualization in grid widget * allow overflow-y * add onListItemClick action * add beta label * add pagination * fix actions in pagination in list widget * add list widget icon * add list background color default value * remove extra div * fix pagination issue * fix list widget crashing on perpage change * extract child operation function to widgetblueprint saga * refactor enhancements * add enhancement hook * refactor propertyUpdate hook enhancment * remove enhacement map * revert renaming ads to alloy * add autopagination * Cleanup unused vars Re-write loop using map Fix binding with external input widget * update default background color * remove unnessary scrol + fix pagination per page * remove console.log * use grid gap in pixel instead of snap * fix list widget tests for binding * add tests for on click action and pagination * remove unnecessary imports * remove overflow hidden in list component * Add feature to enable template actions * update property pane help text for list widget * disable pagination in editor view * update property pane options * add test case for action * uncomment tests * fix grid gap validation * update test cases * fix property pane opening issue for list tempalte * Disable form widgets in list widget * fix template issue for actions * add validation tests for list data * update starting template * add selectedRow + enable pagination in edit mode * remove extra padding in list widget + popper fix on settingDisabled * add stop propagation for button click * fix click event in edit mode * disallow filepicker widget for list widget * add test for list widget entity definition for selectItem * remove unused imports * fix test * remove evaluated value for list child widgets * add comment * remove log * fix copying bug in list widget * add check for not allowing template to copy * fix test * add test for property pane actions * remove unused import * add draglayercomponent test * add test for draggable component * add test for evaluatedvalue popup * add test for messages.ts * add test for widgeticons * add test for property pane selector * add test for widget config response * start testing widget configresponse * add test for enhancements in widget config * add test for codeeditor * add test for base widget + list widget * add test for executeWidgetBlueprintChildOperations * remove unused import * add test for widget operation utils * remove unused import * add test for handleSpecificCasesWhilePasting * remove unused function * remove unused import * add empty list styling * resolve all review comments * fix message test * add test for widget operation utils * fix merge conflicts * move validations in property config Co-authored-by: Abhinav Jha <abhinav@appsmith.com> Co-authored-by: nandan.anantharamu <nandan.anantharamu@thoughtspot.com> Co-authored-by: vicky-primathon.in <vicky.bansal@primathon.in> Co-authored-by: Pawan Kumar <pawankumar@Pawans-MacBook-Pro.local> Co-authored-by: Piyush <piyush@codeitout.com> Co-authored-by: hetunandu <hetu@appsmith.com> Co-authored-by: Hetu Nandu <hetunandu@gmail.com> Co-authored-by: root <root@DESKTOP-9GENCK0.localdomain>
824 lines
25 KiB
TypeScript
824 lines
25 KiB
TypeScript
import { WidgetConfigReducerState } from "reducers/entityReducers/widgetConfigReducer";
|
|
import { WidgetProps } from "widgets/BaseWidget";
|
|
import moment from "moment-timezone";
|
|
import { cloneDeep, get, indexOf, isString } from "lodash";
|
|
import { generateReactKey } from "utils/generators";
|
|
import { WidgetTypes } from "constants/WidgetConstants";
|
|
import { BlueprintOperationTypes } from "sagas/WidgetBlueprintSagasEnums";
|
|
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
|
|
import { getDynamicBindings } from "utils/DynamicBindingUtils";
|
|
import { Colors } from "constants/Colors";
|
|
import FileDataTypes from "widgets/FileDataTypes";
|
|
|
|
/**
|
|
* this config sets the default values of properties being used in the widget
|
|
*/
|
|
const WidgetConfigResponse: WidgetConfigReducerState = {
|
|
config: {
|
|
BUTTON_WIDGET: {
|
|
text: "Submit",
|
|
buttonStyle: "PRIMARY_BUTTON",
|
|
rows: 1,
|
|
columns: 2,
|
|
widgetName: "Button",
|
|
isDisabled: false,
|
|
isVisible: true,
|
|
isDefaultClickDisabled: true,
|
|
version: 1,
|
|
},
|
|
TEXT_WIDGET: {
|
|
text: "Label",
|
|
fontSize: "PARAGRAPH",
|
|
fontStyle: "BOLD",
|
|
textAlign: "LEFT",
|
|
textColor: Colors.THUNDER,
|
|
rows: 1,
|
|
columns: 4,
|
|
widgetName: "Text",
|
|
version: 1,
|
|
},
|
|
RICH_TEXT_EDITOR_WIDGET: {
|
|
defaultText: "This is the initial <b>content</b> of the editor",
|
|
rows: 5,
|
|
columns: 8,
|
|
isDisabled: false,
|
|
isVisible: true,
|
|
widgetName: "RichTextEditor",
|
|
isDefaultClickDisabled: true,
|
|
inputType: "html",
|
|
version: 1,
|
|
},
|
|
IMAGE_WIDGET: {
|
|
defaultImage:
|
|
"https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png",
|
|
imageShape: "RECTANGLE",
|
|
maxZoomLevel: 1,
|
|
image: "",
|
|
rows: 3,
|
|
columns: 4,
|
|
widgetName: "Image",
|
|
version: 1,
|
|
},
|
|
INPUT_WIDGET: {
|
|
inputType: "TEXT",
|
|
rows: 1,
|
|
label: "",
|
|
columns: 5,
|
|
widgetName: "Input",
|
|
version: 1,
|
|
resetOnSubmit: true,
|
|
},
|
|
SWITCH_WIDGET: {
|
|
label: "Label",
|
|
rows: 1,
|
|
columns: 2,
|
|
defaultSwitchState: true,
|
|
widgetName: "Switch",
|
|
alignWidget: "LEFT",
|
|
version: 1,
|
|
},
|
|
ICON_WIDGET: {
|
|
widgetName: "Icon",
|
|
rows: 1,
|
|
columns: 1,
|
|
version: 1,
|
|
},
|
|
CONTAINER_WIDGET: {
|
|
backgroundColor: "#FFFFFF",
|
|
rows: 10,
|
|
columns: 8,
|
|
widgetName: "Container",
|
|
containerStyle: "card",
|
|
children: [],
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "CANVAS_WIDGET",
|
|
position: { top: 0, left: 0 },
|
|
props: {
|
|
containerStyle: "none",
|
|
canExtend: false,
|
|
detachFromLayout: true,
|
|
children: [],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
version: 1,
|
|
},
|
|
DATE_PICKER_WIDGET: {
|
|
isDisabled: false,
|
|
datePickerType: "DATE_PICKER",
|
|
rows: 1,
|
|
label: "",
|
|
dateFormat: "DD/MM/YYYY HH:mm",
|
|
columns: 5,
|
|
widgetName: "DatePicker",
|
|
defaultDate: moment().format("DD/MM/YYYY HH:mm"),
|
|
version: 1,
|
|
},
|
|
DATE_PICKER_WIDGET2: {
|
|
isDisabled: false,
|
|
datePickerType: "DATE_PICKER",
|
|
rows: 1,
|
|
label: "",
|
|
dateFormat: "DD/MM/YYYY HH:mm",
|
|
columns: 5,
|
|
widgetName: "DatePicker",
|
|
defaultDate: moment().toISOString(),
|
|
version: 2,
|
|
},
|
|
VIDEO_WIDGET: {
|
|
rows: 7,
|
|
columns: 7,
|
|
widgetName: "Video",
|
|
url: "https://www.youtube.com/watch?v=mzqK0QIZRLs",
|
|
autoPlay: false,
|
|
version: 1,
|
|
},
|
|
TABLE_WIDGET: {
|
|
rows: 7,
|
|
columns: 8,
|
|
label: "Data",
|
|
widgetName: "Table",
|
|
searchKey: "",
|
|
textSize: "PARAGRAPH",
|
|
horizontalAlignment: "LEFT",
|
|
verticalAlignment: "CENTER",
|
|
primaryColumns: {},
|
|
derivedColumns: {},
|
|
tableData: [
|
|
{
|
|
id: 2381224,
|
|
email: "michael.lawson@reqres.in",
|
|
userName: "Michael Lawson",
|
|
productName: "Chicken Sandwich",
|
|
orderAmount: 4.99,
|
|
},
|
|
{
|
|
id: 2736212,
|
|
email: "lindsay.ferguson@reqres.in",
|
|
userName: "Lindsay Ferguson",
|
|
productName: "Tuna Salad",
|
|
orderAmount: 9.99,
|
|
},
|
|
{
|
|
id: 6788734,
|
|
email: "tobias.funke@reqres.in",
|
|
userName: "Tobias Funke",
|
|
productName: "Beef steak",
|
|
orderAmount: 19.99,
|
|
},
|
|
],
|
|
version: 1,
|
|
},
|
|
DROP_DOWN_WIDGET: {
|
|
rows: 1,
|
|
columns: 5,
|
|
label: "",
|
|
selectionType: "SINGLE_SELECT",
|
|
options: [
|
|
{ label: "Vegetarian", value: "VEG" },
|
|
{ label: "Non-Vegetarian", value: "NON_VEG" },
|
|
{ label: "Vegan", value: "VEGAN" },
|
|
],
|
|
widgetName: "Dropdown",
|
|
defaultOptionValue: "VEG",
|
|
version: 1,
|
|
},
|
|
CHECKBOX_WIDGET: {
|
|
rows: 1,
|
|
columns: 3,
|
|
label: "Label",
|
|
defaultCheckedState: true,
|
|
widgetName: "Checkbox",
|
|
version: 1,
|
|
alignWidget: "LEFT",
|
|
},
|
|
RADIO_GROUP_WIDGET: {
|
|
rows: 2,
|
|
columns: 3,
|
|
label: "",
|
|
options: [
|
|
{ label: "Male", value: "M" },
|
|
{ label: "Female", value: "F" },
|
|
],
|
|
defaultOptionValue: "M",
|
|
widgetName: "RadioGroup",
|
|
version: 1,
|
|
},
|
|
FILE_PICKER_WIDGET: {
|
|
rows: 1,
|
|
files: [],
|
|
label: "Select Files",
|
|
columns: 4,
|
|
maxNumFiles: 1,
|
|
maxFileSize: 5,
|
|
fileDataType: FileDataTypes.Base64,
|
|
widgetName: "FilePicker",
|
|
isDefaultClickDisabled: true,
|
|
version: 1,
|
|
},
|
|
TABS_WIDGET: {
|
|
rows: 7,
|
|
columns: 8,
|
|
shouldScrollContents: false,
|
|
widgetName: "Tabs",
|
|
tabs: [
|
|
{ label: "Tab 1", id: "tab1", widgetId: "", isVisible: true },
|
|
{ label: "Tab 2", id: "tab2", widgetId: "", isVisible: true },
|
|
],
|
|
shouldShowTabs: true,
|
|
defaultTab: "Tab 1",
|
|
blueprint: {
|
|
operations: [
|
|
{
|
|
type: BlueprintOperationTypes.MODIFY_PROPS,
|
|
fn: (widget: WidgetProps & { children?: WidgetProps[] }) => {
|
|
const tabs = [...widget.tabs];
|
|
|
|
const newTabs = tabs.map((tab: any) => {
|
|
const newTab = { ...tab };
|
|
newTab.widgetId = generateReactKey();
|
|
return newTab;
|
|
});
|
|
const updatePropertyMap = [
|
|
{
|
|
widgetId: widget.widgetId,
|
|
propertyName: "tabs",
|
|
propertyValue: newTabs,
|
|
},
|
|
];
|
|
return updatePropertyMap;
|
|
},
|
|
},
|
|
],
|
|
},
|
|
version: 1,
|
|
},
|
|
MODAL_WIDGET: {
|
|
rows: 6,
|
|
columns: 6,
|
|
size: "MODAL_SMALL",
|
|
canEscapeKeyClose: true,
|
|
// detachFromLayout is set true for widgets that are not bound to the widgets within the layout.
|
|
// setting it to true will only render the widgets(from sidebar) on the main container without any collision check.
|
|
detachFromLayout: true,
|
|
canOutsideClickClose: true,
|
|
shouldScrollContents: true,
|
|
widgetName: "Modal",
|
|
children: [],
|
|
version: 1,
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "CANVAS_WIDGET",
|
|
position: { left: 0, top: 0 },
|
|
props: {
|
|
detachFromLayout: true,
|
|
canExtend: true,
|
|
isVisible: true,
|
|
isDisabled: false,
|
|
shouldScrollContents: false,
|
|
children: [],
|
|
version: 1,
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "ICON_WIDGET",
|
|
position: { left: 14, top: 0 },
|
|
size: { rows: 1, cols: 2 },
|
|
props: {
|
|
iconName: "cross",
|
|
iconSize: 24,
|
|
color: "#040627",
|
|
version: 1,
|
|
},
|
|
},
|
|
{
|
|
type: "TEXT_WIDGET",
|
|
position: { left: 0, top: 0 },
|
|
size: { rows: 1, cols: 10 },
|
|
props: {
|
|
text: "Modal Title",
|
|
textStyle: "HEADING",
|
|
version: 1,
|
|
},
|
|
},
|
|
{
|
|
type: "BUTTON_WIDGET",
|
|
position: { left: 9, top: 4 },
|
|
size: { rows: 1, cols: 3 },
|
|
props: {
|
|
text: "Cancel",
|
|
buttonStyle: "SECONDARY_BUTTON",
|
|
version: 1,
|
|
},
|
|
},
|
|
{
|
|
type: "BUTTON_WIDGET",
|
|
position: { left: 12, top: 4 },
|
|
size: { rows: 1, cols: 4 },
|
|
props: {
|
|
text: "Confirm",
|
|
buttonStyle: "PRIMARY_BUTTON",
|
|
version: 1,
|
|
},
|
|
},
|
|
],
|
|
operations: [
|
|
{
|
|
type: BlueprintOperationTypes.MODIFY_PROPS,
|
|
fn: (
|
|
widget: WidgetProps & { children?: WidgetProps[] },
|
|
widgets: { [widgetId: string]: FlattenedWidgetProps },
|
|
parent?: WidgetProps & { children?: WidgetProps[] },
|
|
) => {
|
|
const iconChild =
|
|
widget.children &&
|
|
widget.children.find(
|
|
(child) => child.type === "ICON_WIDGET",
|
|
);
|
|
|
|
if (iconChild && parent) {
|
|
return [
|
|
{
|
|
widgetId: iconChild.widgetId,
|
|
propertyName: "onClick",
|
|
propertyValue: `{{closeModal('${parent.widgetName}')}}`,
|
|
},
|
|
];
|
|
}
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
CANVAS_WIDGET: {
|
|
rows: 0,
|
|
columns: 0,
|
|
widgetName: "Canvas",
|
|
version: 1,
|
|
},
|
|
CHART_WIDGET: {
|
|
rows: 8,
|
|
columns: 6,
|
|
widgetName: "Chart",
|
|
chartType: "LINE_CHART",
|
|
chartName: "Sales on working days",
|
|
allowHorizontalScroll: false,
|
|
version: 1,
|
|
chartData: [
|
|
{
|
|
seriesName: "Sales",
|
|
data: [
|
|
{
|
|
x: "Mon",
|
|
y: 10000,
|
|
},
|
|
{
|
|
x: "Tue",
|
|
y: 12000,
|
|
},
|
|
{
|
|
x: "Wed",
|
|
y: 32000,
|
|
},
|
|
{
|
|
x: "Thu",
|
|
y: 28000,
|
|
},
|
|
{
|
|
x: "Fri",
|
|
y: 14000,
|
|
},
|
|
{
|
|
x: "Sat",
|
|
y: 19000,
|
|
},
|
|
{
|
|
x: "Sun",
|
|
y: 36000,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
xAxisName: "Last Week",
|
|
yAxisName: "Total Order Revenue $",
|
|
},
|
|
FORM_BUTTON_WIDGET: {
|
|
rows: 1,
|
|
columns: 3,
|
|
widgetName: "FormButton",
|
|
text: "Submit",
|
|
isDefaultClickDisabled: true,
|
|
version: 1,
|
|
},
|
|
FORM_WIDGET: {
|
|
rows: 13,
|
|
columns: 7,
|
|
widgetName: "Form",
|
|
backgroundColor: "white",
|
|
children: [],
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "CANVAS_WIDGET",
|
|
position: { top: 0, left: 0 },
|
|
props: {
|
|
containerStyle: "none",
|
|
canExtend: false,
|
|
detachFromLayout: true,
|
|
children: [],
|
|
version: 1,
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "TEXT_WIDGET",
|
|
size: { rows: 1, cols: 12 },
|
|
position: { top: 0, left: 0 },
|
|
props: {
|
|
text: "Form",
|
|
textStyle: "HEADING",
|
|
version: 1,
|
|
},
|
|
},
|
|
{
|
|
type: "FORM_BUTTON_WIDGET",
|
|
size: { rows: 1, cols: 4 },
|
|
position: { top: 11, left: 12 },
|
|
props: {
|
|
text: "Submit",
|
|
buttonStyle: "PRIMARY_BUTTON",
|
|
disabledWhenInvalid: true,
|
|
resetFormOnClick: true,
|
|
version: 1,
|
|
},
|
|
},
|
|
{
|
|
type: "FORM_BUTTON_WIDGET",
|
|
size: { rows: 1, cols: 4 },
|
|
position: { top: 11, left: 8 },
|
|
props: {
|
|
text: "Reset",
|
|
buttonStyle: "SECONDARY_BUTTON",
|
|
disabledWhenInvalid: false,
|
|
resetFormOnClick: true,
|
|
version: 1,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
MAP_WIDGET: {
|
|
rows: 12,
|
|
columns: 8,
|
|
isDisabled: false,
|
|
isVisible: true,
|
|
widgetName: "Map",
|
|
enableSearch: true,
|
|
zoomLevel: 50,
|
|
enablePickLocation: true,
|
|
allowZoom: true,
|
|
mapCenter: { lat: -34.397, long: 150.644 },
|
|
defaultMarkers: [{ lat: -34.397, long: 150.644, title: "Test A" }],
|
|
version: 1,
|
|
},
|
|
SKELETON_WIDGET: {
|
|
isLoading: true,
|
|
rows: 1,
|
|
columns: 1,
|
|
widgetName: "Skeleton",
|
|
version: 1,
|
|
},
|
|
[WidgetTypes.LIST_WIDGET]: {
|
|
backgroundColor: "",
|
|
itemBackgroundColor: "white",
|
|
rows: 10,
|
|
columns: 8,
|
|
gridType: "vertical",
|
|
enhancements: {
|
|
child: {
|
|
autocomplete: (parentProps: any) => {
|
|
return parentProps.childAutoComplete;
|
|
},
|
|
hideEvaluatedValue: () => true,
|
|
propertyUpdateHook: (
|
|
parentProps: any,
|
|
widgetName: string,
|
|
propertyPath: string, // onClick
|
|
propertyValue: string,
|
|
isTriggerProperty: boolean,
|
|
) => {
|
|
let value = propertyValue;
|
|
|
|
if (!parentProps.widgetId) return [];
|
|
|
|
const { jsSnippets } = getDynamicBindings(propertyValue);
|
|
|
|
const modifiedAction = jsSnippets.reduce(
|
|
(prev: string, next: string) => {
|
|
return `${prev}${next}`;
|
|
},
|
|
"",
|
|
);
|
|
|
|
value = `{{${parentProps.widgetName}.items.map((currentItem) => ${modifiedAction})}}`;
|
|
const path = `template.${widgetName}.${propertyPath}`;
|
|
|
|
return [
|
|
{
|
|
widgetId: parentProps.widgetId,
|
|
propertyPath: path,
|
|
propertyValue: isTriggerProperty ? propertyValue : value,
|
|
isDynamicTrigger: isTriggerProperty,
|
|
},
|
|
];
|
|
},
|
|
},
|
|
},
|
|
gridGap: 0,
|
|
items: [
|
|
{
|
|
id: 1,
|
|
num: "001",
|
|
name: "Bulbasaur",
|
|
img: "http://www.serebii.net/pokemongo/pokemon/001.png",
|
|
},
|
|
{
|
|
id: 2,
|
|
num: "002",
|
|
name: "Ivysaur",
|
|
img: "http://www.serebii.net/pokemongo/pokemon/002.png",
|
|
},
|
|
{
|
|
id: 3,
|
|
num: "003",
|
|
name: "Venusaur",
|
|
img: "http://www.serebii.net/pokemongo/pokemon/003.png",
|
|
},
|
|
{
|
|
id: 4,
|
|
num: "004",
|
|
name: "Charmander",
|
|
img: "http://www.serebii.net/pokemongo/pokemon/004.png",
|
|
},
|
|
{
|
|
id: 5,
|
|
num: "005",
|
|
name: "Charmeleon",
|
|
img: "http://www.serebii.net/pokemongo/pokemon/005.png",
|
|
},
|
|
{
|
|
id: 6,
|
|
num: "006",
|
|
name: "Charizard",
|
|
img: "http://www.serebii.net/pokemongo/pokemon/006.png",
|
|
},
|
|
],
|
|
widgetName: "List",
|
|
children: [],
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "CANVAS_WIDGET",
|
|
position: { top: 0, left: 0 },
|
|
props: {
|
|
containerStyle: "none",
|
|
canExtend: false,
|
|
detachFromLayout: true,
|
|
dropDisabled: true,
|
|
noPad: true,
|
|
children: [],
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "CONTAINER_WIDGET",
|
|
size: { rows: 4, cols: 16 },
|
|
position: { top: 0, left: 0 },
|
|
props: {
|
|
backgroundColor: "white",
|
|
containerStyle: "card",
|
|
dragDisabled: true,
|
|
isDeletable: false,
|
|
disallowCopy: true,
|
|
disablePropertyPane: true,
|
|
children: [],
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "CANVAS_WIDGET",
|
|
position: { top: 0, left: 0 },
|
|
props: {
|
|
containerStyle: "none",
|
|
canExtend: false,
|
|
detachFromLayout: true,
|
|
children: [],
|
|
version: 1,
|
|
blueprint: {
|
|
view: [
|
|
{
|
|
type: "IMAGE_WIDGET",
|
|
size: { rows: 3, cols: 4 },
|
|
position: { top: 0, left: 0 },
|
|
props: {
|
|
defaultImage:
|
|
"https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png",
|
|
imageShape: "RECTANGLE",
|
|
maxZoomLevel: 1,
|
|
image: "{{currentItem.img}}",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "image",
|
|
},
|
|
],
|
|
dynamicTriggerPathList: [],
|
|
},
|
|
},
|
|
{
|
|
type: "TEXT_WIDGET",
|
|
size: { rows: 1, cols: 6 },
|
|
position: { top: 0, left: 4 },
|
|
props: {
|
|
text: "{{currentItem.name}}",
|
|
textStyle: "HEADING",
|
|
textAlign: "LEFT",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "text",
|
|
},
|
|
],
|
|
dynamicTriggerPathList: [],
|
|
},
|
|
},
|
|
{
|
|
type: "TEXT_WIDGET",
|
|
size: { rows: 1, cols: 6 },
|
|
position: { top: 1, left: 4 },
|
|
props: {
|
|
text: "{{currentItem.num}}",
|
|
textStyle: "BODY",
|
|
textAlign: "LEFT",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "text",
|
|
},
|
|
],
|
|
dynamicTriggerPathList: [],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
operations: [
|
|
{
|
|
type: BlueprintOperationTypes.MODIFY_PROPS,
|
|
fn: (
|
|
widget: WidgetProps & { children?: WidgetProps[] },
|
|
widgets: { [widgetId: string]: FlattenedWidgetProps },
|
|
) => {
|
|
let template = {};
|
|
const container = get(
|
|
widgets,
|
|
`${get(widget, "children.0.children.0")}`,
|
|
);
|
|
const canvas = get(widgets, `${get(container, "children.0")}`);
|
|
let updatePropertyMap: any = [];
|
|
const dynamicBindingPathList: any[] = get(
|
|
widget,
|
|
"dynamicBindingPathList",
|
|
[],
|
|
);
|
|
|
|
canvas.children &&
|
|
get(canvas, "children", []).forEach((child: string) => {
|
|
const childWidget = cloneDeep(get(widgets, `${child}`));
|
|
const keys = Object.keys(childWidget);
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
|
const key = keys[i];
|
|
let value = childWidget[key];
|
|
|
|
if (isString(value) && value.indexOf("currentItem") > -1) {
|
|
const { jsSnippets } = getDynamicBindings(value);
|
|
|
|
const modifiedAction = jsSnippets.reduce(
|
|
(prev: string, next: string) => {
|
|
return prev + `${next}`;
|
|
},
|
|
"",
|
|
);
|
|
|
|
value = `{{${widget.widgetName}.items.map((currentItem) => ${modifiedAction})}}`;
|
|
|
|
childWidget[key] = value;
|
|
|
|
dynamicBindingPathList.push({
|
|
key: `template.${childWidget.widgetName}.${key}`,
|
|
});
|
|
}
|
|
}
|
|
|
|
template = {
|
|
...template,
|
|
[childWidget.widgetName]: childWidget,
|
|
};
|
|
});
|
|
|
|
updatePropertyMap = [
|
|
{
|
|
widgetId: widget.widgetId,
|
|
propertyName: "dynamicBindingPathList",
|
|
propertyValue: dynamicBindingPathList,
|
|
},
|
|
{
|
|
widgetId: widget.widgetId,
|
|
propertyName: "template",
|
|
propertyValue: template,
|
|
},
|
|
];
|
|
return updatePropertyMap;
|
|
},
|
|
},
|
|
{
|
|
type: BlueprintOperationTypes.CHILD_OPERATIONS,
|
|
fn: (
|
|
widgets: { [widgetId: string]: FlattenedWidgetProps },
|
|
widgetId: string,
|
|
parentId: string,
|
|
widgetPropertyMaps: {
|
|
defaultPropertyMap: Record<string, string>;
|
|
},
|
|
) => {
|
|
if (!parentId) return { widgets };
|
|
const widget = { ...widgets[widgetId] };
|
|
const parent = { ...widgets[parentId] };
|
|
|
|
const disallowedWidgets = [WidgetTypes.FILE_PICKER_WIDGET];
|
|
|
|
if (
|
|
Object.keys(widgetPropertyMaps.defaultPropertyMap).length > 0 ||
|
|
indexOf(disallowedWidgets, widget.type) > -1
|
|
) {
|
|
const widget = widgets[widgetId];
|
|
if (widget.children && widget.children.length > 0) {
|
|
widget.children.forEach((childId: string) => {
|
|
delete widgets[childId];
|
|
});
|
|
}
|
|
if (widget.parentId) {
|
|
const _parent = { ...widgets[widget.parentId] };
|
|
_parent.children = _parent.children?.filter(
|
|
(id) => id !== widgetId,
|
|
);
|
|
widgets[widget.parentId] = _parent;
|
|
}
|
|
delete widgets[widgetId];
|
|
|
|
return {
|
|
widgets,
|
|
message: `${
|
|
WidgetConfigResponse.config[widget.type].widgetName
|
|
} widgets cannot be used inside the list widget right now.`,
|
|
};
|
|
}
|
|
|
|
const template = {
|
|
...get(parent, "template", {}),
|
|
[widget.widgetName]: widget,
|
|
};
|
|
|
|
parent.template = template;
|
|
|
|
widgets[parentId] = parent;
|
|
|
|
return { widgets };
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
configVersion: 1,
|
|
};
|
|
|
|
export default WidgetConfigResponse;
|