PromucFlow_constructor/app/client/src/components/propertyControls/ChartDataControl.tsx

294 lines
7.7 KiB
TypeScript
Raw Normal View History

2020-04-15 11:42:11 +00:00
import React from "react";
import { get, isString } from "lodash";
2020-04-15 11:42:11 +00:00
import BaseControl, { ControlProps } from "./BaseControl";
2020-06-10 12:16:50 +00:00
import { ControlWrapper, StyledPropertyPaneButton } from "./StyledControls";
2020-04-15 11:42:11 +00:00
import styled from "constants/DefaultTheme";
import { FormIcons } from "icons/FormIcons";
import { AnyStyledComponent } from "styled-components";
fix: Improve CodeMirror rendering performance using idleCallback (#13676) * working editor wrapper * updated other property controls * fix tablefilter_spec unit test * autofocus on editor * update font styles * show lint errors * add syntax highlighting * fix import issue * fix input height * use lazy and suspense * wip * update code clean up * update input style * fix select widget issue * fix build issue * fix import issue and linting css * update lint error method * add polyfill for idle callback * fix undo aggregate helper changes * rename CodeEditor component * fix tests add delay before code mirror * undo name change * rename lazy editor * add comments and update aggregate helper * fix cypress helper * fix testJsonText command * update aggregate helper * add wait to allow time to load * fix filepicker issue * fix currency input test * fix unit tests * update aggregate helper * fix table property tests * fix test * fix command * update json text command * updated command ii * update iii * update iv * add force click * check for wrapper * fix for objects * fix test iv * fix test v * fix tests vi * fix tests vi * fix variable naming issue * fix tests vii * remove wait from wrapper click * fix tests viii * fix recheck wrapper availability * fix updateCodeInput command * fix undo while loop * fix ix * fix each loop * removed EnableAllCodeEditors * updated tests * Upated wait * updated some more tests * updated wait time * updated common method * updated all related common methods * update state name and add callback timeout * updated test * updated the test * fix use while loop and update count * update click func * fix use get instead of find * fix on click action command * remove comments * fix: update import statements * add force click to widget command * update wrapper ui * fix auto load code editor * update editor wrapper ui * fix lineheight adjustment * refactor editor wrapper * update style import * fix ascetic style import * fix font style * fix wrapper height * update color for code block * fix min height of content wrapper * remove error linting and editor wrapper * remove unused variable * remove unused imports * fix font color for objects * update styles for placeholders * remove console log * remove react syntax highlighter * cancel idlecallback on unmount * Delay input foucs Co-authored-by: Aishwarya UR <aishwarya@appsmith.com> Co-authored-by: apple <nandan@thinkify.io> Co-authored-by: Satish Gandham <satish@appsmith.com>
2022-07-20 09:26:12 +00:00
import { CodeEditorExpected } from "components/editorComponents/CodeEditor";
import {
EditorModes,
EditorSize,
EditorTheme,
TabBehaviour,
} from "components/editorComponents/CodeEditor/EditorConfig";
feat: Migrate design system components import to design-system repo - I (#15562) * Icon component deleted and changed the imports in refrence places * design system package version changed * import changes * Delete TextInput.tsx * Change imports * Change single named import * Update package * Update package * Delete ScrollIndicator.tsx * Change imports * Icon import completed * Event type added * Changed Button component imports * import change button * Button onclick type fix * Label with Tooltip import changes * Changed breadcrumbs import * EmojiPicker and Emoji Reaction import changes * AppIcon import change * import bug fix * Menu Item import chnages * Icon selector imports changed * Delete LabelWithTooltip.tsx * Change imports across the app * Update package version * Update version number for design-system * Delete Checkbox.tsx * Remove the exports * Add lock file for ds package update * Change imports * default import -> named * Update release version * Make arg type explicit * Updated design-system to latest release * Missing file mysteriously comes back and is updated accordingly * changes design-system package version * Add types to arguments in the onChange for text input * onBlur type fix * Search component in property pane * WDS button changes reverted * package version bumped * conflict fix * Remove Dropdown, change imports * Category import fix * fix: table icon size import * Bump version of design system package * Yarn lock Co-authored-by: Tanvi Bhakta <tanvibhakta@gmail.com>
2022-08-22 05:09:39 +00:00
import { Size, Category } from "design-system";
import { AllChartData, ChartData } from "widgets/ChartWidget/constants";
import { generateReactKey } from "utils/generators";
import { AutocompleteDataType } from "utils/autocomplete/CodemirrorTernService";
fix: Improve CodeMirror rendering performance using idleCallback (#13676) * working editor wrapper * updated other property controls * fix tablefilter_spec unit test * autofocus on editor * update font styles * show lint errors * add syntax highlighting * fix import issue * fix input height * use lazy and suspense * wip * update code clean up * update input style * fix select widget issue * fix build issue * fix import issue and linting css * update lint error method * add polyfill for idle callback * fix undo aggregate helper changes * rename CodeEditor component * fix tests add delay before code mirror * undo name change * rename lazy editor * add comments and update aggregate helper * fix cypress helper * fix testJsonText command * update aggregate helper * add wait to allow time to load * fix filepicker issue * fix currency input test * fix unit tests * update aggregate helper * fix table property tests * fix test * fix command * update json text command * updated command ii * update iii * update iv * add force click * check for wrapper * fix for objects * fix test iv * fix test v * fix tests vi * fix tests vi * fix variable naming issue * fix tests vii * remove wait from wrapper click * fix tests viii * fix recheck wrapper availability * fix updateCodeInput command * fix undo while loop * fix ix * fix each loop * removed EnableAllCodeEditors * updated tests * Upated wait * updated some more tests * updated wait time * updated common method * updated all related common methods * update state name and add callback timeout * updated test * updated the test * fix use while loop and update count * update click func * fix use get instead of find * fix on click action command * remove comments * fix: update import statements * add force click to widget command * update wrapper ui * fix auto load code editor * update editor wrapper ui * fix lineheight adjustment * refactor editor wrapper * update style import * fix ascetic style import * fix font style * fix wrapper height * update color for code block * fix min height of content wrapper * remove error linting and editor wrapper * remove unused variable * remove unused imports * fix font color for objects * update styles for placeholders * remove console log * remove react syntax highlighter * cancel idlecallback on unmount * Delay input foucs Co-authored-by: Aishwarya UR <aishwarya@appsmith.com> Co-authored-by: apple <nandan@thinkify.io> Co-authored-by: Satish Gandham <satish@appsmith.com>
2022-07-20 09:26:12 +00:00
import CodeEditor from "components/editorComponents/LazyCodeEditorWrapper";
const Wrapper = styled.div`
background-color: ${(props) =>
props.theme.colors.propertyPane.dropdownSelectBg};
padding: 0 8px;
`;
2020-04-15 11:42:11 +00:00
const StyledOptionControlWrapper = styled(ControlWrapper)`
display: flex;
justify-content: flex-start;
padding: 0;
width: 100%;
`;
const StyledDynamicInput = styled.div`
width: 100%;
&&& {
input {
border: none;
2020-12-24 04:32:25 +00:00
color: ${(props) => props.theme.colors.textOnDarkBG};
background: ${(props) => props.theme.colors.paneInputBG};
2020-04-15 11:42:11 +00:00
&:focus {
border: none;
2020-12-24 04:32:25 +00:00
color: ${(props) => props.theme.colors.textOnDarkBG};
background: ${(props) => props.theme.colors.paneInputBG};
2020-04-15 11:42:11 +00:00
}
}
}
`;
const StyledDeleteIcon = styled(FormIcons.DELETE_ICON as AnyStyledComponent)`
padding: 0;
position: relative;
margin-left: 15px;
cursor: pointer;
&&& svg {
path {
fill: ${(props) => props.theme.colors.propertyPane.jsIconBg};
}
}
`;
const ActionHolder = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
`;
const StyledLabel = styled.label`
margin: 8px auto 8px 0;
&& {
color: ${(props) => props.theme.colors.propertyPane.label};
}
`;
const Box = styled.div`
height: 16px;
2020-04-15 11:42:11 +00:00
`;
type RenderComponentProps = {
index: string;
item: ChartData;
length: number;
dataTreePath: string;
deleteOption: (index: string) => void;
updateOption: (index: string, key: string, value: string) => void;
2020-06-05 16:20:23 +00:00
evaluated: {
seriesName: string;
data: Array<{ x: string; y: string }> | any;
};
theme: EditorTheme;
2020-04-15 11:42:11 +00:00
};
const expectedSeriesName: CodeEditorExpected = {
type: "string",
example: "series1",
autocompleteDataType: AutocompleteDataType.STRING,
};
const expectedSeriesData: CodeEditorExpected = {
2021-12-17 06:19:44 +00:00
type: "Array<{ x: string, y: number Required }>",
example: [
{
x: "Mon",
y: 10000,
},
],
autocompleteDataType: AutocompleteDataType.ARRAY,
};
2020-04-15 11:42:11 +00:00
function DataControlComponent(props: RenderComponentProps) {
2020-06-05 16:20:23 +00:00
const {
dataTreePath,
2020-06-05 16:20:23 +00:00
deleteOption,
evaluated,
2020-06-05 16:20:23 +00:00
index,
item,
2020-06-05 16:20:23 +00:00
length,
updateOption,
2020-06-05 16:20:23 +00:00
} = props;
2020-04-15 11:42:11 +00:00
return (
<StyledOptionControlWrapper orientation={"VERTICAL"}>
<ActionHolder>
2021-03-17 11:34:53 +00:00
<StyledLabel>Series Title</StyledLabel>
{length > 1 && (
<StyledDeleteIcon
height={20}
onClick={() => {
deleteOption(index);
}}
width={20}
/>
)}
</ActionHolder>
2020-04-29 10:29:02 +00:00
<StyledOptionControlWrapper orientation={"HORIZONTAL"}>
<CodeEditor
dataTreePath={`${dataTreePath}.seriesName`}
evaluatedValue={evaluated?.seriesName}
expected={expectedSeriesName}
2020-06-05 16:20:23 +00:00
input={{
value: item.seriesName,
onChange: (
event: React.ChangeEvent<HTMLTextAreaElement> | string,
) => {
let value: string = event as string;
2020-06-05 16:20:23 +00:00
if (typeof event !== "string") {
value = event.target.value;
}
updateOption(index, "seriesName", value);
},
2020-04-29 10:29:02 +00:00
}}
mode={EditorModes.TEXT_WITH_BINDING}
2020-06-05 16:20:23 +00:00
placeholder="Series Name"
size={EditorSize.EXTENDED}
tabBehaviour={TabBehaviour.INPUT}
theme={props.theme}
2020-04-29 10:29:02 +00:00
/>
</StyledOptionControlWrapper>
<StyledLabel>Series Data</StyledLabel>
2020-06-05 16:20:23 +00:00
<StyledDynamicInput
className={"t--property-control-chart-series-data-control"}
>
<CodeEditor
dataTreePath={`${dataTreePath}.data`}
evaluatedValue={evaluated?.data}
expected={expectedSeriesData}
2020-04-15 11:42:11 +00:00
input={{
value: item.data,
onChange: (
event: React.ChangeEvent<HTMLTextAreaElement> | string,
) => {
let value: string = event as string;
2020-04-15 11:42:11 +00:00
if (typeof event !== "string") {
value = event.target.value;
}
updateOption(index, "data", value);
},
}}
mode={EditorModes.JSON_WITH_BINDING}
2020-04-15 11:42:11 +00:00
placeholder=""
size={EditorSize.EXTENDED}
tabBehaviour={TabBehaviour.INPUT}
theme={props.theme}
2020-04-15 11:42:11 +00:00
/>
</StyledDynamicInput>
<Box />
2020-04-15 11:42:11 +00:00
</StyledOptionControlWrapper>
);
}
class ChartDataControl extends BaseControl<ControlProps> {
render() {
const chartData: AllChartData = isString(this.props.propertyValue)
? {}
: this.props.propertyValue;
const dataLength = Object.keys(chartData).length;
const evaluatedValue = this.props.evaluatedValue;
const firstKey = Object.keys(chartData)[0] as string;
if (this.props.widgetProperties.chartType === "PIE_CHART") {
const data = dataLength
? get(chartData, `${firstKey}`)
: {
seriesName: "",
data: [],
};
return (
<DataControlComponent
dataTreePath={`${this.props.dataTreePath}.${firstKey}`}
deleteOption={this.deleteOption}
evaluated={get(evaluatedValue, `${firstKey}`)}
index={firstKey}
item={data}
length={1}
theme={this.props.theme}
updateOption={this.updateOption}
/>
);
}
2020-04-15 11:42:11 +00:00
return (
<>
<Wrapper>
{Object.keys(chartData).map((key: string) => {
const data = get(chartData, `${key}`);
return (
<DataControlComponent
dataTreePath={`${this.props.dataTreePath}.${key}`}
deleteOption={this.deleteOption}
evaluated={get(evaluatedValue, `${key}`)}
index={key}
item={data}
key={key}
length={dataLength}
theme={this.props.theme}
updateOption={this.updateOption}
/>
);
})}
</Wrapper>
2020-04-15 11:42:11 +00:00
<StyledPropertyPaneButton
category={Category.tertiary}
2020-04-15 11:42:11 +00:00
icon="plus"
onClick={this.addOption}
size={Size.medium}
tag="button"
text="Add Series"
type="button"
2020-04-15 11:42:11 +00:00
/>
</>
2020-04-15 11:42:11 +00:00
);
}
deleteOption = (index: string) => {
this.deleteProperties([`${this.props.propertyName}.${index}`]);
2020-04-15 11:42:11 +00:00
};
updateOption = (
index: string,
2020-04-15 11:42:11 +00:00
propertyName: string,
updatedValue: string,
) => {
this.updateProperty(
`${this.props.propertyName}.${index}.${propertyName}`,
updatedValue,
);
2020-04-15 11:42:11 +00:00
};
/**
* it adds new series data object in the chartData
*/
2020-04-15 11:42:11 +00:00
addOption = () => {
const randomString = generateReactKey();
this.updateProperty(`${this.props.propertyName}.${randomString}`, {
seriesName: "",
data: JSON.stringify([{ x: "label", y: 50 }]),
});
2020-04-15 11:42:11 +00:00
};
static getControlType() {
return "CHART_DATA";
}
}
export default ChartDataControl;