PromucFlow_constructor/app/client/src/widgets/TableWidgetV2/component/Constants.ts
balajisoundar 694b17062b
feat: Table widget currency column (#27819)
## Description
Adds a new currency column type on the table widget.

#### PR fixes following issue(s)
Fixes #5632 
> if no issue exists, please create an issue and ask the maintainers
about this first
>
>
#### Media
> A video or a GIF is preferred. when using Loom, don’t embed because it
looks like it’s a GIF. instead, just link to the video
>
>
#### Type of change

- New feature (non-breaking change which adds functionality)
>
>
>
## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [x] Manual
- [ ] JUnit
- [ ] Jest
- [x] Cypress
>
>
#### Test Plan
> https://github.com/appsmithorg/TestSmith/issues/2447
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed
2023-11-06 11:05:26 +05:30

567 lines
13 KiB
TypeScript

import { isString } from "lodash";
import moment from "moment";
import type { IconName } from "@blueprintjs/icons";
import type { Alignment } from "@blueprintjs/core";
import type {
ButtonBorderRadius,
ButtonStyleType,
ButtonVariant,
} from "components/constants";
import type { DropdownOption } from "widgets/SelectWidget/constants";
import type {
ConfigureMenuItems,
MenuItem,
MenuItems,
MenuItemsSource,
} from "widgets/MenuButtonWidget/constants";
import type { ColumnTypes } from "../constants";
import type { TimePrecision } from "widgets/DatePickerWidget2/constants";
import { generateReactKey } from "widgets/WidgetUtils";
export interface TableSizes {
COLUMN_HEADER_HEIGHT: number;
TABLE_HEADER_HEIGHT: number;
ROW_HEIGHT: number;
ROW_FONT_SIZE: number;
VERTICAL_PADDING: number;
EDIT_ICON_TOP: number;
ROW_VIRTUAL_OFFSET: number;
VERTICAL_EDITOR_PADDING: number;
EDITABLE_CELL_HEIGHT: number;
}
export enum CompactModeTypes {
SHORT = "SHORT",
DEFAULT = "DEFAULT",
TALL = "TALL",
}
export enum CellAlignmentTypes {
LEFT = "LEFT",
RIGHT = "RIGHT",
CENTER = "CENTER",
}
export enum VerticalAlignmentTypes {
TOP = "TOP",
BOTTOM = "BOTTOM",
CENTER = "CENTER",
}
export enum ImageSizes {
DEFAULT = "32px",
MEDIUM = "64px",
LARGE = "128px",
}
export const TABLE_SIZES: { [key: string]: TableSizes } = {
[CompactModeTypes.DEFAULT]: {
COLUMN_HEADER_HEIGHT: 32,
TABLE_HEADER_HEIGHT: 40,
ROW_HEIGHT: 40,
ROW_FONT_SIZE: 14,
VERTICAL_PADDING: 6,
VERTICAL_EDITOR_PADDING: 0,
EDIT_ICON_TOP: 10,
ROW_VIRTUAL_OFFSET: 3,
EDITABLE_CELL_HEIGHT: 30,
},
[CompactModeTypes.SHORT]: {
COLUMN_HEADER_HEIGHT: 32,
TABLE_HEADER_HEIGHT: 40,
ROW_HEIGHT: 30,
ROW_FONT_SIZE: 12,
VERTICAL_PADDING: 0,
VERTICAL_EDITOR_PADDING: 0,
EDIT_ICON_TOP: 5,
ROW_VIRTUAL_OFFSET: 1,
EDITABLE_CELL_HEIGHT: 20,
},
[CompactModeTypes.TALL]: {
COLUMN_HEADER_HEIGHT: 32,
TABLE_HEADER_HEIGHT: 40,
ROW_HEIGHT: 60,
ROW_FONT_SIZE: 18,
VERTICAL_PADDING: 16,
VERTICAL_EDITOR_PADDING: 16,
EDIT_ICON_TOP: 21,
ROW_VIRTUAL_OFFSET: 3,
EDITABLE_CELL_HEIGHT: 30,
},
};
export enum OperatorTypes {
OR = "OR",
AND = "AND",
}
export enum SortOrderTypes {
asc = "asc",
desc = "desc",
}
export interface TableStyles {
cellBackground?: string;
textColor?: string;
textSize?: string;
fontStyle?: string;
horizontalAlignment?: CellAlignment;
verticalAlignment?: VerticalAlignment;
}
export type CompactMode = keyof typeof CompactModeTypes;
export type Condition = keyof typeof ConditionFunctions | "";
export type Operator = keyof typeof OperatorTypes;
export type CellAlignment = keyof typeof CellAlignmentTypes;
export type VerticalAlignment = keyof typeof VerticalAlignmentTypes;
export type ImageSize = keyof typeof ImageSizes;
export interface ReactTableFilter {
id: string;
column: string;
operator: Operator;
condition: Condition;
value: any;
}
export interface EditActionCellProperties {
discardActionIconName?: IconName;
discardActionLabel?: string;
discardButtonColor: string;
discardButtonVariant: ButtonVariant;
discardBorderRadius: ButtonBorderRadius;
discardIconAlign: Alignment;
isDiscardDisabled?: boolean;
isDiscardVisible?: boolean;
isSaveDisabled?: boolean;
isSaveVisible?: boolean;
saveActionIconName?: IconName;
saveActionLabel?: string;
saveButtonColor: string;
saveButtonVariant: ButtonVariant;
saveBorderRadius: ButtonBorderRadius;
saveIconAlign: Alignment;
}
export interface InlineEditingCellProperties {
isCellEditable: boolean;
hasUnsavedChanges?: boolean;
}
export interface CellWrappingProperties {
allowCellWrapping: boolean;
}
export interface ButtonCellProperties {
buttonVariant: ButtonVariant;
buttonColor?: string;
buttonLabel?: string;
isCompact?: boolean;
iconName?: IconName;
iconAlign?: Alignment;
}
export interface MenuButtonCellProperties {
menuButtonLabel?: string;
menuItems: MenuItems;
menuVariant?: ButtonVariant;
menuColor?: string;
menuButtoniconName?: IconName;
onItemClicked?: (onClick: string | undefined) => void;
menuItemsSource: MenuItemsSource;
configureMenuItems: ConfigureMenuItems;
sourceData?: Array<Record<string, unknown>>;
}
export interface URLCellProperties {
displayText?: string;
}
export interface SelectCellProperties {
isFilterable?: boolean;
serverSideFiltering?: boolean;
placeholderText?: string;
resetFilterTextOnClose?: boolean;
selectOptions?: DropdownOption[];
}
export interface ImageCellProperties {
imageSize?: ImageSize;
}
export interface DateCellProperties {
inputFormat: string;
outputFormat: string;
shortcuts: boolean;
timePrecision?: TimePrecision;
}
export interface CurrencyCellProperties {
currencyCode: string;
decimals: number;
thousandSeparator: boolean;
notation: Intl.NumberFormatOptions["notation"];
}
export interface BaseCellProperties {
horizontalAlignment?: CellAlignment;
verticalAlignment?: VerticalAlignment;
textSize?: string;
fontStyle?: string;
textColor?: string;
cellBackground?: string;
isVisible?: boolean;
isDisabled?: boolean;
borderRadius: string;
boxShadow: string;
isCellVisible: boolean;
isCellDisabled?: boolean;
}
export interface CellLayoutProperties
extends EditActionCellProperties,
InlineEditingCellProperties,
CellWrappingProperties,
ButtonCellProperties,
URLCellProperties,
MenuButtonCellProperties,
SelectCellProperties,
ImageCellProperties,
DateCellProperties,
CurrencyCellProperties,
BaseCellProperties {}
export interface TableColumnMetaProps {
isHidden: boolean;
format?: string;
inputFormat?: string;
type: ColumnTypes;
decimals?: number;
}
export enum StickyType {
LEFT = "left",
RIGHT = "right",
NONE = "",
}
export const SORT_ORDER = {
left: -1,
right: 1,
none: 0,
};
export interface TableColumnProps {
id: string;
Header: string;
alias: string;
accessor: any;
width?: number;
minWidth: number;
draggable: boolean;
isHidden?: boolean;
isAscOrder?: boolean;
metaProperties?: TableColumnMetaProps;
isDerived?: boolean;
columnProperties: ColumnProperties;
sticky?: StickyType;
}
export interface ReactTableColumnProps extends TableColumnProps {
Cell: (props: any) => JSX.Element;
}
export interface ColumnBaseProperties {
id: string;
originalId: string;
label?: string;
columnType: string;
isVisible: boolean;
isDisabled?: boolean;
index: number;
enableFilter?: boolean;
enableSort?: boolean;
isDerived: boolean;
computedValue: string;
isCellVisible?: boolean;
isAscOrder?: boolean;
alias: string;
allowCellWrapping: boolean;
}
export interface ColumnStyleProperties {
width: number;
cellBackground?: string;
horizontalAlignment?: CellAlignment;
verticalAlignment?: VerticalAlignment;
textSize?: string;
fontStyle?: string;
textColor?: string;
}
export interface DateColumnProperties {
outputFormat?: string;
inputFormat?: string;
shortcuts?: boolean;
timePrecision?: TimePrecision;
}
export interface ColumnEditabilityProperties {
isCellEditable: boolean; // Cell level editability
isEditable: boolean; // column level edtitability
validation?: {
regex?: string;
isEditableCellValid?: boolean;
errorMessage?: string;
isEditableCellRequired?: boolean;
min?: number;
max?: number;
minDate?: string;
maxDate?: string;
};
}
export interface EditActionColumnProperties {
saveButtonVariant?: ButtonVariant;
saveButtonColor?: string;
saveIconAlign?: Alignment;
saveBorderRadius?: ButtonBorderRadius;
saveActionIconName?: string;
saveActionLabel?: string;
isSaveVisible?: boolean;
isSaveDisabled?: boolean;
discardButtonVariant?: ButtonVariant;
discardButtonColor?: string;
discardIconAlign?: Alignment;
discardBorderRadius?: ButtonBorderRadius;
discardActionLabel?: string;
discardActionIconName?: string;
isDiscardVisible?: boolean;
isDiscardDisabled?: boolean;
isFilterable?: boolean;
serverSideFiltering?: boolean;
placeholderText?: string;
resetFilterTextOnClose?: boolean;
selectOptions?: DropdownOption[] | DropdownOption[][];
}
export interface CurrencyColumnProperties {
currencyCode?: string;
decimals?: number;
thousandSeparator?: boolean;
notation?: Intl.NumberFormatOptions["notation"];
}
export interface ColumnProperties
extends ColumnBaseProperties,
ColumnStyleProperties,
DateColumnProperties,
ColumnEditabilityProperties,
CurrencyColumnProperties,
EditActionColumnProperties {
allowSameOptionsInNewRow?: boolean;
newRowSelectOptions?: DropdownOption[];
buttonLabel?: string;
menuButtonLabel?: string;
buttonColor?: string;
onClick?: string;
dropdownOptions?: string;
onOptionChange?: string;
displayText?: string;
buttonVariant?: ButtonVariant;
isCompact?: boolean;
menuItems?: MenuItems;
menuVariant?: ButtonVariant;
menuColor?: string;
borderRadius?: ButtonBorderRadius;
boxShadow?: string;
boxShadowColor?: string;
iconName?: IconName;
menuButtoniconName?: IconName;
iconAlign?: Alignment;
onItemClicked?: (onClick: string | undefined) => void;
iconButtonStyle?: ButtonStyleType;
imageSize?: ImageSize;
sticky?: StickyType;
getVisibleItems?: () => Array<MenuItem>;
menuItemsSource?: MenuItemsSource;
configureMenuItems?: ConfigureMenuItems;
sourceData?: Array<Record<string, unknown>>;
}
export const ConditionFunctions: {
[key: string]: (a: any, b: any) => boolean;
} = {
isExactly: (a: any, b: any) => {
return a.toString() === b.toString();
},
empty: (a: any) => {
return a === "" || a === undefined || a === null;
},
notEmpty: (a: any) => {
return a !== "" && a !== undefined && a !== null;
},
notEqualTo: (a: any, b: any) => {
return a.toString() !== b.toString();
},
isEqualTo: (a: any, b: any) => {
return a.toString() === b.toString();
},
lessThan: (a: any, b: any) => {
const numericB = Number(b);
const numericA = Number(a);
return numericA < numericB;
},
lessThanEqualTo: (a: any, b: any) => {
const numericB = Number(b);
const numericA = Number(a);
return numericA <= numericB;
},
greaterThan: (a: any, b: any) => {
const numericB = Number(b);
const numericA = Number(a);
return numericA > numericB;
},
greaterThanEqualTo: (a: any, b: any) => {
const numericB = Number(b);
const numericA = Number(a);
return numericA >= numericB;
},
contains: (a: any, b: any) => {
if (isString(a) && isString(b)) {
return a.includes(b);
}
return false;
},
doesNotContain: (a: any, b: any) => {
if (isString(a) && isString(b)) {
return !a.includes(b);
}
return false;
},
startsWith: (a: any, b: any) => {
if (isString(a) && isString(b)) {
return a.indexOf(b) === 0;
}
return false;
},
endsWith: (a: any, b: any) => {
if (isString(a) && isString(b)) {
return a.length === a.lastIndexOf(b) + b.length;
}
return false;
},
is: (a: any, b: any) => {
return moment(a).isSame(moment(b), "d");
},
isNot: (a: any, b: any) => {
return !moment(a).isSame(moment(b), "d");
},
isAfter: (a: any, b: any) => {
return !moment(a).isAfter(moment(b), "d");
},
isBefore: (a: any, b: any) => {
return !moment(a).isBefore(moment(b), "d");
},
};
export enum JUSTIFY_CONTENT {
LEFT = "flex-start",
CENTER = "center",
RIGHT = "flex-end",
}
export enum TEXT_ALIGN {
LEFT = "left",
CENTER = "center",
RIGHT = "right",
}
export enum ALIGN_ITEMS {
TOP = "flex-start",
CENTER = "center",
BOTTOM = "flex-end",
}
export enum IMAGE_HORIZONTAL_ALIGN {
LEFT = "flex-start",
CENTER = "center",
RIGHT = "flex-end",
}
export enum IMAGE_VERTICAL_ALIGN {
TOP = "flex-start",
CENTER = "center",
BOTTOM = "flex-end",
}
export interface BaseCellComponentProps {
compactMode: string;
isHidden: boolean;
allowCellWrapping?: boolean;
horizontalAlignment?: CellAlignment;
verticalAlignment?: VerticalAlignment;
cellBackground?: string;
isCellVisible: boolean;
fontStyle?: string;
textColor?: string;
textSize?: string;
isCellDisabled?: boolean;
}
export enum CheckboxState {
UNCHECKED = 0,
CHECKED = 1,
PARTIAL = 2,
}
export const scrollbarOnHoverCSS = `
.track-horizontal {
height: 6px;
bottom: 1px;
width: 100%;
opacity: 0;
transition: opacity 0.15s ease-in;
&:active {
opacity: 1;
}
}
&:hover {
.track-horizontal {
opacity: 1;
}
}
.thumb-horizontal {
&:hover, &:active {
height: 6px !important;
}
}
`;
export const MULTISELECT_CHECKBOX_WIDTH = 40;
export enum AddNewRowActions {
SAVE = "SAVE",
DISCARD = "DISCARD",
}
export const EDITABLE_CELL_PADDING_OFFSET = 8;
export const TABLE_SCROLLBAR_WIDTH = 10;
export const TABLE_SCROLLBAR_HEIGHT = 8;
export const POPOVER_ITEMS_TEXT_MAP = {
SORT_ASC: "Sort column ascending",
SORT_DSC: "Sort column descending",
FREEZE_LEFT: "Freeze column left",
FREEZE_RIGHT: "Freeze column right",
};
export const HEADER_MENU_PORTAL_CLASS = ".header-menu-portal";
export const MENU_CONTENT_CLASS = ".menu-content";
export const DEFAULT_FILTER = {
id: generateReactKey(),
column: "",
operator: OperatorTypes.OR,
value: "",
condition: "",
};