Merge branch 'release' into fix/4134-table-filter-case-insensitive

This commit is contained in:
Paul Li 2021-04-29 06:04:05 -04:00
commit 6d9d7d94bf
429 changed files with 4598 additions and 4495 deletions

View File

@ -28,7 +28,13 @@
"react/prop-types": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"cypress/no-unnecessary-waiting": 0,
"cypress/no-assigning-return-values": 0
"cypress/no-assigning-return-values": 0,
"react/function-component-definition": "warn",
"react/jsx-boolean-value": "error",
"react/self-closing-comp": "error",
"react/jsx-sort-props": "error",
"react/jsx-fragments": "error",
"react/jsx-no-useless-fragment": "error"
},
"settings": {
"react": {

View File

@ -137,6 +137,27 @@
"parentId": "qrqizehc5b",
"widgetId": "672gf8vm2q",
"dynamicBindingPathList": []
},
{
"defaultOptionValue": "",
"dynamicBindingPathList": [],
"dynamicTriggerPathList": [],
"isLoading": false,
"isVisible": true,
"label": "",
"options": "[\n {\n \"label\": \"Option 1\",\n \"value\": \"1\"\n },\n {\n \"label\": \"Option 2\",\n \"value\": \"2\"\n },\n {\n \"label\": \"Option 3\",\n \"value\": \"3\"\n },\n {\n \"label\": \"Option 4\",\n \"value\": \"4\"\n },\n {\n \"label\": \"Option 5\",\n \"value\": \"5\"\n }\n]",
"parentId": "qrqizehc5b",
"parentColumnSpace": 71.5,
"parentRowSpace": 40,
"selectionType": "MULTI_SELECT",
"leftColumn": 6,
"rightColumn": 16,
"topRow": 9,
"bottomRow": 10,
"type": "DROP_DOWN_WIDGET",
"version": 1,
"widgetId": "dwh49bulj9",
"widgetName": "Dropdown1"
}
],
"blueprint": {

View File

@ -4,6 +4,7 @@ const pages = require("../../../../locators/Pages.json");
const apiPage = require("../../../../locators/ApiEditor.json");
const publishPage = require("../../../../locators/publishWidgetspage.json");
const testdata = require("../../../../fixtures/testdata.json");
const widgetsPage = require("../../../../locators/Widgets.json");
describe("Test Create Api and Bind to Table widget", function() {
before(() => {
@ -41,6 +42,37 @@ describe("Test Create Api and Bind to Table widget", function() {
cy.closePropertyPane();
});
it("Check Image alignment is working as expected", function() {
cy.SearchEntityandOpen("Table1");
cy.editColumn("avatar");
cy.changeColumnType("Image");
cy.closePropertyPane();
cy.SearchEntityandOpen("Table1");
cy.get(widgetsPage.centerAlign)
.first()
.click({ force: true });
cy.closePropertyPane();
cy.get(`.t--widget-tablewidget .tbody .image-cell`)
.first()
.should("have.css", "background-position", "50% 50%");
cy.SearchEntityandOpen("Table1");
cy.get(widgetsPage.rightAlign)
.first()
.click({ force: true });
cy.closePropertyPane();
cy.get(`.t--widget-tablewidget .tbody .image-cell`)
.first()
.should("have.css", "background-position", "100% 50%");
cy.SearchEntityandOpen("Table1");
cy.get(widgetsPage.leftAlign)
.first()
.click({ force: true });
cy.closePropertyPane();
cy.get(`.t--widget-tablewidget .tbody .image-cell`)
.first()
.should("have.css", "background-position", "0% 50%");
});
it("Update table json data and check the derived column values after update", function() {
cy.SearchEntityandOpen("Table1");
cy.tableColumnDataValidation("id");

View File

@ -15,7 +15,6 @@ describe("Dropdown Widget Functionality", function() {
cy.testJsontext("options", JSON.stringify(data.input));
cy.testJsontext("defaultoption", "{{ undefined }}");
cy.get(formWidgetsPage.dropdownWidget)
.find(widgetLocators.dropdownSingleSelect)
.click({ force: true });
@ -27,6 +26,13 @@ describe("Dropdown Widget Functionality", function() {
.find(widgetLocators.defaultSingleSelectValue)
.should("have.text", "Option 3");
});
it("Selects value with enter in default value", () => {
// cy.openPropertyPane("dropdownwidget");
cy.testJsontext("defaultoption", "3\n");
cy.get(formWidgetsPage.dropdownWidget)
.find(widgetLocators.defaultSingleSelectValue)
.should("have.text", "Option 3");
});
it("Dropdown Widget Functionality", function() {
cy.widgetText(
"lock",

View File

@ -12,6 +12,12 @@ describe("Form reset functionality", function() {
.click()
.should("have.class", "selected-row");
cy.get(".t--draggable-dropdownwidget").click({ force: true });
cy.get(".t--draggable-dropdownwidget").type("Option");
cy.dropdownDynamic("Option 1");
cy.dropdownDynamic("Option 2");
cy.dropdownDynamic("Option 3");
cy.get(widgetsPage.inputWidget + " " + "input")
.invoke("attr", "value")
.should("contain", "lindsay.ferguson@reqres.in");
@ -26,6 +32,12 @@ describe("Form reset functionality", function() {
.eq(2)
.should("not.have.class", "selected-row");
cy.get(".t-draggable-dropdownwidget .bp3-tag-input-values .bp3-tag").should(
($span) => {
expect($span).to.have.length(0);
},
);
cy.get(widgetsPage.inputWidget + " " + "input")
.invoke("attr", "value")
.should("not.contain", "lindsay.ferguson@reqres.in");

View File

@ -51,7 +51,7 @@ class AppErrorBoundary extends Component {
if (this.state.hasError) {
return (
<Wrapper>
<img src={AppCrashImage} alt="App crashed" />
<img alt="App crashed" src={AppCrashImage} />
<div>
<p className="bold-text">Oops! Something went wrong</p>
<p>

View File

@ -90,24 +90,24 @@ class AppRouter extends React.Component<any, any> {
<>
<AppHeader />
<Switch>
<SentryRoute exact path={BASE_URL} component={LandingScreen} />
<SentryRoute component={LandingScreen} exact path={BASE_URL} />
<Redirect exact from={BASE_LOGIN_URL} to={AUTH_LOGIN_URL} />
<Redirect exact from={BASE_SIGNUP_URL} to={SIGN_UP_URL} />
<SentryRoute path={ORG_URL} component={OrganizationLoader} />
<SentryRoute exact path={USERS_URL} component={Users} />
<SentryRoute path={USER_AUTH_URL} component={UserAuth} />
<SentryRoute component={OrganizationLoader} path={ORG_URL} />
<SentryRoute component={Users} exact path={USERS_URL} />
<SentryRoute component={UserAuth} path={USER_AUTH_URL} />
<SentryRoute
component={ApplicationListLoader}
exact
path={APPLICATIONS_URL}
component={ApplicationListLoader}
/>
<SentryRoute path={BUILDER_URL} component={EditorLoader} />
<SentryRoute component={EditorLoader} path={BUILDER_URL} />
<SentryRoute
path={getApplicationViewerPageURL()}
component={AppViewerLoader}
path={getApplicationViewerPageURL()}
/>
<SentryRoute exact path={PROFILE} component={UserProfile} />
<SentryRoute path={APP_VIEW_URL} component={AppViewerLoader} />
<SentryRoute component={UserProfile} exact path={PROFILE} />
<SentryRoute component={AppViewerLoader} path={APP_VIEW_URL} />
<SentryRoute component={PageNotFound} />
</Switch>
</>

View File

@ -13,7 +13,7 @@ type Props = {
authError: string;
};
const LandingScreen = (props: Props) => {
function LandingScreen(props: Props) {
if (props.user && window.location.pathname === BASE_URL) {
if (props.user.email === ANONYMOUS_USERNAME) {
return <Redirect to={AUTH_LOGIN_URL} />;
@ -25,7 +25,7 @@ const LandingScreen = (props: Props) => {
return <ServerUnavailable />;
}
return <PageLoadingBar />;
};
}
const mapStateToProps = (state: AppState) => ({
user: getCurrentUser(state),

View File

@ -223,7 +223,7 @@ export type AppIconProps = CommonComponentProps & {
name: AppIconName;
};
const AppIcon = (props: AppIconProps) => {
function AppIcon(props: AppIconProps) {
const styledProps = useMemo(() => appSizeHandler(props.size || Size.medium), [
props,
]);
@ -484,6 +484,6 @@ const AppIcon = (props: AppIconProps) => {
{returnIcon}
</IconWrapper>
) : null;
};
}
export default AppIcon;

View File

@ -376,13 +376,13 @@ const IconSizeProp = (size?: Size) => {
return size ? sizeMapping[size] : IconSize.SMALL;
};
const TextLoadingState = ({ text }: { text?: string }) => (
<VisibilityWrapper>{text}</VisibilityWrapper>
);
function TextLoadingState({ text }: { text?: string }) {
return <VisibilityWrapper>{text}</VisibilityWrapper>;
}
const IconLoadingState = ({ size, icon }: { size?: Size; icon?: IconName }) => (
<Icon name={icon} size={IconSizeProp(size)} invisible />
);
function IconLoadingState({ size, icon }: { size?: Size; icon?: IconName }) {
return <Icon invisible name={icon} size={IconSizeProp(size)} />;
}
const getIconContent = (props: ButtonProps) =>
props.icon ? (
@ -410,39 +410,44 @@ const getButtonContent = (props: ButtonProps) => (
</>
);
const ButtonComponent = (props: ButtonProps) => (
<StyledButton
className={props.className}
data-cy={props.cypressSelector}
{...props}
onClick={(e: React.MouseEvent<HTMLElement>) =>
props.onClick && props.onClick(e)
}
>
{getButtonContent(props)}
</StyledButton>
);
function ButtonComponent(props: ButtonProps) {
return (
<StyledButton
className={props.className}
data-cy={props.cypressSelector}
{...props}
onClick={(e: React.MouseEvent<HTMLElement>) =>
props.onClick && props.onClick(e)
}
>
{getButtonContent(props)}
</StyledButton>
);
}
const LinkButtonComponent = (props: ButtonProps) => (
<StyledLinkButton
href={props.href}
className={props.className}
data-cy={props.cypressSelector}
{...props}
onClick={(e: React.MouseEvent<HTMLElement>) =>
props.onClick && props.onClick(e)
}
>
{getButtonContent(props)}
</StyledLinkButton>
);
function LinkButtonComponent(props: ButtonProps) {
return (
<StyledLinkButton
className={props.className}
data-cy={props.cypressSelector}
href={props.href}
{...props}
onClick={(e: React.MouseEvent<HTMLElement>) =>
props.onClick && props.onClick(e)
}
>
{getButtonContent(props)}
</StyledLinkButton>
);
}
const Button = (props: ButtonProps) =>
props.tag === "button" ? (
function Button(props: ButtonProps) {
return props.tag === "button" ? (
<ButtonComponent {...props} />
) : (
<LinkButtonComponent {...props} />
);
}
export default Button;

View File

@ -41,7 +41,7 @@ interface ButtonTabComponentProps {
selectButton: (value: string) => void;
}
const ButtonTabComponent = (props: ButtonTabComponentProps) => {
function ButtonTabComponent(props: ButtonTabComponentProps) {
return (
<FlexWrapper>
{props.options.map((option: ButtonTabOption, index: number) => {
@ -50,17 +50,17 @@ const ButtonTabComponent = (props: ButtonTabComponentProps) => {
const isSelected = props.values.includes(option.value);
return (
<ItemWrapper
key={index}
selected={isSelected}
onClick={() => props.selectButton(option.value)}
className={`t--button-tab-${option.value}`}
key={index}
onClick={() => props.selectButton(option.value)}
selected={isSelected}
>
<ControlIcon width={24} height={24} />
<ControlIcon height={24} width={24} />
</ItemWrapper>
);
})}
</FlexWrapper>
);
};
}
export default ButtonTabComponent;

View File

@ -73,14 +73,14 @@ Callout.defaultProps = {
function Callout(props: CalloutProps) {
return (
<CalloutContainer variant={props.variant || Variant.info} fill={props.fill}>
<CalloutContainer fill={props.fill} variant={props.variant || Variant.info}>
{props.text && props.variant !== Variant.info ? (
<Icon name={props.variant} size={IconSize.MEDIUM} />
) : null}
<Text type={TextType.P2}>{props.text}</Text>
{props.label ? props.label : null}
{props.closeButton ? (
<Label variant={props.variant || Variant.info} onClick={props.onClose}>
<Label onClick={props.onClose} variant={props.variant || Variant.info}>
<Icon name="close-modal" />
</Label>
) : null}

View File

@ -106,7 +106,7 @@ const useUpdate = (intitialValue?: boolean) => {
return [checked, setChecked] as const;
};
const Checkbox = (props: CheckboxProps) => {
function Checkbox(props: CheckboxProps) {
const [checked, setChecked] = useUpdate(props.isDefaultChecked);
const onChangeHandler = (checked: boolean) => {
@ -121,20 +121,20 @@ const Checkbox = (props: CheckboxProps) => {
{props.info ? <Text type={TextType.P3}>{props.info}</Text> : null}
</LabelContainer>
<input
type="checkbox"
disabled={props.disabled}
checked={checked}
disabled={props.disabled}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
onChangeHandler(e.target.checked)
}
type="checkbox"
/>
<Checkmark
disabled={props.disabled}
isChecked={checked}
info={props.info}
isChecked={checked}
/>
</StyledCheckbox>
);
};
}
export default Checkbox;

View File

@ -93,14 +93,14 @@ const EmptyColorIconWrapper = styled.div`
}
`;
const ColorBoard = (props: ColorBoardProps) => {
function ColorBoard(props: ColorBoardProps) {
return (
<ColorsWrapper>
{defaultColors.map((color: string, index: number) => (
<ColorTab
key={index}
color={color}
className={Classes.POPOVER_DISMISS}
color={color}
key={index}
onClick={() => props.selectColor(color)}
>
{props.selectedColor === color && <CheckedIcon />}
@ -113,7 +113,7 @@ const ColorBoard = (props: ColorBoardProps) => {
</EmptyColorIconWrapper>
</ColorsWrapper>
);
};
}
const NoColorIconWrapper = styled.div`
position: absolute;
@ -148,7 +148,7 @@ interface ColorPickerProps {
changeColor: (color: string) => void;
}
const ColorPickerComponent = (props: ColorPickerProps) => {
function ColorPickerComponent(props: ColorPickerProps) {
const [color, setColor] = React.useState(props.color);
const debouncedOnChange = React.useCallback(
debounce(props.changeColor, 500),
@ -161,16 +161,16 @@ const ColorPickerComponent = (props: ColorPickerProps) => {
};
return (
<Popover
minimal
usePortal
enforceFocus={false}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM}
minimal
modifiers={{
offset: {
offset: "0, 24px",
},
}}
position={Position.BOTTOM}
usePortal
>
<StyledInputGroup
leftIcon={
@ -189,14 +189,14 @@ const ColorPickerComponent = (props: ColorPickerProps) => {
value={color}
/>
<ColorBoard
selectedColor={color}
selectColor={(color) => {
setColor(color);
props.changeColor(color);
}}
selectedColor={color}
/>
</Popover>
);
};
}
export default ColorPickerComponent;

View File

@ -56,7 +56,7 @@ const ColorBox = styled.div<{ selected: string; color: string }>`
`}
`;
const ColorSelector = (props: ColorSelectorProps) => {
function ColorSelector(props: ColorSelectorProps) {
const [selected, setSelected] = useState<string>(
props.defaultValue || props.colorPalette[0],
);
@ -68,28 +68,28 @@ const ColorSelector = (props: ColorSelectorProps) => {
}, [props.defaultValue]);
return (
<Palette fill={props.fill} data-cy={props.cypressSelector}>
<Palette data-cy={props.cypressSelector} fill={props.fill}>
{props.colorPalette.map((hex: string, index: number) => {
return (
<ColorBox
key={index}
selected={selected}
className={
selected === hex ? "t--color-selected" : "t--color-not-selected"
}
color={hex}
key={index}
onClick={() => {
if (selected !== hex) {
setSelected(hex);
props.onSelect && props.onSelect(hex);
}
}}
className={
selected === hex ? "t--color-selected" : "t--color-not-selected"
}
selected={selected}
/>
);
})}
</Palette>
);
};
}
ColorSelector.defaultProps = {
fill: false,

View File

@ -15,7 +15,7 @@ const Wrapper = styled.div`
}
`;
const CopyToClipboard = (props: any) => {
function CopyToClipboard(props: any) {
const { copyText } = props;
const copyURLInput = createRef<HTMLInputElement>();
const [isCopied, setIsCopied] = useState(false);
@ -36,25 +36,25 @@ const CopyToClipboard = (props: any) => {
return (
<Wrapper>
<TextInput
defaultValue={copyText}
fill
ref={copyURLInput}
readOnly
onChange={() => {
selectText();
}}
defaultValue={copyText}
readOnly
ref={copyURLInput}
/>
<Button
text={isCopied ? "Copied" : "Copy"}
category={Category.tertiary}
onClick={() => {
copyToClipboard(copyText);
}}
size={Size.large}
text={isCopied ? "Copied" : "Copy"}
/>
</Wrapper>
);
};
}
export default CopyToClipboard;

View File

@ -100,25 +100,25 @@ interface DatePickerComponentProps {
parseDate?: (dateStr: string) => Date;
}
const DatePickerComponent = (props: DatePickerComponentProps) => {
function DatePickerComponent(props: DatePickerComponentProps) {
return (
<StyledDateInput
className={Classes.DATE_PICKER_OVARLAY}
closeOnSelection={props.closeOnSelection}
formatDate={props.formatDate}
highlightCurrentDay={props.highlightCurrentDay}
maxDate={props.maxDate}
minDate={props.minDate}
onChange={props.onChange}
parseDate={props.parseDate}
placeholder={props.placeholder}
popoverProps={{ usePortal: true }}
showActionsBar={props.showActionsBar}
timePrecision={props.timePrecision}
closeOnSelection={props.closeOnSelection}
value={props.value}
highlightCurrentDay={props.highlightCurrentDay}
onChange={props.onChange}
formatDate={props.formatDate}
parseDate={props.parseDate}
className={Classes.DATE_PICKER_OVARLAY}
popoverProps={{ usePortal: true }}
/>
);
};
}
DatePickerComponent.defaultProps = {
highlightCurrentDay: true,

View File

@ -93,7 +93,7 @@ type DialogComponentProps = {
className?: string;
};
export const DialogComponent = (props: DialogComponentProps) => {
export function DialogComponent(props: DialogComponentProps) {
const [isOpen, setIsOpen] = useState(!!props.isOpen);
const onClose = () => {
@ -107,7 +107,7 @@ export const DialogComponent = (props: DialogComponentProps) => {
const getHeader = props.getHeader;
return (
<React.Fragment>
<>
<TriggerWrapper
className="ads-dialog-trigger"
onClick={() => {
@ -118,23 +118,23 @@ export const DialogComponent = (props: DialogComponentProps) => {
{props.trigger}
</TriggerWrapper>
<StyledDialog
canOutsideClickClose={!!props.canOutsideClickClose}
canEscapeKeyClose={!!props.canEscapeKeyClose}
title={props.title}
onClose={onClose}
isOpen={isOpen}
width={props.width}
setMaxWidth={props.setMaxWidth}
maxHeight={props.maxHeight}
onOpening={props.onOpening}
showHeaderUnderline={props.showHeaderUnderline}
canOutsideClickClose={!!props.canOutsideClickClose}
className={props.className}
isOpen={isOpen}
maxHeight={props.maxHeight}
onClose={onClose}
onOpening={props.onOpening}
setMaxWidth={props.setMaxWidth}
showHeaderUnderline={props.showHeaderUnderline}
title={props.title}
width={props.width}
>
{getHeader && getHeader()}
<div className={Classes.DIALOG_BODY}>{props.children}</div>
</StyledDialog>
</React.Fragment>
</>
);
};
}
export default DialogComponent;

View File

@ -59,7 +59,7 @@ const DraggableListWrapper = styled.div`
}
`;
const DraggableList = ({ items, ItemRenderer, onUpdate, itemHeight }: any) => {
function DraggableList({ items, ItemRenderer, onUpdate, itemHeight }: any) {
// order of items in the list
const order = useRef<any>(items.map((_: any, index: any) => index));
@ -111,12 +111,12 @@ const DraggableList = ({ items, ItemRenderer, onUpdate, itemHeight }: any) => {
});
return (
<DraggableListWrapper
className="content"
onMouseDown={() => {
// set events to null to stop other parent draggable elements execution(ex: Property pane)
document.onmouseup = null;
document.onmousemove = null;
}}
className="content"
style={{ height: items.length * itemHeight }}
>
{springs.map(({ zIndex, y, scale }, i) => (
@ -134,13 +134,13 @@ const DraggableList = ({ items, ItemRenderer, onUpdate, itemHeight }: any) => {
}}
>
<div>
<ItemRenderer item={items[i]} index={i} />
<ItemRenderer index={i} item={items[i]} />
</div>
</animated.div>
))}
</DraggableListWrapper>
);
};
}
DraggableList.displayName = "DraggableList";
export default DraggableList;

View File

@ -185,22 +185,24 @@ const SelectedIcon = styled(Icon)`
}
`;
const DefaultDropDownValueNode = ({
function DefaultDropDownValueNode({
selected,
showLabelOnly,
}: {
selected: DropdownOption;
showLabelOnly?: boolean;
}) => (
<SelectedDropDownHolder>
{selected.icon ? (
<SelectedIcon name={selected.icon} size={IconSize.XXS} />
) : null}
<Text type={TextType.P1}>
{showLabelOnly ? selected.label : selected.value}
</Text>
</SelectedDropDownHolder>
);
}) {
return (
<SelectedDropDownHolder>
{selected.icon ? (
<SelectedIcon name={selected.icon} size={IconSize.XXS} />
) : null}
<Text type={TextType.P1}>
{showLabelOnly ? selected.label : selected.value}
</Text>
</SelectedDropDownHolder>
);
}
export default function Dropdown(props: DropdownProps) {
const {
@ -226,25 +228,25 @@ export default function Dropdown(props: DropdownProps) {
);
return (
<DropdownContainer
tabIndex={0}
data-cy={props.cypressSelector}
width={props.width || "260px"}
height={props.height || "38px"}
tabIndex={0}
width={props.width || "260px"}
>
<Popover
boundary="scrollParent"
isOpen={isOpen && !props.disabled}
minimal
onInteraction={(state) => setIsOpen(state)}
popoverClassName={props.className}
position={Position.BOTTOM_LEFT}
isOpen={isOpen && !props.disabled}
onInteraction={(state) => setIsOpen(state)}
boundary="scrollParent"
>
<Selected
isOpen={isOpen}
disabled={props.disabled}
onClick={() => setIsOpen(!isOpen)}
className={props.className}
disabled={props.disabled}
height={props.height || "38px"}
isOpen={isOpen}
onClick={() => setIsOpen(!isOpen)}
>
<SelectedValueNode
selected={selected}
@ -256,15 +258,15 @@ export default function Dropdown(props: DropdownProps) {
{props.options.map((option: DropdownOption, index: number) => {
return (
<OptionWrapper
key={index}
selected={selected.value === option.value}
onClick={() => optionClickHandler(option)}
className="t--dropdown-option"
key={index}
onClick={() => optionClickHandler(option)}
selected={selected.value === option.value}
>
{option.icon ? (
<SelectedIcon
name={option.icon}
fillColor={option?.iconColor}
name={option.icon}
size={option.iconSize || IconSize.XXS}
/>
) : null}

View File

@ -152,7 +152,7 @@ const IconWrapper = styled.div`
justify-content: flex-end;
`;
export const EditableText = (props: EditableTextProps) => {
export function EditableText(props: EditableTextProps) {
const {
onBlur,
onTextChanged,
@ -268,36 +268,36 @@ export const EditableText = (props: EditableTextProps) => {
return (
<EditableTextWrapper
filled={!!props.fill}
onMouseEnter={nonEditMode}
onDoubleClick={
props.editInteractionKind === EditInteractionKind.DOUBLE
? editMode
: noop
}
onClick={
props.editInteractionKind === EditInteractionKind.SINGLE
? editMode
: noop
}
onDoubleClick={
props.editInteractionKind === EditInteractionKind.DOUBLE
? editMode
: noop
}
onMouseEnter={nonEditMode}
>
<TextContainer
bgColor={bgColor}
className="editable-text-container"
data-cy={props.cypressSelector}
isInvalid={!!isInvalid}
isEditing={isEditing}
bgColor={bgColor}
isInvalid={!!isInvalid}
underline={props.underline}
>
<BlueprintEditableText
className={props.className}
disabled={!isEditing}
isEditing={isEditing}
onCancel={onConfirm}
onChange={onInputchange}
onConfirm={onConfirm}
value={value}
selectAllOnFocus
placeholder={props.placeholder || defaultValue}
className={props.className}
onCancel={onConfirm}
selectAllOnFocus
value={value}
/>
{savingState === SavingState.STARTED ? (
@ -317,6 +317,6 @@ export const EditableText = (props: EditableTextProps) => {
) : null}
</EditableTextWrapper>
);
};
}
export default EditableText;

View File

@ -86,23 +86,16 @@ export default function EditableTextWrapper(props: EditableTextWrapperProps) {
return (
<Container
isEditing={isEditing}
savingState={props.savingState}
isInvalid={isValid}
savingState={props.savingState}
>
<EditableText
className={props.className}
defaultValue={props.defaultValue}
editInteractionKind={props.editInteractionKind}
placeholder={props.placeholder}
fill={!!props.fill}
hideEditIcon={props.hideEditIcon}
isEditingDefault={props.isNewApp}
savingState={props.savingState}
fill={!!props.fill}
onBlur={(value) => {
setIsEditing(false);
props.onBlur && props.onBlur(value);
}}
className={props.className}
onTextChanged={() => setIsEditing(true)}
isInvalid={(value: string) => {
setIsEditing(true);
if (props.isInvalid) {
@ -118,6 +111,13 @@ export default function EditableTextWrapper(props: EditableTextWrapperProps) {
return false;
}
}}
onBlur={(value) => {
setIsEditing(false);
props.onBlur && props.onBlur(value);
}}
onTextChanged={() => setIsEditing(true)}
placeholder={props.placeholder}
savingState={props.savingState}
/>
</Container>
);

View File

@ -158,7 +158,7 @@ export function CloudinaryUploader(
});
}
const FilePickerComponent = (props: FilePickerProps) => {
function FilePickerComponent(props: FilePickerProps) {
const { logoUploadError } = props;
const [fileInfo, setFileInfo] = useState<{ name: string; size: number }>({
name: "",
@ -293,64 +293,64 @@ const FilePickerComponent = (props: FilePickerProps) => {
return (
<ContainerDiv
isActive={isActive}
canDrop={canDrop}
isActive={isActive}
isUploaded={isUploaded}
ref={drop}
>
<div ref={bgRef} className="bg-image">
<div className="bg-image" ref={bgRef}>
<div className="button-wrapper" ref={fileContainerRef}>
<UploadIcon />
<Text type={TextType.P2} className="drag-drop-text">
<Text className="drag-drop-text" type={TextType.P2}>
Drag & Drop files to upload or
</Text>
<form>
<input
type="file"
accept=".jpeg,.png,.svg"
id="fileInput"
multiple={false}
ref={inputRef}
accept=".jpeg,.png,.svg"
value={""}
onChange={(el) => handleFileUpload(el.target.files)}
ref={inputRef}
type="file"
value={""}
/>
<Button
text="Browse"
category={Category.tertiary}
size={Size.medium}
onClick={(el) => ButtonClick(el)}
size={Size.medium}
text="Browse"
/>
</form>
</div>
<div className="file-description" ref={fileDescRef} id="fileDesc">
<div className="file-description" id="fileDesc" ref={fileDescRef}>
<div className="file-spec">
<Text type={TextType.H6}>{fileInfo.name}</Text>
<Text type={TextType.H6}>{fileInfo.size}KB</Text>
</div>
<div className="progress-container">
<div className="progress-inner" ref={progressRef}></div>
<div className="progress-inner" ref={progressRef} />
</div>
</div>
</div>
<div className="remove-button">
<Button
text="remove"
icon="delete"
size={Size.medium}
category={Category.tertiary}
icon="delete"
onClick={() => removeFile()}
size={Size.medium}
text="remove"
/>
</div>
</ContainerDiv>
);
};
}
const FilePicker = (props: FilePickerProps) => {
function FilePicker(props: FilePickerProps) {
return (
<DndProvider backend={HTML5Backend}>
<FilePickerComponent {...props} />
</DndProvider>
);
};
}
export default FilePicker;

View File

@ -52,24 +52,20 @@ const Overlay = styled.div`
transition: 0.5s ease;
`;
const GifPlayerComponent = (props: GifPlayerProps) => {
function GifPlayerComponent(props: GifPlayerProps) {
const [startGif, setStartGif] = useState(false);
return (
<React.Fragment>
{!startGif ? (
<ThumnailContainer onClick={() => setStartGif(!startGif)}>
<Overlay />
<img src={props.thumbnail} />
<PlayButton>
<Icon name="play" size={IconSize.XXXL} />
<Text type={TextType.P3}>Click to play</Text>
</PlayButton>
</ThumnailContainer>
) : (
<img src={props.gif} />
)}
</React.Fragment>
return !startGif ? (
<ThumnailContainer onClick={() => setStartGif(!startGif)}>
<Overlay />
<img src={props.thumbnail} />
<PlayButton>
<Icon name="play" size={IconSize.XXXL} />
<Text type={TextType.P3}>Click to play</Text>
</PlayButton>
</ThumnailContainer>
) : (
<img src={props.gif} />
);
};
}
export default GifPlayerComponent;

View File

@ -364,7 +364,7 @@ const Icon = forwardRef(
case "PARAGRAPH":
case "PARAGRAPH_TWO":
const ControlIcon = ControlIcons[props.name];
returnIcon = <ControlIcon width={24} height={24} />;
returnIcon = <ControlIcon height={24} width={24} />;
break;
default:

View File

@ -58,7 +58,7 @@ const IconBox = styled.div<{ selectedColor?: string }>`
: null};
`;
const IconSelector = (props: IconSelectorProps) => {
function IconSelector(props: IconSelectorProps) {
const iconRef = useRef<HTMLDivElement>(null);
const [selected, setSelected] = useState<AppIconName>(firstSelectedIcon());
const iconPaletteRef = React.createRef<HTMLDivElement>();
@ -87,8 +87,8 @@ const IconSelector = (props: IconSelectorProps) => {
return (
<IconPalette
fill={props.fill}
data-cy={props.cypressSelector}
fill={props.fill}
ref={iconPaletteRef}
>
{props.iconPalette &&
@ -96,19 +96,19 @@ const IconSelector = (props: IconSelectorProps) => {
return (
<IconBox
{...(selected === iconName ? { ref: iconRef } : {})}
key={index}
selectedColor={selected === iconName ? props.selectedColor : ""}
className={
selected === iconName
? "t--icon-selected"
: "t--icon-not-selected"
}
key={index}
onClick={() => {
if (iconName !== selected) {
setSelected(iconName);
props.onSelect && props.onSelect(iconName);
}
}}
selectedColor={selected === iconName ? props.selectedColor : ""}
>
<AppIcon name={iconName} size={Size.small} />
</IconBox>
@ -117,7 +117,7 @@ const IconSelector = (props: IconSelectorProps) => {
<ScrollIndicator containerRef={iconPaletteRef} mode="DARK" />
</IconPalette>
);
};
}
IconSelector.defaultProps = {
fill: false,

View File

@ -38,7 +38,7 @@ interface IconTabsComponentProps {
selectOption: (value: string) => void;
}
const IconTabsComponent = (props: IconTabsComponentProps) => {
function IconTabsComponent(props: IconTabsComponentProps) {
return (
<FlexWrapper>
{props.options.map((option: IconTabOption, index: number) => {
@ -47,17 +47,17 @@ const IconTabsComponent = (props: IconTabsComponentProps) => {
const isSelected = props.value === option.value;
return (
<ItemWrapper
key={index}
selected={isSelected}
onClick={() => props.selectOption(option.value)}
className={`t--icon-tab-${option.value}`}
key={index}
onClick={() => props.selectOption(option.value)}
selected={isSelected}
>
<ControlIcon width={24} height={24} />
<ControlIcon height={24} width={24} />
</ItemWrapper>
);
})}
</FlexWrapper>
);
};
}
export default IconTabsComponent;

View File

@ -24,18 +24,18 @@ const MenuOption = styled.div`
font-family: ${(props) => props.theme.fonts[3]};
`;
const Menu = (props: MenuProps) => {
function Menu(props: MenuProps) {
return (
<Popover
minimal
position={props.position || Position.BOTTOM}
onOpening={props.onOpening}
onClosing={props.onClosing}
className={props.className}
portalClassName={props.className}
data-cy={props.cypressSelector}
disabled={props.disabled}
minimal
modifiers={props.modifiers}
onClosing={props.onClosing}
onOpening={props.onOpening}
portalClassName={props.className}
position={props.position || Position.BOTTOM}
>
{props.target}
<MenuWrapper>
@ -46,6 +46,6 @@ const Menu = (props: MenuProps) => {
</MenuWrapper>
</Popover>
);
};
}
export default Menu;

View File

@ -90,7 +90,7 @@ const IconContainer = styled.span`
const MenuItem = forwardRef(
(props: MenuItemProps, ref: Ref<HTMLAnchorElement>) => {
return props.ellipsize && props.text.length > props.ellipsize ? (
<TooltipComponent position={Position.BOTTOM} content={props.text}>
<TooltipComponent content={props.text} position={Position.BOTTOM}>
<MenuItemContent ref={ref} {...props} />
</TooltipComponent>
) : (
@ -102,13 +102,13 @@ const MenuItemContent = forwardRef(
(props: MenuItemProps, ref: Ref<HTMLAnchorElement>) => {
return (
<ItemRow
data-cy={props.cypressSelector}
disabled={props.disabled}
href={props.href}
onClick={props.onSelect}
disabled={props.disabled}
data-cy={props.cypressSelector}
type={props.type}
ref={ref}
selected={props.selected}
type={props.type}
>
<IconContainer className={props.className}>
{props.icon ? <Icon name={props.icon} size={IconSize.LARGE} /> : null}

View File

@ -55,10 +55,10 @@ export default function MultiSwitch<T>(props: MultiSwitchProps<T>) {
{props.tabs.map((tab) => (
<Tab
key={tab.key}
selected={props.selected.value === tab.key}
onClick={() => props.onSelect(tab.title)}
selected={props.selected.value === tab.key}
>
<Text type={TextType.P3} case={Case.UPPERCASE}>
<Text case={Case.UPPERCASE} type={TextType.P3}>
{tab.title}
</Text>
</Tab>

View File

@ -166,7 +166,7 @@ type DropdownProps = CommonComponentProps & {
selectAllQuantifier?: string;
};
const MultiSelectDropdown = (props: DropdownProps) => {
function MultiSelectDropdown(props: DropdownProps) {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [containerWidth, setContainerWidth] = useState<string>("0px");
@ -229,23 +229,23 @@ const MultiSelectDropdown = (props: DropdownProps) => {
return (
<DropdownContainer
tabIndex={0}
data-cy={props.cypressSelector}
ref={measuredRef}
tabIndex={0}
width={props.width}
>
<Popover
minimal
position={Position.TOP_LEFT}
isOpen={isOpen && !props.disabled}
onInteraction={(state) => setIsOpen(state)}
boundary="scrollParent"
isOpen={isOpen && !props.disabled}
minimal
onInteraction={(state) => setIsOpen(state)}
position={Position.TOP_LEFT}
>
<Selected
isOpen={isOpen}
disabled={props.disabled}
onClick={() => setIsOpen(!isOpen)}
className={props.className}
disabled={props.disabled}
isOpen={isOpen}
onClick={() => setIsOpen(!isOpen)}
>
<Text type={TextType.P1}>
{props.selected.length
@ -260,12 +260,12 @@ const MultiSelectDropdown = (props: DropdownProps) => {
{props.options.map((option: DropdownOption, index: number) => {
return (
<MultiOptionWrapper
className="t--multi-dropdown-option"
key={index}
selected={isItemSelected(option.value)}
onClick={() => {
optionClickHandler(option.value as string);
}}
className="t--multi-dropdown-option"
selected={isItemSelected(option.value)}
>
<SquareBox className={Classes.MULTI_SELECT_BOX} />
{option.icon ? (
@ -288,6 +288,6 @@ const MultiSelectDropdown = (props: DropdownProps) => {
</Popover>
</DropdownContainer>
);
};
}
export default MultiSelectDropdown;

View File

@ -129,29 +129,29 @@ export default function RadioComponent(props: RadioProps) {
return (
<RadioGroup
data-cy={props.cypressSelector}
rows={props.rows}
columns={props.columns}
onChange={(e: any) => onChangeHandler(e.target.value)}
className={props.className}
columns={props.columns}
data-cy={props.cypressSelector}
onChange={(e: any) => onChangeHandler(e.target.value)}
rows={props.rows}
>
{props.options.map((option: OptionProps, index: number) => (
<Radio
key={index}
columns={props.columns}
rows={props.rows}
disabled={props.disabled || option.disabled}
key={index}
rows={props.rows}
>
{option.label}
<input
checked={selected === option.value}
disabled={props.disabled || option.disabled}
name="radio"
onChange={(e) => option.onSelect && option.onSelect(e.target.value)}
type="radio"
value={option.value}
disabled={props.disabled || option.disabled}
onChange={(e) => option.onSelect && option.onSelect(e.target.value)}
checked={selected === option.value}
name="radio"
/>
<span className="checkbox"></span>
<span className="checkbox" />
</Radio>
))}
</RadioGroup>

View File

@ -100,14 +100,13 @@ export default function Switch(props: SwitchProps) {
return (
<StyledSwitch
className={props.className}
data-cy={props.cypressSelector}
firstRender={firstRender}
isLoading={props.isLoading}
value={value}
className={props.className}
firstRender={firstRender}
>
<input
type="checkbox"
checked={value}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (!firstRender) {
@ -115,8 +114,9 @@ export default function Switch(props: SwitchProps) {
}
onChangeHandler(e.target.checked);
}}
type="checkbox"
/>
<span className="slider"></span>
<span className="slider" />
<Light value={value}>
<Text type={TextType.H6}>Light</Text>
</Light>

View File

@ -47,7 +47,7 @@ interface Props {
right?: string;
mode?: "DARK" | "LIGHT";
}
const ScrollIndicator = ({ containerRef, top, bottom, right }: Props) => {
function ScrollIndicator({ containerRef, top, bottom, right }: Props) {
const [{ thumbPosition }, setThumbPosition] = useSpring<{
thumbPosition: number;
config: {
@ -105,10 +105,10 @@ const ScrollIndicator = ({ containerRef, top, bottom, right }: Props) => {
return (
<ScrollTrack
isVisible={isScrollVisible}
top={top}
bottom={bottom}
isVisible={isScrollVisible}
right={right}
top={top}
>
<ScrollThumb
ref={thumbRef}
@ -121,6 +121,6 @@ const ScrollIndicator = ({ containerRef, top, bottom, right }: Props) => {
/>
</ScrollTrack>
);
};
}
export default ScrollIndicator;

View File

@ -118,30 +118,30 @@ const SearchInput = forwardRef(
return (
<InputWrapper
data-cy={props.cypressSelector}
value={searchValue}
isFocused={isFocused}
variant={props.variant}
fill={props.fill}
isFocused={isFocused}
value={searchValue}
variant={props.variant}
>
<SearchIcon value={searchValue} isFocused={isFocused}>
<SearchIcon isFocused={isFocused} value={searchValue}>
<Icon name="search" size={IconSize.SMALL} />
</SearchIcon>
<StyledInput
type="text"
ref={ref}
isFocused={isFocused}
ref={ref}
type="text"
{...props}
placeholder={props.placeholder ? props.placeholder : ""}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
onChange={memoizedChangeHandler}
onFocus={() => setIsFocused(true)}
placeholder={props.placeholder ? props.placeholder : ""}
/>
{searchValue && props.variant === SearchVariant.BACKGROUND ? (
<CloseIcon>
<Icon
name="close"
size={IconSize.MEDIUM}
onClick={() => setSearchValue("")}
size={IconSize.MEDIUM}
/>
</CloseIcon>
) : null}

View File

@ -48,11 +48,11 @@ Spinner.defaultProp = {
export default function Spinner(props: SpinnerProp) {
return (
<SvgContainer
viewBox="0 0 50 50"
className={Classes.SPINNER}
size={props.size}
viewBox="0 0 50 50"
>
<SvgCircle cx="25" cy="25" r="20" fill="none"></SvgCircle>
<SvgCircle cx="25" cy="25" fill="none" r="20" />
</SvgContainer>
);
}

View File

@ -63,7 +63,7 @@ interface StepComponentProps {
onChange: (value: number) => void;
}
export const StepComponent = (props: StepComponentProps) => {
export function StepComponent(props: StepComponentProps) {
function decrease() {
if (props.value < props.min) {
return;
@ -80,11 +80,11 @@ export const StepComponent = (props: StepComponentProps) => {
}
return (
<StepWrapper>
<StyledDecreaseIcon height={2} width={12} onClick={decrease} />
<StyledDecreaseIcon height={2} onClick={decrease} width={12} />
<InputWrapper>{props.displayFormat(props.value)}</InputWrapper>
<StyledIncreaseIcon height={12} width={12} onClick={increase} />
<StyledIncreaseIcon height={12} onClick={increase} width={12} />
</StepWrapper>
);
};
}
export default StepComponent;

View File

@ -138,8 +138,8 @@ function Table(props: TableProps) {
return (
<td
{...cell.getCellProps()}
key={index}
data-colindex={index}
key={index}
>
{cell.render("Cell")}
</td>

View File

@ -1,14 +1,14 @@
import React, { Fragment, useState } from "react";
import { CommonComponentProps, Classes } from "./common";
import Text, { TextType } from "./Text";
import styled from "styled-components";
import { Position } from "@blueprintjs/core/lib/esm/common/position";
import {
Popover,
PopoverInteractionKind,
} from "@blueprintjs/core/lib/esm/components/popover/popover";
import { Position } from "@blueprintjs/core/lib/esm/common/position";
import React, { useState } from "react";
import styled from "styled-components";
import { Classes, CommonComponentProps } from "./common";
import Icon, { IconSize } from "./Icon";
import Spinner from "./Spinner";
import Text, { TextType } from "./Text";
type DropdownOption = {
name: string;
@ -79,7 +79,7 @@ const Content = styled.div<{ isLoading?: boolean }>`
}
`;
const TableDropdown = (props: DropdownProps) => {
function TableDropdown(props: DropdownProps) {
const [selectedIndex, setSelectedIndex] = useState(props.selectedIndex);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState(
@ -93,41 +93,37 @@ const TableDropdown = (props: DropdownProps) => {
setIsDropdownOpen(false);
};
return (
<Fragment>
{props.isLoading ? (
<Spinner size={IconSize.LARGE} />
) : (
<Popover
data-cy={props.cypressSelector}
usePortal={false}
position={props.position || Position.BOTTOM_LEFT}
isOpen={isDropdownOpen}
onInteraction={(state) => setIsDropdownOpen(state)}
interactionKind={PopoverInteractionKind.CLICK}
>
<Content isLoading={props.isLoading}>
<SelectedItem className="selected-item">
<Text type={TextType.P1}>{selectedOption.name}</Text>
<Icon name="downArrow" size={IconSize.XXS} />
</SelectedItem>
</Content>
<OptionsWrapper>
{props.options.map((el: DropdownOption, index: number) => (
<DropdownOption
key={index}
isSelected={selectedIndex === index}
onClick={() => optionSelector(index)}
>
<Text type={TextType.H5}>{el.name}</Text>
<Text type={TextType.P3}>{el.desc}</Text>
</DropdownOption>
))}
</OptionsWrapper>
</Popover>
)}
</Fragment>
return props.isLoading ? (
<Spinner size={IconSize.LARGE} />
) : (
<Popover
data-cy={props.cypressSelector}
interactionKind={PopoverInteractionKind.CLICK}
isOpen={isDropdownOpen}
onInteraction={(state) => setIsDropdownOpen(state)}
position={props.position || Position.BOTTOM_LEFT}
usePortal={false}
>
<Content isLoading={props.isLoading}>
<SelectedItem className="selected-item">
<Text type={TextType.P1}>{selectedOption.name}</Text>
<Icon name="downArrow" size={IconSize.XXS} />
</SelectedItem>
</Content>
<OptionsWrapper>
{props.options.map((el: DropdownOption, index: number) => (
<DropdownOption
isSelected={selectedIndex === index}
key={index}
onClick={() => optionSelector(index)}
>
<Text type={TextType.H5}>{el.name}</Text>
<Text type={TextType.P3}>{el.desc}</Text>
</DropdownOption>
))}
</OptionsWrapper>
</Popover>
);
};
}
export default TableDropdown;

View File

@ -130,17 +130,17 @@ type TabbedViewComponentType = CommonComponentProps & {
overflow?: boolean;
};
export const TabComponent = (props: TabbedViewComponentType) => {
export function TabComponent(props: TabbedViewComponentType) {
return (
<TabsWrapper
shouldOverflow={props.overflow}
data-cy={props.cypressSelector}
shouldOverflow={props.overflow}
>
<Tabs
selectedIndex={props.selectedIndex}
onSelect={(index: number) => {
props.onSelect && props.onSelect(index);
}}
selectedIndex={props.selectedIndex}
>
<TabList>
{props.tabs.map((tab) => (
@ -163,4 +163,4 @@ export const TabComponent = (props: TabbedViewComponentType) => {
</Tabs>
</TabsWrapper>
);
};
}

View File

@ -62,7 +62,7 @@ type TagInputProps = {
* On addition or removal of tags, passes the comman separated string to input.onChange prop
* @param props : TagInputProps
*/
const TagInputComponent = (props: TagInputProps) => {
function TagInputComponent(props: TagInputProps) {
const _values =
props.input.value && props.input.value.length > 0
? props.input.value.split(",")
@ -145,25 +145,25 @@ const TagInputComponent = (props: TagInputProps) => {
return (
<TagInputWrapper intent={props.intent}>
<TagInput
addOnPaste
inputProps={{
type: props.type,
value: currentValue,
onBlur: handleInputBlur,
}}
onInputChange={handleInputChange}
placeholder={props.placeholder}
values={_values || [""]}
separator={props.separator || ","}
addOnPaste
large={false}
onChange={onTagsChange}
onInputChange={handleInputChange}
onKeyDown={onKeyDown}
placeholder={props.placeholder}
separator={props.separator || ","}
tagProps={{
round: true,
}}
large={false}
values={_values || [""]}
/>
</TagInputWrapper>
);
};
}
export default TagInputComponent;

View File

@ -88,8 +88,8 @@ const StyledInput = styled((props) => {
return props.asyncControl ? (
<AsyncControllableInput
{...inputProps}
inputRef={inputRef}
dataType={dataType}
inputRef={inputRef}
/>
) : (
<input ref={inputRef} {...inputProps} />
@ -200,17 +200,17 @@ const TextInput = forwardRef(
return (
<InputWrapper>
<StyledInput
type={props.dataType || "text"}
ref={ref}
defaultValue={props.defaultValue}
inputStyle={inputStyle}
isValid={validation.isValid}
defaultValue={props.defaultValue}
ref={ref}
type={props.dataType || "text"}
{...props}
placeholder={props.placeholder}
onChange={memoizedChangeHandler}
readOnly={props.readOnly}
data-cy={props.cypressSelector}
inputRef={ref}
onChange={memoizedChangeHandler}
placeholder={props.placeholder}
readOnly={props.readOnly}
/>
{ErrorMessage}
</InputWrapper>

View File

@ -39,13 +39,13 @@ const WrappedToastContainer = styled.div`
top: 4em;
}
`;
export const StyledToastContainer = (props: ToastOptions) => {
export function StyledToastContainer(props: ToastOptions) {
return (
<WrappedToastContainer>
<ToastContainer {...props} />
</WrappedToastContainer>
);
};
}
const ToastBody = styled.div<{
variant?: Variant;
@ -110,19 +110,19 @@ const StyledDebugButton = styled(DebugButton)`
margin-left: auto;
`;
const ToastComponent = (props: ToastProps & { undoAction?: () => void }) => {
function ToastComponent(props: ToastProps & { undoAction?: () => void }) {
const dispatch = useDispatch();
return (
<ToastBody
variant={props.variant || Variant.info}
isUndo={!!props.onUndo}
dispatchableAction={props.dispatchableAction}
className="t--toast-action"
dispatchableAction={props.dispatchableAction}
isUndo={!!props.onUndo}
variant={props.variant || Variant.info}
>
<FlexContainer>
{props.variant === Variant.success ? (
<Icon name="success" size={IconSize.XXL} fillColor={Colors.GREEN} />
<Icon fillColor={Colors.GREEN} name="success" size={IconSize.XXL} />
) : props.variant === Variant.warning ? (
<Icon name="warning" size={IconSize.XXL} />
) : null}
@ -139,7 +139,6 @@ const ToastComponent = (props: ToastProps & { undoAction?: () => void }) => {
<div className="undo-section">
{props.onUndo || props.dispatchableAction ? (
<Text
type={TextType.H6}
onClick={() => {
if (props.dispatchableAction) {
dispatch(props.dispatchableAction);
@ -148,6 +147,7 @@ const ToastComponent = (props: ToastProps & { undoAction?: () => void }) => {
props.undoAction && props.undoAction();
}
}}
type={TextType.H6}
>
UNDO
</Text>
@ -155,7 +155,7 @@ const ToastComponent = (props: ToastProps & { undoAction?: () => void }) => {
</div>
</ToastBody>
);
};
}
export const Toaster = {
show: (config: ToastProps) => {

View File

@ -126,21 +126,21 @@ export default function Toggle(props: ToggleProps) {
return (
<StyledToggle
data-cy={props.cypressSelector}
isLoading={props.isLoading}
disabled={props.disabled}
value={value}
className={props.className}
data-cy={props.cypressSelector}
disabled={props.disabled}
isLoading={props.isLoading}
value={value}
>
<input
type="checkbox"
checked={value}
disabled={props.disabled || props.isLoading}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
onChangeHandler(e.target.checked)
}
type="checkbox"
/>
<span className="slider"></span>
<span className="slider" />
{props.isLoading ? (
<div className="toggle-spinner">
<Spinner />

View File

@ -19,26 +19,26 @@ type TooltipProps = CommonComponentProps & {
minimal?: boolean;
};
const TooltipComponent = (props: TooltipProps) => {
function TooltipComponent(props: TooltipProps) {
return (
<Tooltip
content={props.content}
position={props.position}
usePortal
boundary={props.boundary || "scrollParent"}
autoFocus={props.autoFocus}
boundary={props.boundary || "scrollParent"}
content={props.content}
hoverOpenDelay={props.hoverOpenDelay}
openOnTargetFocus={props.openOnTargetFocus}
minimal={props.minimal}
popoverClassName={GLOBAL_STYLE_TOOLTIP_CLASSNAME}
modifiers={{
preventOverflow: { enabled: false },
}}
openOnTargetFocus={props.openOnTargetFocus}
popoverClassName={GLOBAL_STYLE_TOOLTIP_CLASSNAME}
position={props.position}
usePortal
>
{props.children}
</Tooltip>
);
};
}
TooltipComponent.defaultProps = {
position: Position.TOP,

View File

@ -169,10 +169,11 @@ export default function TreeDropdown(props: TreeDropdownProps) {
selectedOption.type === option.value;
return (
<MenuItem
className={option.className || "single-select"}
active={isSelected}
key={option.value}
className={option.className || "single-select"}
icon={option.icon}
intent={option.intent}
key={option.value}
onClick={
option.children
? noop
@ -183,14 +184,13 @@ export default function TreeDropdown(props: TreeDropdownProps) {
e.stopPropagation();
}
}
text={option.label}
intent={option.intent}
popoverProps={{
minimal: true,
interactionKind: PopoverInteractionKind.CLICK,
position: PopoverPosition.LEFT,
targetProps: { onClick: (e: any) => e.stopPropagation() },
}}
text={option.label}
>
{option.children && option.children.map(renderTreeOption)}
</MenuItem>
@ -202,30 +202,30 @@ export default function TreeDropdown(props: TreeDropdownProps) {
const defaultToggle = (
<DropdownTarget>
<Button
className={`t--open-dropdown-${defaultText.split(" ").join("-")} ${
selectedLabelModifier ? "code-highlight" : ""
}`}
rightIcon={IconNames.CHEVRON_DOWN}
text={
selectedLabelModifier
? selectedLabelModifier(selectedOption, displayValue)
: selectedOption.label
}
className={`t--open-dropdown-${defaultText.split(" ").join("-")} ${
selectedLabelModifier ? "code-highlight" : ""
}`}
/>
</DropdownTarget>
);
return (
<Popover
className="wrapper-popover"
content={menuItems}
isOpen={isOpen}
minimal
content={menuItems}
position={PopoverPosition.LEFT}
className="wrapper-popover"
modifiers={props.modifiers}
onClose={() => {
setIsOpen(false);
props.onMenuToggle && props.onMenuToggle(false);
}}
position={PopoverPosition.LEFT}
targetProps={{
onClick: (e: any) => {
setIsOpen(true);

View File

@ -20,7 +20,7 @@ type FormFieldErrorProps = {
className?: string;
};
export const FormFieldError = (props: FormFieldErrorProps) => {
export function FormFieldError(props: FormFieldErrorProps) {
return (
<StyledError
className={props.className ? props.className : undefined}
@ -29,6 +29,6 @@ export const FormFieldError = (props: FormFieldErrorProps) => {
{props.error || "&nbsp;"}
</StyledError>
);
};
}
export default FormFieldError;

View File

@ -38,13 +38,13 @@ const StyledAction = styled.div<{ intent: Intent }>`
}
`;
export const ActionButton = (props: MessageAction) => {
export function ActionButton(props: MessageAction) {
if (props.url) {
const isExternal = props.url.indexOf("//") !== -1;
return (
<StyledAction intent={props.intent}>
{isExternal ? (
<a href={props.url} target="_blank" rel="noreferrer">
<a href={props.url} rel="noreferrer" target="_blank">
{props.text}
</a>
) : (
@ -54,13 +54,13 @@ export const ActionButton = (props: MessageAction) => {
);
} else if (props.onClick) {
return (
<StyledAction onClick={props.onClick} intent={props.intent}>
<StyledAction intent={props.intent} onClick={props.onClick}>
{props.text}
</StyledAction>
);
}
return null;
};
}
export type FormMessageProps = {
intent: Intent;
@ -68,18 +68,18 @@ export type FormMessageProps = {
actions?: MessageAction[];
};
export const FormMessage = (props: FormMessageProps) => {
export function FormMessage(props: FormMessageProps) {
const actions =
props.actions &&
props.actions.map((action) => (
<ActionButton key={action.text} {...action} intent={props.intent} />
));
return (
<StyledMessage intent={props.intent} className="form-message-container">
<StyledMessage className="form-message-container" intent={props.intent}>
{props.message}
{actions && <ActionsContainer>{actions}</ActionsContainer>}
</StyledMessage>
);
};
}
export default FormMessage;

View File

@ -17,10 +17,10 @@ const renderComponent = (
const showError = componentProps.meta.touched && !componentProps.meta.active;
return (
<React.Fragment>
<>
<InputComponent {...componentProps} {...componentProps.input} fill />
<FormFieldError error={showError && componentProps.meta.error} />
</React.Fragment>
</>
);
};
@ -34,12 +34,8 @@ type FormTextFieldProps = {
autoFocus?: boolean;
};
const FormTextField = (props: FormTextFieldProps) => {
return (
<React.Fragment>
<Field component={renderComponent} {...props} asyncControl />
</React.Fragment>
);
};
function FormTextField(props: FormTextFieldProps) {
return <Field component={renderComponent} {...props} asyncControl />;
}
export default FormTextField;

View File

@ -31,7 +31,7 @@ const StyledContainerComponent = styled.div<
${(props) => (props.shouldScrollContents ? scrollContents : "")}
}`;
const ContainerComponent = (props: ContainerComponentProps) => {
function ContainerComponent(props: ContainerComponentProps) {
const containerStyle = props.containerStyle || "card";
const containerRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
@ -51,18 +51,18 @@ const ContainerComponent = (props: ContainerComponentProps) => {
return (
<StyledContainerComponent
{...props}
ref={containerRef}
containerStyle={containerStyle}
// Before you remove: generateClassName is used for bounding the resizables within this canvas
// getCanvasClassName is used to add a scrollable parent.
className={`${
props.shouldScrollContents ? getCanvasClassName() : ""
} ${generateClassName(props.widgetId)}`}
containerStyle={containerStyle}
// Before you remove: generateClassName is used for bounding the resizables within this canvas
// getCanvasClassName is used to add a scrollable parent.
ref={containerRef}
>
{props.children}
</StyledContainerComponent>
);
};
}
export type ContainerStyle = "border" | "card" | "rounded-border" | "none";

View File

@ -19,7 +19,7 @@ const Wrapper = styled.div`
}
`;
const CopyToClipboard = (props: any) => {
function CopyToClipboard(props: any) {
const { copyText } = props;
const copyURLInput = createRef<HTMLInputElement>();
const [isCopied, setIsCopied] = useState(false);
@ -40,22 +40,22 @@ const CopyToClipboard = (props: any) => {
return (
<Wrapper>
<BaseTextInput
defaultValue={copyText}
disabled
fill
disabled={true}
onChange={() => {
selectText();
}}
defaultValue={copyText}
/>
<BaseButton
text={isCopied ? "Copied" : "Copy"}
onClick={() => {
copyToClipboard(copyText);
}}
text={isCopied ? "Copied" : "Copy"}
/>
</Wrapper>
);
};
}
export default CopyToClipboard;

View File

@ -94,12 +94,14 @@ class CreatableDropdown extends React.Component<DropdownProps> {
return (
<Select
isMulti
placeholder={placeholder}
options={options}
styles={selectStyles}
isLoading={isLoading}
isMulti
options={options}
placeholder={placeholder}
styles={selectStyles}
{...input}
isClearable
onBlur={() => input.value}
onChange={(value) => {
const formattedValue = value;
if (formattedValue && formattedValue.length > 1) {
@ -108,8 +110,6 @@ class CreatableDropdown extends React.Component<DropdownProps> {
input.onChange(formattedValue);
}}
onBlur={() => input.value}
isClearable
{...optionalProps}
/>
);

View File

@ -100,8 +100,8 @@ export class DroppableComponent extends React.Component<
return (
<Draggable
draggableId={item.id}
key={item.id}
index={index}
key={item.id}
>
{({ innerRef, draggableProps, dragHandleProps }) => (
<ItemWrapper

View File

@ -52,23 +52,23 @@ const selectStyles = {
indicatorSeparator: () => ({}),
};
export const BaseDropdown = (props: DropdownProps) => {
export function BaseDropdown(props: DropdownProps) {
const { input, customSelectStyles } = props;
return (
<Select
styles={{ ...selectStyles, ...customSelectStyles }}
{...input}
width={props.width}
onChange={(value) => input.onChange(value)}
isSearchable={props.isSearchable}
isDisabled={props.isDisabled}
isSearchable={props.isSearchable}
onChange={(value) => input.onChange(value)}
width={props.width}
{...props}
/>
);
};
}
const Dropdown = (props: DropdownProps) => {
function Dropdown(props: DropdownProps) {
return <BaseDropdown {...props} />;
};
}
export default Dropdown;

View File

@ -26,16 +26,14 @@ class FilePickerComponent extends React.Component<
label = `${this.props.files.length} files selected`;
}
return (
<React.Fragment>
<BaseButton
accent="primary"
filled
loading={this.props.isLoading}
text={label}
onClick={this.openModal}
disabled={this.props.isDisabled}
/>
</React.Fragment>
<BaseButton
accent="primary"
disabled={this.props.isDisabled}
filled
loading={this.props.isLoading}
onClick={this.openModal}
text={label}
/>
);
}

View File

@ -8,15 +8,15 @@ class IconComponent extends React.Component<IconComponentProps> {
render() {
return (
<Icon
style={{
cursor:
this.props.onClick && !this.props.disabled ? "pointer" : "auto",
}}
color={this.props.color}
icon={this.props.iconName as IconName}
iconSize={this.props.iconSize}
intent={this.props.intent}
onClick={this.props.disabled ? noop : this.props.onClick}
color={this.props.color}
style={{
cursor:
this.props.onClick && !this.props.disabled ? "pointer" : "auto",
}}
/>
);
}

View File

@ -74,29 +74,18 @@ class ImageComponent extends React.Component<
<Wrapper>
<TransformWrapper
defaultScale={1}
onPanningStart={() => {
this.props.disableDrag(true);
doubleClick={{
disabled: true,
}}
onPanning={() => {
this.isPanning = true;
}}
onPanningStart={() => {
this.props.disableDrag(true);
}}
onPanningStop={() => {
this.props.disableDrag(false);
}}
options={{
maxScale: maxZoomLevel,
disabled: !zoomActive,
transformEnabled: zoomActive,
}}
pan={{
disabled: !zoomActive,
}}
wheel={{
disabled: !zoomActive,
}}
doubleClick={{
disabled: true,
}}
onZoomChange={(zoom: any) => {
if (zoomActive) {
//Check max zoom
@ -119,42 +108,51 @@ class ImageComponent extends React.Component<
}
}
}}
options={{
maxScale: maxZoomLevel,
disabled: !zoomActive,
transformEnabled: zoomActive,
}}
pan={{
disabled: !zoomActive,
}}
wheel={{
disabled: !zoomActive,
}}
>
{({ zoomIn, zoomOut }: any) => (
<React.Fragment>
<TransformComponent>
<StyledImage
className={this.props.isLoading ? "bp3-skeleton" : ""}
imageError={this.state.imageError}
{...this.props}
data-testid="styledImage"
style={{
cursor,
}}
onClick={(event: React.MouseEvent<HTMLElement>) => {
if (!this.isPanning) {
if (isZoomingIn) {
zoomIn(event);
} else {
zoomOut(event);
}
this.props.onClick && this.props.onClick(event);
<TransformComponent>
<StyledImage
className={this.props.isLoading ? "bp3-skeleton" : ""}
imageError={this.state.imageError}
{...this.props}
data-testid="styledImage"
onClick={(event: React.MouseEvent<HTMLElement>) => {
if (!this.isPanning) {
if (isZoomingIn) {
zoomIn(event);
} else {
zoomOut(event);
}
this.isPanning = false;
this.props.onClick && this.props.onClick(event);
}
this.isPanning = false;
}}
style={{
cursor,
}}
>
<img
alt={this.props.widgetName}
onError={this.onImageError}
onLoad={this.onImageLoad}
src={this.props.imageUrl}
style={{
display: "none",
}}
>
<img
style={{
display: "none",
}}
alt={this.props.widgetName}
src={this.props.imageUrl}
onError={this.onImageError}
onLoad={this.onImageLoad}
></img>
</StyledImage>
</TransformComponent>
</React.Fragment>
/>
</StyledImage>
</TransformComponent>
)}
</TransformWrapper>
</Wrapper>

View File

@ -115,6 +115,12 @@ const MyMapComponent = withGoogleMap((props: any) => {
}, [props.center, props.selectedMarker]);
return (
<GoogleMap
center={mapCenter}
onClick={(e) => {
if (props.enableCreateMarker) {
props.saveMarker(e.latLng.lat(), e.latLng.lng());
}
}}
options={{
zoomControl: props.allowZoom,
fullscreenControl: false,
@ -124,12 +130,6 @@ const MyMapComponent = withGoogleMap((props: any) => {
streetViewControl: false,
}}
zoom={props.zoom}
center={mapCenter}
onClick={(e) => {
if (props.enableCreateMarker) {
props.saveMarker(e.latLng.lat(), e.latLng.lng());
}
}}
>
{props.enableSearch && (
<SearchBox
@ -137,21 +137,19 @@ const MyMapComponent = withGoogleMap((props: any) => {
onPlacesChanged={onPlacesChanged}
ref={searchBox}
>
<StyledInput type="text" placeholder="Enter location to search" />
<StyledInput placeholder="Enter location to search" type="text" />
</SearchBox>
)}
{Array.isArray(props.markers) &&
props.markers.map((marker: MarkerProps, index: number) => (
<Marker
key={index}
title={marker.title}
position={{ lat: marker.lat, lng: marker.long }}
clickable
draggable={
props.selectedMarker &&
props.selectedMarker.lat === marker.lat &&
props.selectedMarker.long === marker.long
}
key={index}
onClick={() => {
setMapCenter({
...marker,
@ -162,12 +160,14 @@ const MyMapComponent = withGoogleMap((props: any) => {
onDragEnd={(de) => {
props.updateMarker(de.latLng.lat(), de.latLng.lng(), index);
}}
position={{ lat: marker.lat, lng: marker.long }}
title={marker.title}
/>
))}
{props.enablePickLocation && (
<PickMyLocationWrapper
title="Pick My Location"
allowZoom={props.allowZoom}
title="Pick My Location"
>
<PickMyLocation updateCenter={props.updateCenter} />
</PickMyLocationWrapper>
@ -176,7 +176,7 @@ const MyMapComponent = withGoogleMap((props: any) => {
);
});
const MapComponent = (props: MapComponentProps) => {
function MapComponent(props: MapComponentProps) {
const zoom = Math.floor(props.zoomLevel / 5);
const status = useScript(
`https://maps.googleapis.com/maps/api/js?key=${props.apiKey}&v=3.exp&libraries=geometry,drawing,places`,
@ -186,8 +186,8 @@ const MapComponent = (props: MapComponentProps) => {
<MapWrapper onMouseLeave={props.enableDrag}>
{status === ScriptStatus.READY && (
<MyMapComponent
loadingElement={<MapContainerWrapper />}
containerElement={<MapContainerWrapper />}
loadingElement={<MapContainerWrapper />}
mapElement={<MapContainerWrapper />}
{...props}
zoom={zoom}
@ -195,6 +195,6 @@ const MapComponent = (props: MapComponentProps) => {
)}
</MapWrapper>
);
};
}
export default MapComponent;

View File

@ -26,16 +26,14 @@ const PlayerWrapper = styled.div` import React, { Ref } from "react";
height: 400px;
`;
const PopoverVideo = (props: VideoComponentProps) => {
function PopoverVideo(props: VideoComponentProps) {
return (
<div onClick={(e) => e.stopPropagation()}>
<Popover
position={PopoverPosition.AUTO}
interactionKind={PopoverInteractionKind.CLICK}
minimal
usePortal
enforceFocus={false}
interactionKind={PopoverInteractionKind.CLICK}
lazy
minimal
modifiers={{
flip: {
behavior: ["right", "left", "bottom", "top"],
@ -51,14 +49,16 @@ const PopoverVideo = (props: VideoComponentProps) => {
boundariesElement: "viewport",
},
}}
position={PopoverPosition.AUTO}
usePortal
>
<PlayIcon></PlayIcon>
<PlayIcon />
<PlayerWrapper>
<VideoComponent url={props.url} />
</PlayerWrapper>
</Popover>
</div>
);
};
}
export default PopoverVideo;

View File

@ -17,7 +17,7 @@ type PositionedContainerProps = {
widgetType: string;
};
export const PositionedContainer = (props: PositionedContainerProps) => {
export function PositionedContainer(props: PositionedContainerProps) {
const x = props.style.xPosition + (props.style.xPositionUnit || "px");
const y = props.style.yPosition + (props.style.yPositionUnit || "px");
const padding = WIDGET_PADDING;
@ -47,16 +47,16 @@ export const PositionedContainer = (props: PositionedContainerProps) => {
return (
<PositionedWidget
onClickCapture={openPropertyPane}
style={containerStyle}
id={props.widgetId}
//Before you remove: This is used by property pane to reference the element
className={containerClassName}
id={props.widgetId}
onClickCapture={openPropertyPane}
//Before you remove: This is used by property pane to reference the element
style={containerStyle}
>
{props.children}
</PositionedWidget>
);
};
}
PositionedContainer.padding = WIDGET_PADDING;

View File

@ -21,9 +21,7 @@ export interface RichtextEditorComponentProps {
isVisible?: boolean;
onValueChange: (valueAsString: string) => void;
}
export const RichtextEditorComponent = (
props: RichtextEditorComponentProps,
) => {
export function RichtextEditorComponent(props: RichtextEditorComponentProps) {
const status = useScript(
"https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.7.0/tinymce.min.js",
);
@ -110,9 +108,9 @@ export const RichtextEditorComponent = (
return (
<StyledRTEditor>
<textarea id={`rte-${props.widgetId}`}></textarea>
<textarea id={`rte-${props.widgetId}`} />
</StyledRTEditor>
);
};
}
export default RichtextEditorComponent;

View File

@ -53,9 +53,9 @@ class SearchComponent extends React.Component<
return (
<SearchInputWrapper
leftIcon="search"
type="search"
onChange={this.handleSearch}
placeholder={this.props.placeholder}
type="search"
value={this.state.localValue}
/>
);

View File

@ -68,7 +68,7 @@ interface StepComponentProps {
onChange: (value: number) => void;
}
export const StepComponent = (props: StepComponentProps) => {
export function StepComponent(props: StepComponentProps) {
function decrease() {
if (props.value < props.min) {
return;
@ -85,11 +85,11 @@ export const StepComponent = (props: StepComponentProps) => {
}
return (
<StepWrapper>
<StyledDecreaseIcon height={2} width={12} onClick={decrease} />
<StyledDecreaseIcon height={2} onClick={decrease} width={12} />
<InputWrapper>{props.displayFormat(props.value)}</InputWrapper>
<StyledIncreaseIcon height={12} width={12} onClick={increase} />
<StyledIncreaseIcon height={12} onClick={increase} width={12} />
</StepWrapper>
);
};
}
export default StepComponent;

View File

@ -49,14 +49,14 @@ type TabbedViewComponentType = {
overflow?: boolean;
};
export const BaseTabbedView = (props: TabbedViewComponentType) => {
export function BaseTabbedView(props: TabbedViewComponentType) {
return (
<TabsWrapper shouldOverflow={props.overflow}>
<Tabs
selectedIndex={props.selectedIndex}
onSelect={(index: number) => {
props.setSelectedIndex && props.setSelectedIndex(index);
}}
selectedIndex={props.selectedIndex}
>
<TabList>
{props.tabs.map((tab) => (
@ -69,4 +69,4 @@ export const BaseTabbedView = (props: TabbedViewComponentType) => {
</Tabs>
</TabsWrapper>
);
};
}

View File

@ -28,7 +28,7 @@ interface Props {
columnType?: string;
}
const LinkWrapper = (props: Props) => {
function LinkWrapper(props: Props) {
const ref = createRef<HTMLDivElement>();
const [useToolTip, updateToolTip] = useState(false);
useEffect(() => {
@ -41,24 +41,24 @@ const LinkWrapper = (props: Props) => {
}, [ref]);
return (
<CellWrapper
isHidden={props.isHidden}
cellProperties={props.cellProperties}
isHidden={props.isHidden}
isHyperLink
useLinkToolTip={useToolTip}
onClick={() => {
window.open(props.title, "_blank");
}}
useLinkToolTip={useToolTip}
>
<div ref={ref} className="link-text">
<div className="link-text" ref={ref}>
{useToolTip && props.children ? (
<Tooltip
autoFocus={false}
hoverOpenDelay={1000}
content={
<TooltipContentWrapper width={(props.tableWidth || 300) - 32}>
{props.title}
</TooltipContentWrapper>
}
hoverOpenDelay={1000}
position="top"
>
{props.children}
@ -72,9 +72,9 @@ const LinkWrapper = (props: Props) => {
</OpenNewTabIconWrapper>
</CellWrapper>
);
};
}
const AutoToolTipComponent = (props: Props) => {
function AutoToolTipComponent(props: Props) {
const ref = createRef<HTMLDivElement>();
const [useToolTip, updateToolTip] = useState(false);
useEffect(() => {
@ -90,19 +90,19 @@ const AutoToolTipComponent = (props: Props) => {
}
return (
<CellWrapper
ref={ref}
isHidden={props.isHidden}
cellProperties={props.cellProperties}
isHidden={props.isHidden}
ref={ref}
>
{useToolTip && props.children ? (
<Tooltip
autoFocus={false}
hoverOpenDelay={1000}
content={
<TooltipContentWrapper width={(props.tableWidth || 300) - 32}>
{props.title}
</TooltipContentWrapper>
}
hoverOpenDelay={1000}
position="top"
>
{props.children}
@ -112,6 +112,6 @@ const AutoToolTipComponent = (props: Props) => {
)}
</CellWrapper>
);
};
}
export default AutoToolTipComponent;

View File

@ -169,27 +169,23 @@ const columnTypeNameMap: Record<ColumnTypes, string> = {
[ColumnTypes.URL]: "Url",
};
const RenderOption = (props: {
type: string;
title: string;
active: boolean;
}) => {
function RenderOption(props: { type: string; title: string; active: boolean }) {
return (
<RenderOptionWrapper selected={props.active}>
<div className="title">{props.title}</div>
<div className="type">{columnTypeNameMap[props.type as ColumnTypes]}</div>
</RenderOptionWrapper>
);
};
}
const RenderOptions = (props: {
function RenderOptions(props: {
columns: DropdownOption[];
selectItem: (column: DropdownOption) => void;
placeholder: string;
value?: string | Condition;
showType?: boolean;
className?: string;
}) => {
}) {
const [selectedValue, selectValue] = useState(props.placeholder);
const configs = {
sections: [
@ -199,9 +195,9 @@ const RenderOptions = (props: {
return {
content: props.showType ? (
<RenderOption
active={isActive}
title={column.label}
type={column.type}
active={isActive}
/>
) : (
column.label
@ -223,7 +219,7 @@ const RenderOptions = (props: {
<AutoToolTipComponentWrapper title={selectedValue}>
{selectedValue}
</AutoToolTipComponentWrapper>
<Icon icon="chevron-down" iconSize={16} color={Colors.SLATE_GRAY} />
<Icon color={Colors.SLATE_GRAY} icon="chevron-down" iconSize={16} />
</DropdownTrigger>
),
},
@ -244,13 +240,13 @@ const RenderOptions = (props: {
}
}, [props.value, props.placeholder, props.columns]);
return <CustomizedDropdown {...configs} />;
};
}
const RenderInput = (props: {
function RenderInput(props: {
value: string;
onChange: (value: string) => void;
className?: string;
}) => {
}) {
const debouncedOnChange = useCallback(debounce(props.onChange, 400), []);
const [value, setValue] = useState(props.value);
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
@ -263,14 +259,14 @@ const RenderInput = (props: {
}, [props.value]);
return (
<StyledInputGroup
placeholder="Enter value"
onChange={onChange}
type="text"
defaultValue={value}
className={props.className}
defaultValue={value}
onChange={onChange}
placeholder="Enter value"
type="text"
/>
);
};
}
type CascadeFieldProps = {
columns: DropdownOption[];
@ -429,14 +425,14 @@ function CaseCaseFieldReducer(
}
}
const CascadeField = (props: CascadeFieldProps) => {
function CascadeField(props: CascadeFieldProps) {
const memoizedState = React.useMemo(() => calculateInitialState(props), [
props,
]);
return <Fields state={memoizedState} {...props} />;
};
}
const Fields = (props: CascadeFieldProps & { state: CascadeFieldState }) => {
function Fields(props: CascadeFieldProps & { state: CascadeFieldState }) {
const { index, removeFilter, applyFilter, hasAnyFilters } = props;
const [state, dispatch] = React.useReducer(CaseCaseFieldReducer, props.state);
const handleRemoveFilter = () => {
@ -513,22 +509,22 @@ const Fields = (props: CascadeFieldProps & { state: CascadeFieldState }) => {
return (
<FieldWrapper className="t--table-filter">
<StyledRemoveIcon
onClick={handleRemoveFilter}
height={16}
width={16}
color={Colors.RIVER_BED}
className={`t--table-filter-remove-btn ${
hasAnyFilters ? "" : "hide-icon"
}`}
color={Colors.RIVER_BED}
height={16}
onClick={handleRemoveFilter}
width={16}
/>
{index === 1 ? (
<DropdownWrapper width={95}>
<RenderOptions
className="t--table-filter-operators-dropdown"
columns={operatorOptions}
placeholder="or"
selectItem={selectOperator}
value={operator}
placeholder="or"
className="t--table-filter-operators-dropdown"
/>
</DropdownWrapper>
) : (
@ -538,22 +534,22 @@ const Fields = (props: CascadeFieldProps & { state: CascadeFieldState }) => {
)}
<DropdownWrapper width={150}>
<RenderOptions
columns={props.columns}
selectItem={selectColumn}
value={column}
showType
placeholder="Attribute"
className="t--table-filter-columns-dropdown"
columns={props.columns}
placeholder="Attribute"
selectItem={selectColumn}
showType
value={column}
/>
</DropdownWrapper>
{showConditions ? (
<DropdownWrapper width={200}>
<RenderOptions
className="t--table-filter-conditions-dropdown"
columns={conditions}
placeholder=""
selectItem={selectCondition}
value={condition}
placeholder=""
className="t--table-filter-conditions-dropdown"
/>
</DropdownWrapper>
) : null}
@ -567,20 +563,20 @@ const Fields = (props: CascadeFieldProps & { state: CascadeFieldState }) => {
{showDateInput ? (
<DatePickerWrapper className="t--table-filter-date-input">
<DatePickerComponent
label=""
dateFormat="DD/MM/YYYY"
datePickerType="DATE_PICKER"
onDateSelected={onDateSelected}
selectedDate={value}
enableTimePicker={false}
isDisabled={false}
isLoading={false}
enableTimePicker={false}
label=""
onDateSelected={onDateSelected}
selectedDate={value}
widgetId=""
/>
</DatePickerWrapper>
) : null}
</FieldWrapper>
);
};
}
export default CascadeField;

View File

@ -62,7 +62,7 @@ const defaultColumn = {
width: 150,
};
export const Table = (props: TableProps) => {
export function Table(props: TableProps) {
const isResizingColumn = React.useRef(false);
const tableWrapperRef = React.useRef<HTMLDivElement>(null);
@ -142,45 +142,45 @@ export const Table = (props: TableProps) => {
/* Subtracting 9px to handling widget padding */
return (
<TableWrapper
width={props.width}
height={props.height}
tableSizes={tableSizes}
id={`table${props.widgetId}`}
triggerRowSelection={props.triggerRowSelection}
backgroundColor={Colors.ATHENS_GRAY_DARKER}
height={props.height}
id={`table${props.widgetId}`}
ref={tableWrapperRef}
tableSizes={tableSizes}
triggerRowSelection={props.triggerRowSelection}
width={props.width}
>
<TableHeader
width={props.width}
tableData={props.data}
tableColumns={props.columns}
searchTableData={props.searchTableData}
searchKey={props.searchKey}
updatePageNo={props.updatePageNo}
nextPageClick={props.nextPageClick}
prevPageClick={props.prevPageClick}
pageNo={props.pageNo}
pageCount={pageCount}
currentPageIndex={currentPageIndex}
pageOptions={pageOptions}
widgetName={props.widgetName}
serverSidePaginationEnabled={props.serverSidePaginationEnabled}
applyFilter={props.applyFilter}
columns={props.columns.filter((column: ReactTableColumnProps) => {
return column.accessor !== "actions";
})}
filters={props.filters}
applyFilter={props.applyFilter}
editMode={props.editMode}
compactMode={props.compactMode}
updateCompactMode={props.updateCompactMode}
currentPageIndex={currentPageIndex}
editMode={props.editMode}
filters={props.filters}
nextPageClick={props.nextPageClick}
pageCount={pageCount}
pageNo={props.pageNo}
pageOptions={pageOptions}
prevPageClick={props.prevPageClick}
searchKey={props.searchKey}
searchTableData={props.searchTableData}
serverSidePaginationEnabled={props.serverSidePaginationEnabled}
tableColumns={props.columns}
tableData={props.data}
tableSizes={tableSizes}
updateCompactMode={props.updateCompactMode}
updatePageNo={props.updatePageNo}
widgetName={props.widgetName}
width={props.width}
/>
<div className={props.isLoading ? Classes.SKELETON : "tableWrap"}>
<div {...getTableProps()} className="table">
<div
onMouseOver={props.disableDrag}
onMouseLeave={props.enableDrag}
className="thead"
onMouseLeave={props.enableDrag}
onMouseOver={props.disableDrag}
>
{headerGroups.map((headerGroup: any, index: number) => (
<div
@ -191,14 +191,14 @@ export const Table = (props: TableProps) => {
{headerGroup.headers.map((column: any, columnIndex: number) => {
return (
<TableHeaderCell
key={columnIndex}
column={column}
columnName={column.Header}
columnIndex={columnIndex}
isHidden={column.isHidden}
sortTableColumn={props.sortTableColumn}
columnName={column.Header}
isAscOrder={column.isAscOrder}
isHidden={column.isHidden}
isResizingColumn={isResizingColumn.current}
key={columnIndex}
sortTableColumn={props.sortTableColumn}
/>
);
})}
@ -233,20 +233,20 @@ export const Table = (props: TableProps) => {
: ""
}`
}
key={rowIndex}
onClick={() => {
row.toggleRowSelected();
props.selectTableRow(row);
}}
key={rowIndex}
>
{row.cells.map((cell, cellIndex) => {
return (
<div
{...cell.getCellProps()}
className="td"
key={cellIndex}
data-rowindex={rowIndex}
data-colindex={cellIndex}
data-rowindex={rowIndex}
key={cellIndex}
>
{cell.render("Cell")}
</div>
@ -269,6 +269,6 @@ export const Table = (props: TableProps) => {
<ScrollIndicator containerRef={tableWrapperRef} mode="LIGHT" />
</TableWrapper>
);
};
}
export default Table;

View File

@ -13,30 +13,30 @@ interface TableActionIconProps {
icon?: React.ReactNode;
}
const TableActionIcon = (props: TableActionIconProps) => {
function TableActionIcon(props: TableActionIconProps) {
return (
<Tooltip
autoFocus={false}
hoverOpenDelay={1000}
content={props.tooltip}
position="top"
hoverOpenDelay={1000}
modifiers={{
preventOverflow: { enabled: false },
flip: { enabled: false },
}}
position="top"
>
<TableIconWrapper
selected={props.selected}
className={props.className}
onClick={(e) => {
props.selectMenu(!props.selected);
e.stopPropagation();
}}
className={props.className}
selected={props.selected}
>
<IconWrapper
width={20}
height={20}
color={props.selected ? Colors.OXFORD_BLUE : Colors.CADET_BLUE}
height={20}
width={20}
>
{props.children}
</IconWrapper>
@ -44,6 +44,6 @@ const TableActionIcon = (props: TableActionIconProps) => {
</TableIconWrapper>
</Tooltip>
);
};
}
export default TableActionIcon;

View File

@ -75,25 +75,25 @@ interface TableColumnsVisibilityProps {
updateHiddenColumns: (hiddenColumns?: string[]) => void;
}
const VisibilityIcon = (props: { visible?: boolean }) => {
function VisibilityIcon(props: { visible?: boolean }) {
return props.visible ? (
<Icon
className="visible-icon"
color={Colors.OXFORD_BLUE}
icon="eye-open"
iconSize={20}
color={Colors.OXFORD_BLUE}
/>
) : (
<VisibleIcon className="hidden-icon" />
);
};
}
const TableColumnsVisibility = (props: TableColumnsVisibilityProps) => {
function TableColumnsVisibility(props: TableColumnsVisibilityProps) {
const [selected, selectMenu] = React.useState(false);
if (props.columns.length === 0) {
return (
<TableIconWrapper disabled>
<IconWrapper width={20} height={20} color={Colors.CADET_BLUE}>
<IconWrapper color={Colors.CADET_BLUE} height={20} width={20}>
<VisibilityIcon />
</IconWrapper>
</TableIconWrapper>
@ -106,30 +106,30 @@ const TableColumnsVisibility = (props: TableColumnsVisibilityProps) => {
);
return (
<Popover
minimal
usePortal
enforceFocus={false}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM}
isOpen={selected}
minimal
onClose={() => {
selectMenu(false);
}}
isOpen={selected}
position={Position.BOTTOM}
usePortal
>
<TableActionIcon
tooltip="Hidden Fields"
className="t--table-column-visibility-toggle-btn"
selected={selected}
selectMenu={(selected: boolean) => {
selectMenu(selected);
}}
selected={selected}
tooltip="Hidden Fields"
>
<VisibilityIcon />
</TableActionIcon>
<DropDownWrapper>
{columns.map((option: ReactTableColumnProps, index: number) => (
<OptionWrapper
selected={!option.isHidden}
className="t--table-column-visibility-column-toggle"
key={index}
onClick={() => {
const hiddenColumns = Array.isArray(props.hiddenColumns)
@ -142,7 +142,7 @@ const TableColumnsVisibility = (props: TableColumnsVisibilityProps) => {
}
props.updateHiddenColumns(hiddenColumns);
}}
className="t--table-column-visibility-column-toggle"
selected={!option.isHidden}
>
<StyledOption className="option-title">
{option.Header}
@ -152,19 +152,19 @@ const TableColumnsVisibility = (props: TableColumnsVisibilityProps) => {
))}
<ButtonWrapper className={Classes.POPOVER_DISMISS}>
<Button
intent="primary"
text="Show All"
filled
size="small"
className="t--table-column-show-all-btn"
filled
intent="primary"
onClick={() => {
props.updateHiddenColumns([]);
}}
size="small"
text="Show All"
/>
</ButtonWrapper>
</DropDownWrapper>
</Popover>
);
};
}
export default TableColumnsVisibility;

View File

@ -76,26 +76,26 @@ interface TableCompactModeProps {
updateCompactMode: (mode: CompactMode) => void;
}
const TableCompactMode = (props: TableCompactModeProps) => {
function TableCompactMode(props: TableCompactModeProps) {
const [selected, selectMenu] = React.useState(false);
return (
<Popover
minimal
enforceFocus={false}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM}
isOpen={selected}
minimal
onClose={() => {
selectMenu(false);
}}
isOpen={selected}
position={Position.BOTTOM}
>
<TableActionIcon
tooltip="Row Height"
selected={selected}
className="t--table-compact-mode-toggle-btn"
selectMenu={(selected: boolean) => {
selectMenu(selected);
}}
className="t--table-compact-mode-toggle-btn"
selected={selected}
tooltip="Row Height"
>
<CompactIcon />
</TableActionIcon>
@ -103,14 +103,14 @@ const TableCompactMode = (props: TableCompactModeProps) => {
{CompactModes.map((item: CompactModeItem, index: number) => {
return (
<OptionWrapper
selected={
props.compactMode ? props.compactMode === item.value : false
}
className={`${Classes.POPOVER_DISMISS} t--table-compact-mode-option`}
key={index}
onClick={() => {
props.updateCompactMode(item.value);
}}
className={`${Classes.POPOVER_DISMISS} t--table-compact-mode-option`}
selected={
props.compactMode ? props.compactMode === item.value : false
}
>
{item.title}
</OptionWrapper>
@ -119,6 +119,6 @@ const TableCompactMode = (props: TableCompactModeProps) => {
</DropDownWrapper>
</Popover>
);
};
}
export default TableCompactMode;

View File

@ -44,7 +44,7 @@ const downloadDataAsCSV = (props: {
}
};
const TableDataDownload = (props: TableDataDownloadProps) => {
function TableDataDownload(props: TableDataDownloadProps) {
const [selected, toggleButtonClick] = React.useState(false);
const downloadTableData = () => {
toggleButtonClick(true);
@ -62,7 +62,7 @@ const TableDataDownload = (props: TableDataDownloadProps) => {
if (props.columns.length === 0) {
return (
<TableIconWrapper disabled>
<IconWrapper width={20} height={20} color={Colors.CADET_BLUE}>
<IconWrapper color={Colors.CADET_BLUE} height={20} width={20}>
<DownloadIcon />
</IconWrapper>
</TableIconWrapper>
@ -70,16 +70,16 @@ const TableDataDownload = (props: TableDataDownloadProps) => {
}
return (
<TableActionIcon
tooltip="Download"
selected={selected}
className="t--table-download-btn"
selectMenu={() => {
downloadTableData();
}}
className="t--table-download-btn"
selected={selected}
tooltip="Download"
>
<DownloadIcon />
</TableActionIcon>
);
};
}
export default TableDataDownload;

View File

@ -102,7 +102,7 @@ interface TableFilterProps {
editMode: boolean;
}
const TableFilters = (props: TableFilterProps) => {
function TableFilters(props: TableFilterProps) {
const [selected, selectMenu] = React.useState(false);
const [filters, updateFilters] = React.useState(
new Array<ReactTableFilter>(),
@ -138,7 +138,7 @@ const TableFilters = (props: TableFilterProps) => {
if (props.columns.length === 0) {
return (
<TableIconWrapper disabled>
<IconWrapper width={20} height={20} color={Colors.CADET_BLUE}>
<IconWrapper color={Colors.CADET_BLUE} height={20} width={20}>
<FilterIcon />
</IconWrapper>
</TableIconWrapper>
@ -163,20 +163,18 @@ const TableFilters = (props: TableFilterProps) => {
);
return (
<Popover
minimal
usePortal
enforceFocus={false}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM}
isOpen={selected}
minimal
onClose={() => {
selectMenu(false);
}}
isOpen={selected}
position={Position.BOTTOM}
usePortal
>
<TableActionIcon
tooltip="Filters"
className="t--table-filter-toggle-btn"
selected={selected}
icon={
hasAnyFilters ? (
<SelectedFilterWrapper>{filters.length}</SelectedFilterWrapper>
@ -185,6 +183,8 @@ const TableFilters = (props: TableFilterProps) => {
selectMenu={(selected: boolean) => {
selectMenu(selected);
}}
selected={selected}
tooltip="Filters"
>
<FilterIcon />
</TableActionIcon>
@ -193,16 +193,6 @@ const TableFilters = (props: TableFilterProps) => {
{filters.map((filter: ReactTableFilter, index: number) => {
return (
<CascadeFields
key={index}
index={index}
operator={
filters.length >= 2 ? filters[1].operator : filter.operator
}
column={filter.column}
condition={filter.condition}
value={filter.value}
columns={columns}
hasAnyFilters={hasAnyFilters}
applyFilter={(filter: ReactTableFilter, index: number) => {
const updatedFilters = props.filters
? [...props.filters]
@ -210,6 +200,15 @@ const TableFilters = (props: TableFilterProps) => {
updatedFilters[index] = filter;
props.applyFilter(updatedFilters);
}}
column={filter.column}
columns={columns}
condition={filter.condition}
hasAnyFilters={hasAnyFilters}
index={index}
key={index}
operator={
filters.length >= 2 ? filters[1].operator : filter.operator
}
removeFilter={(index: number) => {
const filters: ReactTableFilter[] = props.filters || [];
if (index === 1 && filters.length > 2) {
@ -221,18 +220,19 @@ const TableFilters = (props: TableFilterProps) => {
];
props.applyFilter(newFilters);
}}
value={filter.value}
/>
);
})}
{hasAnyFilters ? (
<ButtonWrapper className={Classes.POPOVER_DISMISS}>
<Button
intent="primary"
text="Add Filter"
size="small"
onClick={addFilter}
icon="plus"
className="t--add-filter-btn"
icon="plus"
intent="primary"
onClick={addFilter}
size="small"
text="Add Filter"
/>
</ButtonWrapper>
) : null}
@ -245,6 +245,6 @@ const TableFilters = (props: TableFilterProps) => {
</TableFilterOuterWrapper>
</Popover>
);
};
}
export default TableFilters;

View File

@ -41,25 +41,24 @@ const PageNumberInputWrapper = styled(NumericInput)`
margin: 0 8px;
`;
const PageNumberInput = (props: {
function PageNumberInput(props: {
pageNo: number;
pageCount: number;
updatePageNo: (pageNo: number, event?: EventType) => void;
disabled: boolean;
}) => {
}) {
const [pageNumber, setPageNumber] = React.useState(props.pageNo || 0);
useEffect(() => {
setPageNumber(props.pageNo || 0);
}, [props.pageNo]);
return (
<PageNumberInputWrapper
value={pageNumber}
min={1}
max={props.pageCount || 1}
buttonPosition="none"
clampValueOnBlur
className="t--table-widget-page-input"
disabled={props.disabled}
max={props.pageCount || 1}
min={1}
onBlur={(e: any) => {
const oldPageNo = Number(props.pageNo || 0);
const value = e.target.value;
@ -82,9 +81,10 @@ const PageNumberInput = (props: {
setPageNumber(value);
}
}}
value={pageNumber}
/>
);
};
}
interface TableHeaderProps {
updatePageNo: (pageNo: number, event?: EventType) => void;
@ -111,32 +111,32 @@ interface TableHeaderProps {
tableSizes: TableSizes;
}
const TableHeader = (props: TableHeaderProps) => {
function TableHeader(props: TableHeaderProps) {
const tableHeaderWrapperRef = React.createRef<HTMLDivElement>();
return (
<TableHeaderWrapper
serverSidePaginationEnabled={props.serverSidePaginationEnabled}
width={props.width}
tableSizes={props.tableSizes}
backgroundColor={Colors.WHITE}
ref={tableHeaderWrapperRef}
serverSidePaginationEnabled={props.serverSidePaginationEnabled}
tableSizes={props.tableSizes}
width={props.width}
>
<SearchComponent
value={props.searchKey}
placeholder="Search..."
onSearch={props.searchTableData}
placeholder="Search..."
value={props.searchKey}
/>
<CommonFunctionsMenuWrapper tableSizes={props.tableSizes}>
<TableFilters
columns={props.columns}
filters={props.filters}
applyFilter={props.applyFilter}
columns={props.columns}
editMode={props.editMode}
filters={props.filters}
/>
<TableDataDownload
data={props.tableData}
columns={props.tableColumns}
data={props.tableData}
widgetName={props.widgetName}
/>
<TableCompactMode
@ -153,9 +153,9 @@ const TableHeader = (props: TableHeaderProps) => {
props.prevPageClick();
}}
>
<Icon icon="chevron-left" iconSize={16} color={Colors.HIT_GRAY} />
<Icon color={Colors.HIT_GRAY} icon="chevron-left" iconSize={16} />
</PaginationItemWrapper>
<PaginationItemWrapper selected className="page-item">
<PaginationItemWrapper className="page-item" selected>
{props.pageNo + 1}
</PaginationItemWrapper>
<PaginationItemWrapper
@ -165,7 +165,7 @@ const TableHeader = (props: TableHeaderProps) => {
props.nextPageClick();
}}
>
<Icon icon="chevron-right" iconSize={16} color={Colors.HIT_GRAY} />
<Icon color={Colors.HIT_GRAY} icon="chevron-right" iconSize={16} />
</PaginationItemWrapper>
</PaginationWrapper>
)}
@ -183,15 +183,15 @@ const TableHeader = (props: TableHeaderProps) => {
props.updatePageNo(pageNo + 1, EventType.ON_PREV_PAGE);
}}
>
<Icon icon="chevron-left" iconSize={16} color={Colors.HIT_GRAY} />
<Icon color={Colors.HIT_GRAY} icon="chevron-left" iconSize={16} />
</PaginationItemWrapper>
<RowWrapper>
Page{" "}
<PageNumberInput
disabled={props.pageCount === 1}
pageCount={props.pageCount}
pageNo={props.pageNo + 1}
updatePageNo={props.updatePageNo}
pageCount={props.pageCount}
disabled={props.pageCount === 1}
/>{" "}
of {props.pageCount}
</RowWrapper>
@ -206,13 +206,13 @@ const TableHeader = (props: TableHeaderProps) => {
props.updatePageNo(pageNo + 1, EventType.ON_NEXT_PAGE);
}}
>
<Icon icon="chevron-right" iconSize={16} color={Colors.HIT_GRAY} />
<Icon color={Colors.HIT_GRAY} icon="chevron-right" iconSize={16} />
</PaginationItemWrapper>
</PaginationWrapper>
)}
<ScrollIndicator containerRef={tableHeaderWrapperRef} mode="LIGHT" />
</TableHeaderWrapper>
);
};
}
export default TableHeader;

View File

@ -17,14 +17,14 @@ function PagerIcon(props: {
return (
<Icon
className={props.className}
icon={props.icon}
iconSize={14}
onClick={props.onClick as any}
style={{
padding: 14,
marginTop: 5,
}}
icon={props.icon}
iconSize={14}
onClick={props.onClick as any}
></Icon>
/>
);
}
interface PagerProps {
@ -46,14 +46,14 @@ export function TablePagination(props: PagerProps) {
<PagerContainer className={"e-control e-pager e-lib"}>
<PageWrapper>
<PagerIcon
icon={"chevron-left"}
onClick={props.prevPageClick}
className={
props.pageNo <= 1
? "e-prev e-icons e-icon-prev e-prevpagedisabled e-disable"
: "e-prev e-icons e-icon-prev e-prevpage"
}
></PagerIcon>
icon={"chevron-left"}
onClick={props.prevPageClick}
/>
<div
className={"e-numericcontainer"}
style={{
@ -71,7 +71,7 @@ export function TablePagination(props: PagerProps) {
className={"e-next e-icons e-icon-next e-nextpage"}
icon={"chevron-right"}
onClick={props.nextPageClick}
></PagerIcon>
/>
</PageWrapper>
</PagerContainer>
);

View File

@ -283,6 +283,18 @@ const ALIGN_ITEMS = {
BOTTOM: "flex-end",
};
const IMAGE_HORIZONTAL_ALIGN = {
LEFT: "left",
CENTER: "center",
RIGHT: "right",
};
const IMAGE_VERTICAL_ALIGN = {
TOP: "top",
CENTER: "center",
BOTTOM: "bottom",
};
export const TableStyles = css<{ cellProperties?: CellLayoutProperties }>`
font-weight: ${(props) =>
props?.cellProperties?.fontStyle?.includes(FontStyleTypes.BOLD)
@ -343,7 +355,12 @@ export const CellWrapper = styled.div<{
height: 100%;
margin: 0 5px 0 0;
border-radius: 4px;
background-position: start;
background-position-x: ${(props) =>
props?.cellProperties?.horizontalAlignment &&
IMAGE_HORIZONTAL_ALIGN[props?.cellProperties?.horizontalAlignment]};
background-position-y: ${(props) =>
props?.cellProperties?.verticalAlignment &&
IMAGE_VERTICAL_ALIGN[props?.cellProperties?.verticalAlignment]};
background-repeat: no-repeat;
background-size: contain;
}
@ -450,7 +467,6 @@ export const RenderOptionWrapper = styled.div<{ selected: boolean }>`
justify-content: space-between;
align-items: center;
width: 150px;
background: ${(props) => props.selected && Colors.GREEN};
position: relative;
.title {
color: ${(props) => (props.selected ? Colors.WHITE : Colors.OXFORD_BLUE)};

View File

@ -40,10 +40,7 @@ export const renderCell = (
case ColumnTypes.IMAGE:
if (!value) {
return (
<CellWrapper
cellProperties={cellProperties}
isHidden={isHidden}
></CellWrapper>
<CellWrapper cellProperties={cellProperties} isHidden={isHidden} />
);
} else if (!isString(value)) {
return (
@ -64,12 +61,12 @@ export const renderCell = (
if (imageUrlRegex.test(item) || base64ImageRegex.test(item)) {
return (
<a
onClick={(e) => e.stopPropagation()}
target="_blank"
rel="noopener noreferrer"
className="image-cell-wrapper"
href={item}
key={index}
onClick={(e) => e.stopPropagation()}
rel="noopener noreferrer"
target="_blank"
>
<div
className="image-cell"
@ -87,17 +84,14 @@ export const renderCell = (
const youtubeRegex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=|\?v=)([^#&?]*).*/;
if (!value) {
return (
<CellWrapper
cellProperties={cellProperties}
isHidden={isHidden}
></CellWrapper>
<CellWrapper cellProperties={cellProperties} isHidden={isHidden} />
);
} else if (isString(value) && youtubeRegex.test(value)) {
return (
<CellWrapper
cellProperties={cellProperties}
isHidden={isHidden}
className="video-cell"
isHidden={isHidden}
>
<PopoverVideo url={value} />
</CellWrapper>
@ -112,11 +106,11 @@ export const renderCell = (
default:
return (
<AutoToolTipComponent
title={value.toString()}
isHidden={isHidden}
cellProperties={cellProperties}
tableWidth={tableWidth}
columnType={columnType}
isHidden={isHidden}
tableWidth={tableWidth}
title={value.toString()}
>
{value.toString()}
</AutoToolTipComponent>
@ -138,23 +132,18 @@ export const renderActions = (
cellProperties: CellLayoutProperties,
) => {
if (!props.columnActions)
return (
<CellWrapper
cellProperties={cellProperties}
isHidden={isHidden}
></CellWrapper>
);
return <CellWrapper cellProperties={cellProperties} isHidden={isHidden} />;
return (
<CellWrapper cellProperties={cellProperties} isHidden={isHidden}>
{props.columnActions.map((action: ColumnAction, index: number) => {
return (
<TableAction
key={index}
action={action}
isSelected={props.isSelected}
backgroundColor={props.backgroundColor}
buttonLabelColor={props.buttonLabelColor}
isSelected={props.isSelected}
key={index}
onCommandClick={props.onCommandClick}
/>
);
@ -163,13 +152,13 @@ export const renderActions = (
);
};
const TableAction = (props: {
function TableAction(props: {
isSelected: boolean;
action: ColumnAction;
backgroundColor: string;
buttonLabelColor: string;
onCommandClick: (dynamicTrigger: string, onComplete: () => void) => void;
}) => {
}) {
const [loading, setLoading] = useState(false);
const onComplete = () => {
setLoading(false);
@ -186,19 +175,19 @@ const TableAction = (props: {
}}
>
<Button
filled
intent="PRIMARY_BUTTON"
loading={loading}
onClick={() => {
setLoading(true);
props.onCommandClick(props.action.dynamicTrigger, onComplete);
}}
text={props.action.label}
filled
size="small"
text={props.action.label}
/>
</ActionWrapper>
);
};
}
export const renderEmptyRows = (
rowCount: number,
@ -227,7 +216,7 @@ export const renderEmptyRows = (
? columns
: new Array(3).fill({ width: tableWidth / 3, isHidden: false });
return (
<React.Fragment>
<>
{rows.map((row: string, index: number) => {
return (
<div
@ -241,8 +230,8 @@ export const renderEmptyRows = (
{tableColumns.map((column: any, colIndex: number) => {
return (
<div
key={colIndex}
className="td"
key={colIndex}
style={{
width: column.width + "px",
boxSizing: "border-box",
@ -254,7 +243,7 @@ export const renderEmptyRows = (
</div>
);
})}
</React.Fragment>
</>
);
};
@ -283,7 +272,7 @@ const DescendingIcon = styled(ControlIcons.SORT_CONTROL as AnyStyledComponent)`
}
`;
export const TableHeaderCell = (props: {
export function TableHeaderCell(props: {
columnName: string;
columnIndex: number;
isHidden: boolean;
@ -291,7 +280,7 @@ export const TableHeaderCell = (props: {
sortTableColumn: (columnIndex: number, asc: boolean) => void;
isResizingColumn: boolean;
column: any;
}) => {
}) {
const { column } = props;
const handleSortColumn = () => {
if (props.isResizingColumn) return;
@ -320,7 +309,6 @@ export const TableHeaderCell = (props: {
</SortIconWrapper>
) : null}
<DraggableHeaderWrapper
horizontalAlignment={column.columnProperties.horizontalAlignment}
className={
!props.isHidden
? `draggable-header ${
@ -328,6 +316,7 @@ export const TableHeaderCell = (props: {
}`
: "hidden-header"
}
horizontalAlignment={column.columnProperties.horizontalAlignment}
>
{props.columnName}
</DraggableHeaderWrapper>
@ -341,7 +330,7 @@ export const TableHeaderCell = (props: {
/>
</div>
);
};
}
export function getDefaultColumnProperties(
accessor: string,
@ -445,8 +434,8 @@ export const renderDropdown = (props: {
const isSelected: boolean = isOptionSelected(option);
return (
<MenuItem
className="single-select"
active={isSelected}
className="single-select"
key={option.value}
onClick={itemProps.handleClick}
text={option.label}
@ -455,14 +444,15 @@ export const renderDropdown = (props: {
};
return (
<div
style={{ height: "100%" }}
onClick={(e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
}}
style={{ height: "100%" }}
>
<StyledSingleDropDown
items={props.options}
filterable={false}
itemRenderer={renderSingleSelectItem}
items={props.options}
onItemSelect={(item: DropdownOption) => {
props.onItemSelect(props.onOptionChange, item);
}}
@ -471,7 +461,6 @@ export const renderDropdown = (props: {
usePortal: true,
popoverClassName: "select-popover-wrapper",
}}
filterable={false}
>
<BButton
rightIcon={IconNames.CHEVRON_DOWN}

View File

@ -67,7 +67,7 @@ interface ReactTableComponentProps {
updateCompactMode: (compactMode: CompactMode) => void;
}
const ReactTableComponent = (props: ReactTableComponentProps) => {
function ReactTableComponent(props: ReactTableComponentProps) {
const { columnOrder, hiddenColumns } = useMemo(() => {
const order: string[] = [];
const hidden: string[] = [];
@ -181,45 +181,45 @@ const ReactTableComponent = (props: ReactTableComponentProps) => {
return (
<Table
isLoading={props.isLoading}
width={props.width}
height={props.height}
pageSize={props.pageSize || 1}
widgetId={props.widgetId}
widgetName={props.widgetName}
searchKey={props.searchKey}
columns={props.columns}
applyFilter={props.applyFilter}
columnSizeMap={props.columnSizeMap}
columns={props.columns}
compactMode={props.compactMode}
data={props.tableData}
editMode={props.editMode}
handleResizeColumn={props.handleResizeColumn}
sortTableColumn={sortTableColumn}
selectTableRow={selectTableRow}
pageNo={props.pageNo - 1}
updatePageNo={props.updatePageNo}
triggerRowSelection={props.triggerRowSelection}
nextPageClick={() => {
props.nextPageClick();
}}
prevPageClick={() => {
props.prevPageClick();
}}
serverSidePaginationEnabled={props.serverSidePaginationEnabled}
selectedRowIndex={props.selectedRowIndex}
selectedRowIndices={props.selectedRowIndices}
disableDrag={() => {
props.disableDrag(true);
}}
editMode={props.editMode}
enableDrag={() => {
props.disableDrag(false);
}}
searchTableData={props.searchTableData}
filters={props.filters}
applyFilter={props.applyFilter}
compactMode={props.compactMode}
handleResizeColumn={props.handleResizeColumn}
height={props.height}
isLoading={props.isLoading}
nextPageClick={() => {
props.nextPageClick();
}}
pageNo={props.pageNo - 1}
pageSize={props.pageSize || 1}
prevPageClick={() => {
props.prevPageClick();
}}
searchKey={props.searchKey}
searchTableData={props.searchTableData}
selectTableRow={selectTableRow}
selectedRowIndex={props.selectedRowIndex}
selectedRowIndices={props.selectedRowIndices}
serverSidePaginationEnabled={props.serverSidePaginationEnabled}
sortTableColumn={sortTableColumn}
triggerRowSelection={props.triggerRowSelection}
updateCompactMode={props.updateCompactMode}
updatePageNo={props.updatePageNo}
widgetId={props.widgetId}
widgetName={props.widgetName}
width={props.width}
/>
);
};
}
export default ReactTableComponent;

View File

@ -112,7 +112,7 @@ const StyledText = styled.div<TabProps>`
}
`;
const TabsComponent = (props: TabsComponentProps) => {
function TabsComponent(props: TabsComponentProps) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { onTabChange, ...remainingProps } = props;
const tabContainerRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
@ -132,12 +132,12 @@ const TabsComponent = (props: TabsComponentProps) => {
{props.tabs.map((tab, index) => (
<StyledText
className={`t--tab-${tab.label}`}
key={index}
onClick={(event: React.MouseEvent<HTMLDivElement>) => {
onTabChange(tab.widgetId);
event.stopPropagation();
}}
selected={props.selectedTabWidgetId === tab.widgetId}
key={index}
>
{tab.label}
</StyledText>
@ -160,6 +160,6 @@ const TabsComponent = (props: TabsComponentProps) => {
</ChildrenWrapper>
</TabsContainerWrapper>
);
};
}
export default TabsComponent;

View File

@ -126,14 +126,14 @@ export class BaseTextInput extends Component<TextInputProps, TextInputState> {
return (
<InputContainer className={className}>
<ErrorTooltip message={meta ? meta.error : ""} isOpen={errorIsOpen}>
<ErrorTooltip isOpen={errorIsOpen} message={meta ? meta.error : ""}>
<TextInput
hasError={hasError}
inputRef={refHandler}
{...input}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
autoComplete={"off"}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
{...rest}
/>
</ErrorTooltip>
@ -146,8 +146,8 @@ export class BaseTextInput extends Component<TextInputProps, TextInputState> {
* Text Input Component
* Has Icon, placholder, errors, etc.
*/
const TextInputComponent = (props: TextInputProps & ComponentProps) => {
function TextInputComponent(props: TextInputProps & ComponentProps) {
return <BaseTextInput {...props} />;
};
}
export default TextInputComponent;

View File

@ -42,31 +42,27 @@ export default function VideoComponent(props: VideoComponentProps) {
onError,
player,
} = props;
return (
<>
{url ? (
<ReactPlayer
url={url}
ref={player}
playing={autoplay}
controls={controls || true}
onStart={onStart}
onPlay={onPlay}
onPause={onPause}
onEnded={onEnded}
onReady={onReady}
onProgress={onProgress}
onSeek={onSeek}
onError={onError}
width="100%"
height="100%"
pip={false}
/>
) : (
<ErrorContainer>
<Error>{createMessage(ENTER_VIDEO_URL)}</Error>
</ErrorContainer>
)}
</>
return url ? (
<ReactPlayer
controls={controls || true}
height="100%"
onEnded={onEnded}
onError={onError}
onPause={onPause}
onPlay={onPlay}
onProgress={onProgress}
onReady={onReady}
onSeek={onSeek}
onStart={onStart}
pip={false}
playing={autoplay}
ref={player}
url={url}
width="100%"
/>
) : (
<ErrorContainer>
<Error>{createMessage(ENTER_VIDEO_URL)}</Error>
</ErrorContainer>
);
}

View File

@ -46,28 +46,26 @@ export const DeployLinkButton = withTheme((props: Props) => {
};
return (
<React.Fragment>
<Popover
modifiers={{ offset: { enabled: true, offset: "0, -3" } }}
content={
<DeployLinkDialog>
<DeployLink target="_blank" href={props.link}>
<DeployUrl>Current deployed version</DeployUrl>
<Icon
icon="share"
color={props.theme.colors.header.deployToolTipText}
/>
</DeployLink>
</DeployLinkDialog>
}
canEscapeKeyClose={false}
onClose={onClose}
isOpen={isOpen}
position={PopoverPosition.BOTTOM_RIGHT}
>
<div onClick={() => setIsOpen(true)}>{props.trigger}</div>
</Popover>
</React.Fragment>
<Popover
canEscapeKeyClose={false}
content={
<DeployLinkDialog>
<DeployLink href={props.link} target="_blank">
<DeployUrl>Current deployed version</DeployUrl>
<Icon
color={props.theme.colors.header.deployToolTipText}
icon="share"
/>
</DeployLink>
</DeployLinkDialog>
}
isOpen={isOpen}
modifiers={{ offset: { enabled: true, offset: "0, -3" } }}
onClose={onClose}
position={PopoverPosition.BOTTOM_RIGHT}
>
<div onClick={() => setIsOpen(true)}>{props.trigger}</div>
</Popover>
);
});

View File

@ -56,7 +56,7 @@ type Props = {
className?: string;
};
const ThreeDotLoading = (props: Props) => {
function ThreeDotLoading(props: Props) {
return (
<Spinner className={props.className}>
<div className="bounce1" />
@ -64,6 +64,6 @@ const ThreeDotLoading = (props: Props) => {
<div className="bounce3" />
</Spinner>
);
};
}
export default ThreeDotLoading;

View File

@ -45,7 +45,7 @@ export default function CollapsibleHelp(props: CollapsibleHelpProps) {
return (
<Container>
<LeftBar />
<HelpIcon color={"#FDEBE8"} icon="help"></HelpIcon>
<HelpIcon color={"#FDEBE8"} icon="help" />
<div>{props.children}</div>
</Container>
);

View File

@ -84,7 +84,7 @@ const StyledDiscordIcon = styled(DiscordIcon)`
}
`;
const Hit = (props: { hit: { path: string } }) => {
function Hit(props: { hit: { path: string } }) {
return (
<div
className="t--docHit"
@ -93,7 +93,7 @@ const Hit = (props: { hit: { path: string } }) => {
}}
>
<div className="hit-name t--docHitTitle">
<StyledDocumentIcon width={11.2} height={14} color="#181F24" />
<StyledDocumentIcon color="#181F24" height={14} width={11.2} />
<Highlight attribute="title" hit={props.hit} />
<StyledOpenLinkIcon
className="t--docOpenLink open-link"
@ -102,12 +102,12 @@ const Hit = (props: { hit: { path: string } }) => {
</div>
</div>
);
};
}
const DefaultHelpMenuItem = (props: {
function DefaultHelpMenuItem(props: {
item: { label: string; link?: string; id?: string; icon: React.ReactNode };
onSelect: () => void;
}) => {
}) {
return (
<li className="ais-Hits-item">
<div
@ -134,7 +134,7 @@ const DefaultHelpMenuItem = (props: {
</div>
</li>
);
};
}
const SearchContainer = styled.div`
height: 100%;
@ -322,22 +322,22 @@ type HelpItem = {
const HELP_MENU_ITEMS: HelpItem[] = [
{
icon: <StyledDocumentIcon width={11.2} height={14} color="#181F24" />,
icon: <StyledDocumentIcon color="#181F24" height={14} width={11.2} />,
label: "Documentation",
link: "https://docs.appsmith.com/",
},
{
icon: <StyledGithubIcon width={11.2} height={14} color="#fff" />,
icon: <StyledGithubIcon color="#fff" height={14} width={11.2} />,
label: "Report a bug",
link: "https://github.com/appsmithorg/appsmith/issues/new/choose",
},
{
icon: <StyledChatIcon width={11.2} height={14} color="#fff" />,
icon: <StyledChatIcon color="#fff" height={14} width={11.2} />,
label: "Chat with us",
link: "https://github.com/appsmithorg/appsmith/discussions",
},
{
icon: <StyledDiscordIcon width={16} height={16} />,
icon: <StyledDiscordIcon height={16} width={16} />,
label: "Join our Discord",
link: "https://discord.gg/rBTTVJp",
},
@ -345,7 +345,7 @@ const HELP_MENU_ITEMS: HelpItem[] = [
if (cloudHosting) {
HELP_MENU_ITEMS[2] = {
icon: <StyledChatIcon width={11.2} height={14} color="#fff" />,
icon: <StyledChatIcon color="#fff" height={14} width={11.2} />,
label: "Chat with us",
id: "intercom-trigger",
};
@ -394,6 +394,10 @@ class DocumentationSearch extends React.Component<Props, State> {
{!this.props.hideMinimizeBtn && (
<Icon
className="t--docsMinimize"
color="white"
icon="minus"
iconSize={14}
onClick={this.handleClose}
style={{
position: "absolute",
top: 6,
@ -401,10 +405,6 @@ class DocumentationSearch extends React.Component<Props, State> {
cursor: "pointer",
zIndex: 1,
}}
icon="minus"
color="white"
iconSize={14}
onClick={this.handleClose}
/>
)}
<InstantSearch
@ -417,8 +417,8 @@ class DocumentationSearch extends React.Component<Props, State> {
<Header>
<StyledPoweredBy />
<SearchBox
onChange={this.onSearchValueChange}
defaultRefinement={this.props.defaultRefinement}
onChange={this.onSearchValueChange}
/>
</Header>
)}
@ -429,8 +429,8 @@ class DocumentationSearch extends React.Component<Props, State> {
<ul className="ais-Hits-list">
{HELP_MENU_ITEMS.map((item) => (
<DefaultHelpMenuItem
key={item.label}
item={item}
key={item.label}
onSelect={this.handleClose}
/>
))}

View File

@ -100,17 +100,17 @@ class HelpModal extends React.Component<Props> {
<>
{isHelpModalOpen && (
<ModalComponent
canOutsideClickClose
canEscapeKeyClose
scrollContents
height={MODAL_HEIGHT}
width={MODAL_WIDTH}
top={window.innerHeight - MODAL_BOTTOM_DISTANCE - MODAL_HEIGHT}
left={window.innerWidth - MODAL_RIGHT_DISTANCE - MODAL_WIDTH}
canOutsideClickClose
data-cy={"help-modal"}
hasBackDrop={false}
onClose={this.onClose}
height={MODAL_HEIGHT}
isOpen
left={window.innerWidth - MODAL_RIGHT_DISTANCE - MODAL_WIDTH}
onClose={this.onClose}
scrollContents
top={window.innerHeight - MODAL_BOTTOM_DISTANCE - MODAL_HEIGHT}
width={MODAL_WIDTH}
zIndex={layers.help}
>
<DocumentationSearch hitsPerPage={4} />

View File

@ -121,9 +121,9 @@ type ButtonStyleProps = {
};
// To be used in any other part of the app
export const BaseButton = (props: IButtonProps & ButtonStyleProps) => {
export function BaseButton(props: IButtonProps & ButtonStyleProps) {
return <ButtonWrapper {...props} />;
};
}
BaseButton.defaultProps = {
accent: "secondary",
@ -167,12 +167,12 @@ const mapButtonStyleToStyleName = (buttonStyle?: ButtonStyle) => {
}
};
const RecaptchaComponent = (
function RecaptchaComponent(
props: {
children: any;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
} & RecaptchaProps,
) => {
) {
function handleError(event: React.MouseEvent<HTMLElement>, error: string) {
Toaster.show({
text: error,
@ -209,41 +209,41 @@ const RecaptchaComponent = (
{props.children}
</div>
);
};
}
const BtnWrapper = (
function BtnWrapper(
props: {
children: any;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
} & RecaptchaProps,
) => {
) {
if (!props.googleRecaptchaKey)
return <div onClick={props.onClick}>{props.children}</div>;
return <RecaptchaComponent {...props}></RecaptchaComponent>;
};
return <RecaptchaComponent {...props} />;
}
// To be used with the canvas
const ButtonContainer = (
function ButtonContainer(
props: ButtonContainerProps & ButtonStyleProps & RecaptchaProps,
) => {
) {
return (
<BtnWrapper
googleRecaptchaKey={props.googleRecaptchaKey}
clickWithRecaptcha={props.clickWithRecaptcha}
googleRecaptchaKey={props.googleRecaptchaKey}
onClick={props.onClick}
>
<BaseButton
loading={props.isLoading}
icon={props.icon}
rightIcon={props.rightIcon}
text={props.text}
filled={props.buttonStyle !== "SECONDARY_BUTTON"}
accent={mapButtonStyleToStyleName(props.buttonStyle)}
disabled={props.disabled}
filled={props.buttonStyle !== "SECONDARY_BUTTON"}
icon={props.icon}
loading={props.isLoading}
rightIcon={props.rightIcon}
text={props.text}
type={props.type}
/>
</BtnWrapper>
);
};
}
export default ButtonContainer;

View File

@ -36,19 +36,19 @@ class CheckboxComponent extends React.Component<CheckboxComponentProps> {
this.props.alignWidget === "RIGHT" ? Alignment.RIGHT : Alignment.LEFT;
return (
<CheckboxContainer
isValid={!(this.props.isRequired && !this.props.isChecked)}
className={checkboxAlignClass}
isValid={!(this.props.isRequired && !this.props.isChecked)}
>
<Checkbox
label={this.props.label}
alignIndicator={checkboxAlignClass}
checked={this.props.isChecked}
className={
this.props.isLoading ? Classes.SKELETON : Classes.RUNNING_TEXT
}
style={{ borderRadius: 0 }}
onChange={this.onCheckChange}
disabled={this.props.isDisabled}
checked={this.props.isChecked}
label={this.props.label}
onChange={this.onCheckChange}
style={{ borderRadius: 0 }}
/>
</CheckboxContainer>
);

View File

@ -22,13 +22,13 @@ const StyledButton = styled(Button)<CloseButtonProps>`
}
`;
export const CloseButton = (props: CloseButtonProps) => {
export function CloseButton(props: CloseButtonProps) {
return (
<StyledButton
className={props.className}
{...props}
rightIcon="cross"
minimal
rightIcon="cross"
/>
);
};
}

View File

@ -141,17 +141,17 @@ class DatePickerComponent extends React.Component<
>
<DateInput
className={this.props.isLoading ? "bp3-skeleton" : ""}
closeOnSelection
disabled={this.props.isDisabled}
formatDate={this.formatDate}
maxDate={maxDate}
minDate={minDate}
onChange={this.onDateSelected}
parseDate={this.parseDate}
placeholder={"Select Date"}
disabled={this.props.isDisabled}
showActionsBar={true}
showActionsBar
timePrecision={TimePrecision.MINUTE}
closeOnSelection
onChange={this.onDateSelected}
value={value}
minDate={minDate}
maxDate={maxDate}
/>
</ErrorTooltip>
}

View File

@ -142,17 +142,17 @@ class DatePickerComponent extends React.Component<
>
<DateInput
className={this.props.isLoading ? "bp3-skeleton" : ""}
closeOnSelection
disabled={this.props.isDisabled}
formatDate={this.formatDate}
maxDate={maxDate}
minDate={minDate}
onChange={this.onDateSelected}
parseDate={this.parseDate}
placeholder={"Select Date"}
disabled={this.props.isDisabled}
showActionsBar={true}
showActionsBar
timePrecision={TimePrecision.MINUTE}
closeOnSelection
onChange={this.onDateSelected}
value={value}
minDate={minDate}
maxDate={maxDate}
/>
</ErrorTooltip>
}

View File

@ -258,17 +258,17 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
{this.props.selectionType === "SINGLE_SELECT" ? (
<StyledSingleDropDown
className={this.props.isLoading ? Classes.SKELETON : ""}
items={this.props.options}
filterable={true}
itemRenderer={this.renderSingleSelectItem}
onItemSelect={this.onItemSelect}
disabled={this.props.disabled}
filterable
itemListPredicate={this.itemListPredicate}
itemRenderer={this.renderSingleSelectItem}
items={this.props.options}
onItemSelect={this.onItemSelect}
popoverProps={{
minimal: true,
usePortal: true,
popoverClassName: "select-popover-wrapper",
}}
itemListPredicate={this.itemListPredicate}
>
<Button
rightIcon={IconNames.CHEVRON_DOWN}
@ -283,16 +283,22 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
</StyledSingleDropDown>
) : (
<StyledMultiDropDown
className={this.props.isLoading ? Classes.SKELETON : ""}
height={this.props.height}
hideCloseButtonIndex={hideCloseButtonIndex}
itemListPredicate={this.itemListPredicate}
itemRenderer={this.renderMultiSelectItem}
items={this.props.options}
onItemSelect={this.onItemSelect}
placeholder={this.props.placeholder}
popoverProps={{
minimal: true,
usePortal: true,
popoverClassName: "select-popover-wrapper",
}}
resetOnSelect
scrollToActiveItem={false}
className={this.props.isLoading ? Classes.SKELETON : ""}
items={this.props.options}
itemListPredicate={this.itemListPredicate}
placeholder={this.props.placeholder}
tagRenderer={this.renderTag}
itemRenderer={this.renderMultiSelectItem}
selectedItems={selectedItems}
height={this.props.height}
tagInputProps={{
onRemove: this.onItemRemoved,
tagProps: (value, index) => ({
@ -308,13 +314,7 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
fill: true,
rightElement: <Icon icon={IconNames.CHEVRON_DOWN} />,
}}
hideCloseButtonIndex={hideCloseButtonIndex}
onItemSelect={this.onItemSelect}
popoverProps={{
minimal: true,
usePortal: true,
popoverClassName: "select-popover-wrapper",
}}
tagRenderer={this.renderTag}
width={this.props.width}
/>
)}
@ -365,8 +365,8 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
const isSelected: boolean = this.isOptionSelected(option);
return (
<MenuItem
className="single-select"
active={isSelected}
className="single-select"
key={option.value}
onClick={itemProps.handleClick}
text={option.label}
@ -383,19 +383,17 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
}
const isSelected: boolean = this.isOptionSelected(option);
const content: ReactNode = (
<React.Fragment>
<StyledCheckbox
checked={isSelected}
label={option.label}
alignIndicator="left"
onChange={(e: any) => itemProps.handleClick(e)}
/>
</React.Fragment>
<StyledCheckbox
alignIndicator="left"
checked={isSelected}
label={option.label}
onChange={(e: any) => itemProps.handleClick(e)}
/>
);
return (
<MenuItem
className="multi-select"
active={isSelected}
className="multi-select"
key={option.value}
text={content}
/>

View File

@ -169,39 +169,39 @@ class InputComponent extends React.Component<
private numericInputComponent = () => (
<NumericInput
value={this.props.value}
placeholder={this.props.placeholder}
min={this.props.minNum}
max={this.props.maxNum}
maxLength={this.props.maxChars}
allowNumericCharactersOnly
className={this.props.isLoading ? "bp3-skeleton" : Classes.FILL}
disabled={this.props.disabled}
intent={this.props.intent}
className={this.props.isLoading ? "bp3-skeleton" : Classes.FILL}
onValueChange={this.onNumberChange}
leftIcon={
this.props.inputType === "PHONE_NUMBER" ? "phone" : this.props.leftIcon
}
type={this.props.inputType === "PHONE_NUMBER" ? "tel" : undefined}
allowNumericCharactersOnly
stepSize={this.props.stepSize}
onFocus={() => this.setFocusState(true)}
max={this.props.maxNum}
maxLength={this.props.maxChars}
min={this.props.minNum}
onBlur={() => this.setFocusState(false)}
onFocus={() => this.setFocusState(true)}
onKeyDown={this.onKeyDown}
onValueChange={this.onNumberChange}
placeholder={this.props.placeholder}
stepSize={this.props.stepSize}
type={this.props.inputType === "PHONE_NUMBER" ? "tel" : undefined}
value={this.props.value}
/>
);
private textAreaInputComponent = () => (
<TextArea
value={this.props.value}
placeholder={this.props.placeholder}
disabled={this.props.disabled}
maxLength={this.props.maxChars}
intent={this.props.intent}
onChange={this.onTextChange}
className={this.props.isLoading ? "bp3-skeleton" : ""}
disabled={this.props.disabled}
growVertically={false}
onFocus={() => this.setFocusState(true)}
intent={this.props.intent}
maxLength={this.props.maxChars}
onBlur={() => this.setFocusState(false)}
onChange={this.onTextChange}
onFocus={() => this.setFocusState(true)}
onKeyDown={this.onKeyDownTextArea}
placeholder={this.props.placeholder}
value={this.props.value}
/>
);
@ -210,13 +210,15 @@ class InputComponent extends React.Component<
this.textAreaInputComponent()
) : (
<InputGroup
value={this.props.value}
placeholder={this.props.placeholder}
disabled={this.props.disabled}
maxLength={this.props.maxChars}
intent={this.props.intent}
onChange={this.onTextChange}
className={this.props.isLoading ? "bp3-skeleton" : ""}
disabled={this.props.disabled}
intent={this.props.intent}
maxLength={this.props.maxChars}
onBlur={() => this.setFocusState(false)}
onChange={this.onTextChange}
onFocus={() => this.setFocusState(true)}
onKeyDown={this.onKeyDown}
placeholder={this.props.placeholder}
rightElement={
this.props.inputType === "PASSWORD" ? (
<Button
@ -230,9 +232,7 @@ class InputComponent extends React.Component<
)
}
type={this.getType(this.props.inputType)}
onFocus={() => this.setFocusState(true)}
onBlur={() => this.setFocusState(false)}
onKeyDown={this.onKeyDown}
value={this.props.value}
/>
);
private renderInputComponent = (inputType: InputType, isTextArea: boolean) =>
@ -244,9 +244,9 @@ class InputComponent extends React.Component<
return (
<InputComponentWrapper
fill
hasError={this.props.isInvalid}
multiline={this.props.multiline.toString()}
numeric={this.isNumberInputType(this.props.inputType)}
hasError={this.props.isInvalid}
>
{this.props.label && (
<Label

View File

@ -65,7 +65,7 @@ export type ModalComponentProps = {
};
/* eslint-disable react/display-name */
export const ModalComponent = (props: ModalComponentProps) => {
export function ModalComponent(props: ModalComponentProps) {
const modalContentRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
null,
);
@ -76,29 +76,29 @@ export const ModalComponent = (props: ModalComponentProps) => {
}, [props.scrollContents]);
return (
<Container
width={props.width}
height={props.height}
top={props.top}
left={props.left}
top={props.top}
width={props.width}
zIndex={props.zIndex !== undefined ? props.zIndex : 2}
>
<Overlay
isOpen={props.isOpen}
onClose={props.onClose}
canOutsideClickClose={props.canOutsideClickClose}
canEscapeKeyClose={props.canEscapeKeyClose}
usePortal={false}
canOutsideClickClose={props.canOutsideClickClose}
enforceFocus={false}
hasBackdrop={
props.hasBackDrop !== undefined ? !!props.hasBackDrop : true
}
isOpen={props.isOpen}
onClose={props.onClose}
usePortal={false}
>
<div>
<Content
scroll={props.scrollContents}
className={`${getCanvasClassName()} ${props.className}`}
height={props.height}
ref={modalContentRef}
scroll={props.scrollContents}
>
{props.children}
</Content>
@ -106,6 +106,6 @@ export const ModalComponent = (props: ModalComponentProps) => {
</Overlay>
</Container>
);
};
}
export default ModalComponent;

View File

@ -48,17 +48,17 @@ class RadioGroupComponent extends React.Component<RadioGroupComponentProps> {
</Label>
)}
<StyledRadioGroup
selectedValue={this.props.selectedOptionValue}
onChange={this.onRadioSelectionChange}
disabled={this.props.isDisabled}
onChange={this.onRadioSelectionChange}
selectedValue={this.props.selectedOptionValue}
>
{this.props.options.map((option) => {
return (
<Radio
className={this.props.isLoading ? "bp3-skeleton" : ""}
key={option.value}
label={option.label}
value={option.value}
key={option.value}
/>
);
})}

View File

@ -6,9 +6,9 @@ class SpinnerComponent extends React.Component<SpinnerComponentProps> {
render() {
return (
<Spinner
intent={this.props.intent}
size={this.props.size}
value={this.props.value}
intent={this.props.intent}
/>
);
}

View File

@ -26,14 +26,14 @@ const SwitchComponentContainer = styled.div`
${BlueprintControlTransform}
`;
export const SwitchComponent: React.FC<SwitchComponentProps> = ({
export function SwitchComponent({
label,
isSwitchedOn,
alignWidget,
onChange,
isDisabled,
isLoading,
}) => {
}: SwitchComponentProps) {
const switchAlignClass =
alignWidget === "RIGHT" ? Alignment.RIGHT : Alignment.LEFT;
@ -41,8 +41,7 @@ export const SwitchComponent: React.FC<SwitchComponentProps> = ({
<SwitchComponentContainer className={switchAlignClass}>
<Switch
alignIndicator={switchAlignClass}
label={label}
disabled={isDisabled}
checked={isSwitchedOn}
className={
isLoading
? `${Classes.SKELETON} t--switch-widget-loading`
@ -52,9 +51,10 @@ export const SwitchComponent: React.FC<SwitchComponentProps> = ({
: "t--switch-widget-inactive"
}`
}
checked={isSwitchedOn}
disabled={isDisabled}
label={label}
onChange={() => onChange(!isSwitchedOn)}
/>
</SwitchComponentContainer>
);
};
}

View File

@ -57,6 +57,7 @@ export const StyledText = styled(Text)<{
font-size: ${(props) => props?.fontSize && TEXT_SIZES[props?.fontSize]};
span {
width: 100%;
line-height: 1.2;
}
`;
@ -86,14 +87,14 @@ class TextComponent extends React.Component<TextComponentProps> {
return (
<TextContainer>
<StyledText
scroll={!!this.props.shouldScroll}
textAlign={textAlign}
fontSize={fontSize}
ellipsize={ellipsize}
fontStyle={fontStyle}
textColor={textColor}
backgroundColor={backgroundColor}
className={this.props.isLoading ? "bp3-skeleton" : "bp3-ui-text"}
ellipsize={ellipsize}
fontSize={fontSize}
fontStyle={fontStyle}
scroll={!!this.props.shouldScroll}
textAlign={textAlign}
textColor={textColor}
>
<Interweave
content={text}

View File

@ -272,18 +272,18 @@ const views = {
[ViewTypes.SELECTOR_VIEW]: function SelectorView(props: SelectorViewProps) {
return (
<FieldWrapper>
<ControlWrapper key={props.label} isAction={true}>
<ControlWrapper isAction key={props.label}>
{props.label && <label>{props.label}</label>}
<TreeDropdown
optionTree={props.options}
selectedValue={props.get(props.value, false) as string}
defaultText={props.defaultText}
displayValue={props.displayValue}
getDefaults={props.getDefaults}
onSelect={(value, defaultValue?: string) => {
props.set(value, defaultValue);
}}
getDefaults={props.getDefaults}
optionTree={props.options}
selectedLabelModifier={props.selectedLabelModifier}
displayValue={props.displayValue}
selectedValue={props.get(props.value, false) as string}
/>
</ControlWrapper>
</FieldWrapper>
@ -291,10 +291,10 @@ const views = {
},
[ViewTypes.KEY_VALUE_VIEW]: function KeyValueView(props: KeyValueViewProps) {
return (
<ControlWrapper key={props.label} isAction={true}>
<ControlWrapper isAction key={props.label}>
<KeyValueComponent
pairs={props.get(props.value, false) as DropdownOption[]}
addLabel={"Query Params"}
pairs={props.get(props.value, false) as DropdownOption[]}
updatePairs={(pageParams: DropdownOption[]) => props.set(pageParams)}
/>
</ControlWrapper>
@ -303,11 +303,15 @@ const views = {
[ViewTypes.TEXT_VIEW]: function TextView(props: TextViewProps) {
return (
<FieldWrapper>
<ControlWrapper key={props.label} isAction={true}>
<ControlWrapper isAction key={props.label}>
{props.label && <label>{props.label}</label>}
<InputText
additionalAutocomplete={props.additionalAutoComplete}
errorMessage={props.validationMessage}
evaluatedValue={props.get(props.value, false) as string}
expected={"string"}
isValid={props.isValid}
label={props.label}
value={props.get(props.value, false) as string}
onChange={(event: any) => {
if (event.target) {
props.set(event.target.value);
@ -315,11 +319,7 @@ const views = {
props.set(event);
}
}}
expected={"string"}
evaluatedValue={props.get(props.value, false) as string}
isValid={props.isValid}
errorMessage={props.validationMessage}
additionalAutocomplete={props.additionalAutoComplete}
value={props.get(props.value, false) as string}
/>
</ControlWrapper>
</FieldWrapper>
@ -813,10 +813,10 @@ function renderField(props: {
? field.value
: undefined;
// eslint-disable-next-line react/display-name
selectedLabelModifier = (
selectedLabelModifier = function(
option: TreeDropdownOption,
displayValue?: string,
) => {
) {
if (
option.type === ActionType.api ||
option.type === ActionType.query
@ -976,7 +976,7 @@ function Fields(props: {
if (fields[0].field === FieldType.ACTION_SELECTOR_FIELD) {
const remainingFields = fields.slice(1);
return (
<React.Fragment>
<>
{renderField({
field: fields[0],
...otherProps,
@ -991,25 +991,25 @@ function Fields(props: {
return (
<li key={index}>
<Fields
value={selectorField.value}
fields={field}
label={selectorField.label}
isValid={props.isValid}
validationMessage={props.validationMessage}
additionalAutoComplete={props.additionalAutoComplete}
apiOptionTree={props.apiOptionTree}
widgetOptionTree={props.widgetOptionTree}
queryOptionTree={props.queryOptionTree}
modalDropdownList={props.modalDropdownList}
pageDropdownOptions={props.pageDropdownOptions}
depth={props.depth + 1}
fields={field}
isValid={props.isValid}
label={selectorField.label}
maxDepth={props.maxDepth}
modalDropdownList={props.modalDropdownList}
onValueChange={(value: any) => {
const parentValue = selectorField.getParentValue(
value.substring(2, value.length - 2),
);
props.onValueChange(parentValue);
}}
additionalAutoComplete={props.additionalAutoComplete}
pageDropdownOptions={props.pageDropdownOptions}
queryOptionTree={props.queryOptionTree}
validationMessage={props.validationMessage}
value={selectorField.value}
widgetOptionTree={props.widgetOptionTree}
/>
</li>
);
@ -1025,7 +1025,7 @@ function Fields(props: {
}
})}
</ul>
</React.Fragment>
</>
);
} else {
const ui = fields.map((field: any, index: number) => {
@ -1036,25 +1036,25 @@ function Fields(props: {
const selectorField = field[0];
return (
<Fields
key={index}
value={selectorField.value}
fields={field}
label={selectorField.label}
isValid={props.isValid}
validationMessage={props.validationMessage}
apiOptionTree={props.apiOptionTree}
widgetOptionTree={props.widgetOptionTree}
queryOptionTree={props.queryOptionTree}
modalDropdownList={props.modalDropdownList}
pageDropdownOptions={props.pageDropdownOptions}
depth={props.depth + 1}
fields={field}
isValid={props.isValid}
key={index}
label={selectorField.label}
maxDepth={props.maxDepth}
modalDropdownList={props.modalDropdownList}
onValueChange={(value: any) => {
const parentValue = selectorField.getParentValue(
value.substring(2, value.length - 2),
);
props.onValueChange(parentValue);
}}
pageDropdownOptions={props.pageDropdownOptions}
queryOptionTree={props.queryOptionTree}
validationMessage={props.validationMessage}
value={selectorField.value}
widgetOptionTree={props.widgetOptionTree}
/>
);
} else {
@ -1064,7 +1064,7 @@ function Fields(props: {
});
}
});
return <>{ui}</>;
return ui;
}
}
@ -1208,19 +1208,19 @@ export function ActionCreator(props: ActionCreatorProps) {
return (
<TreeStructure>
<Fields
value={props.value}
additionalAutoComplete={props.additionalAutoComplete}
apiOptionTree={apiOptionTree}
depth={1}
fields={fields}
isValid={props.isValid}
validationMessage={props.validationMessage}
apiOptionTree={apiOptionTree}
widgetOptionTree={widgetOptionTree}
queryOptionTree={queryOptionTree}
modalDropdownList={modalDropdownList}
pageDropdownOptions={pageDropdownOptions}
onValueChange={props.onValueChange}
depth={1}
maxDepth={1}
additionalAutoComplete={props.additionalAutoComplete}
modalDropdownList={modalDropdownList}
onValueChange={props.onValueChange}
pageDropdownOptions={pageDropdownOptions}
queryOptionTree={queryOptionTree}
validationMessage={props.validationMessage}
value={props.value}
widgetOptionTree={widgetOptionTree}
/>
</TreeStructure>
);

View File

@ -58,7 +58,7 @@ type ActionNameEditorProps = {
page?: string;
};
export const ActionNameEditor = (props: ActionNameEditorProps) => {
export function ActionNameEditor(props: ActionNameEditorProps) {
const params = useParams<{ apiId?: string; queryId?: string }>();
const isNew =
new URLSearchParams(window.location.search).get("editName") === "true";
@ -161,19 +161,19 @@ export const ActionNameEditor = (props: ActionNameEditorProps) => {
<NewEditableText
className="t--action-name-edit-field"
defaultValue={currentActionConfig ? currentActionConfig.name : ""}
placeholder="Name of the API in camelCase"
editInteractionKind={NewEditInteractionKind.SINGLE}
fill
forceDefault={forceUpdate}
onBlur={handleAPINameChange}
isInvalid={isInvalidActionName}
valueTransform={removeSpecialChars}
hideEditIcon
isEditingDefault={isNew && !hideEditIcon}
isInvalid={isInvalidActionName}
onBlur={handleAPINameChange}
placeholder="Name of the API in camelCase"
savingState={
saveStatus.isSaving ? SavingState.STARTED : SavingState.NOT_STARTED
}
editInteractionKind={NewEditInteractionKind.SINGLE}
hideEditIcon
underline
fill
valueTransform={removeSpecialChars}
/>
) : (
<div
@ -183,22 +183,22 @@ export const ActionNameEditor = (props: ActionNameEditorProps) => {
>
<EditableText
className="t--action-name-edit-field"
type="text"
defaultValue={currentActionConfig ? currentActionConfig.name : ""}
placeholder="Name of the API in camelCase"
forceDefault={forceUpdate}
onTextChanged={handleAPINameChange}
isInvalid={isInvalidActionName}
valueTransform={removeSpecialChars}
isEditingDefault={isNew}
updating={saveStatus.isSaving}
editInteractionKind={EditInteractionKind.SINGLE}
forceDefault={forceUpdate}
isEditingDefault={isNew}
isInvalid={isInvalidActionName}
onTextChanged={handleAPINameChange}
placeholder="Name of the API in camelCase"
type="text"
updating={saveStatus.isSaving}
valueTransform={removeSpecialChars}
/>
{saveStatus.isSaving && <Spinner size={16} />}
</div>
)}
</ApiNameWrapper>
);
};
}
export default ActionNameEditor;

View File

@ -156,7 +156,7 @@ const StatusCodeText = styled(BaseText)<{ code: string }>`
props.code.startsWith("2") ? props.theme.colors.primaryOld : Colors.RED};
`;
const ApiResponseView = (props: Props) => {
function ApiResponseView(props: Props) {
const {
match: {
params: { apiId },
@ -193,20 +193,18 @@ const ApiResponseView = (props: Props) => {
panelComponent: (
<ResponseTabWrapper>
{hasFailed && !isRunning && requestDebugVisible && (
<>
<Callout
text={createMessage(CHECK_REQUEST_BODY)}
label={
<FailedMessage>
<DebugButton onClick={onDebugClick} />
</FailedMessage>
}
variant={Variant.danger}
fill
closeButton
onClose={() => setRequestDebugVisible(false)}
/>
</>
<Callout
closeButton
fill
label={
<FailedMessage>
<DebugButton onClick={onDebugClick} />
</FailedMessage>
}
onClose={() => setRequestDebugVisible(false)}
text={createMessage(CHECK_REQUEST_BODY)}
variant={Variant.danger}
/>
)}
{_.isEmpty(response.statusCode) ? (
<NoResponseContainer>
@ -215,13 +213,13 @@ const ApiResponseView = (props: Props) => {
</NoResponseContainer>
) : (
<ReadOnlyEditor
folding
height={"100%"}
input={{
value: response.body
? JSON.stringify(response.body, null, 2)
: "",
}}
height={"100%"}
folding={true}
/>
)}
</ResponseTabWrapper>
@ -279,18 +277,28 @@ const ApiResponseView = (props: Props) => {
</Text>
</Flex>
)}
{!_.isEmpty(response.body) && Array.isArray(response.body) && (
<Flex>
<Text type={TextType.P3}>Result: </Text>
<Text type={TextType.H5}>
{`${response.body.length} Record${
response.body.length > 1 ? "s" : ""
}`}
</Text>
</Flex>
)}
</ResponseMetaInfo>
</ResponseMetaWrapper>
)}
<TabComponent
tabs={tabs}
selectedIndex={selectedIndex}
onSelect={setSelectedIndex}
selectedIndex={selectedIndex}
tabs={tabs}
/>
</TabbedViewWrapper>
</ResponseContainer>
);
};
}
const mapStateToProps = (state: AppState): ReduxStateProps => {
return {

Some files were not shown because too many files have changed in this diff Show More