import React, { useState } from "react";
import { Icon, InputGroup } from "@blueprintjs/core";
import moment from "moment-timezone";
import {
MenuColumnWrapper,
CellWrapper,
ActionWrapper,
} from "./TableStyledWrappers";
import { ColumnAction } from "components/propertyControls/ColumnActionSelectorControl";
import { ColumnMenuOptionProps } from "./ReactTableComponent";
import { isString } from "lodash";
import VideoComponent from "components/designSystems/appsmith/VideoComponent";
import Button from "components/editorComponents/Button";
import AutoToolTipComponent from "components/designSystems/appsmith/AutoToolTipComponent";
import TableColumnMenuPopup from "./TableColumnMenu";
interface MenuOptionProps {
columnAccessor?: string;
isColumnHidden: boolean;
columnType: string;
format?: string;
hideColumn: (columnIndex: number, isColumnHidden: boolean) => void;
updateColumnType: (columnIndex: number, columnType: string) => void;
handleUpdateCurrencySymbol: (
columnIndex: number,
currencySymbol: string,
) => void;
handleDateFormatUpdate: (columnIndex: number, dateFormat: string) => void;
}
export const getMenuOptions = (props: MenuOptionProps) => {
const basicOptions: ColumnMenuOptionProps[] = [
{
content: "Rename a Column",
closeOnClick: true,
id: "rename_column",
editColumnName: true,
},
{
content: props.isColumnHidden ? "Show Column" : "Hide Column",
closeOnClick: true,
id: "hide_column",
onClick: (columnIndex: number) => {
props.hideColumn(columnIndex, props.isColumnHidden);
},
},
];
if (props.columnAccessor && props.columnAccessor === "actions") {
return basicOptions;
}
const columnMenuOptions: ColumnMenuOptionProps[] = [
...basicOptions,
{
content: "Select a Data Type",
id: "change_column_type",
category: true,
},
{
content: (
Image
),
closeOnClick: true,
isSelected: props.columnType === "image",
onClick: (columnIndex: number, isSelected: boolean) => {
if (isSelected) {
props.updateColumnType(columnIndex, "");
} else {
props.updateColumnType(columnIndex, "image");
}
},
},
{
content: (
Video
),
isSelected: props.columnType === "video",
closeOnClick: true,
onClick: (columnIndex: number, isSelected: boolean) => {
if (isSelected) {
props.updateColumnType(columnIndex, "");
} else {
props.updateColumnType(columnIndex, "video");
}
},
},
{
content: (
Text
),
closeOnClick: true,
isSelected: props.columnType === "text",
onClick: (columnIndex: number, isSelected: boolean) => {
if (isSelected) {
props.updateColumnType(columnIndex, "");
} else {
props.updateColumnType(columnIndex, "text");
}
},
},
{
content: (
Currency
),
closeOnClick: false,
isSelected: props.columnType === "currency",
options: [
{
content: "USD - $",
isSelected: props.format === "$",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleUpdateCurrencySymbol(columnIndex, "$");
},
},
{
content: "INR - ₹",
isSelected: props.format === "₹",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleUpdateCurrencySymbol(columnIndex, "₹");
},
},
{
content: "GBP - £",
isSelected: props.format === "£",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleUpdateCurrencySymbol(columnIndex, "£");
},
},
{
content: "AUD - A$",
isSelected: props.format === "A$",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleUpdateCurrencySymbol(columnIndex, "A$");
},
},
{
content: "EUR - €",
isSelected: props.format === "€",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleUpdateCurrencySymbol(columnIndex, "€");
},
},
{
content: "SGD - S$",
isSelected: props.format === "S$",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleUpdateCurrencySymbol(columnIndex, "S$");
},
},
{
content: "CAD - C$",
isSelected: props.format === "C$",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleUpdateCurrencySymbol(columnIndex, "C$");
},
},
],
},
{
content: (
Date
),
closeOnClick: false,
isSelected: props.columnType === "date",
options: [
{
content: "MM-DD-YY",
isSelected: props.format === "MM-DD-YY",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleDateFormatUpdate(columnIndex, "MM-DD-YY");
},
},
{
content: "DD-MM-YY",
isSelected: props.format === "DD-MM-YY",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleDateFormatUpdate(columnIndex, "DD-MM-YY");
},
},
{
content: "DD/MM/YY",
isSelected: props.format === "DD/MM/YY",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleDateFormatUpdate(columnIndex, "DD/MM/YY");
},
},
{
content: "MM/DD/YY",
isSelected: props.format === "MM/DD/YY",
closeOnClick: true,
onClick: (columnIndex: number) => {
props.handleDateFormatUpdate(columnIndex, "MM/DD/YY");
},
},
],
},
{
content: (
Time
),
closeOnClick: true,
isSelected: props.columnType === "time",
onClick: (columnIndex: number, isSelected: boolean) => {
if (isSelected) {
props.updateColumnType(columnIndex, "");
} else {
props.updateColumnType(columnIndex, "time");
}
},
},
];
return columnMenuOptions;
};
export const renderCell = (
value: any,
rowIndex: number,
columnType: string,
isHidden: boolean,
widgetId: string,
format?: string,
) => {
if (!value) {
return
;
}
switch (columnType) {
case "image":
if (!isString(value)) {
return (
Invalid Image
);
}
const imageRegex = /(http(s?):)([/|.|\w|\s|-])*\.(?:jpeg|jpg|gif|png)??(?:&?[^=&]*=[^=&]*)*/;
return (
{value
.toString()
.split(",")
.map((item: string, index: number) => {
if (imageRegex.test(item)) {
return (
);
} else {
return Invalid Image
;
}
})}
);
case "video":
const youtubeRegex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|\?v=)([^#\&\?]*).*/;
if (isString(value) && youtubeRegex.test(value)) {
return (
);
} else {
return (
Invalid Video Link
);
}
case "currency":
if (!isNaN(value)) {
return (
{`${format}${value}`}
);
} else {
return Invalid Value;
}
case "date":
let isValidDate = true;
if (isNaN(value)) {
const dateTime = Date.parse(value);
if (isNaN(dateTime)) {
isValidDate = false;
}
}
if (isValidDate) {
return (
{moment(value).format(format)}
);
} else {
return Invalid Date;
}
case "time":
let isValidTime = true;
if (isNaN(value)) {
const time = Date.parse(value);
if (isNaN(time)) {
isValidTime = false;
}
}
if (isValidTime) {
return (
{moment(value).format("HH:mm")}
);
} else {
return Invalid Time;
}
case "text":
const text = isString(value) ? value : JSON.stringify(value);
return (
{text}
);
default:
const data = isString(value) ? value : JSON.stringify(value);
return (
{data}
);
}
};
interface RenderActionProps {
columnActions?: ColumnAction[];
onCommandClick: (dynamicTrigger: string, onComplete: () => void) => void;
}
export const renderActions = (props: RenderActionProps) => {
if (!props.columnActions) return ;
return (
{props.columnActions.map((action: ColumnAction, index: number) => {
return (
);
})}
);
};
const TableAction = (props: {
action: ColumnAction;
onCommandClick: (dynamicTrigger: string, onComplete: () => void) => void;
}) => {
const [loading, setLoading] = useState(false);
const onComplete = () => {
setLoading(false);
};
return (
{
e.stopPropagation();
}}
>
);
};
const RenameColumn = (props: {
value: any;
columnIndex: number;
handleSave: (columnIndex: number, value: any) => void;
}) => {
const [columnName, updateColumnName] = useState(props.value);
const onKeyPress = (key: string) => {
if (key === "Enter") {
props.handleSave(props.columnIndex, columnName);
}
};
const onColumnNameChange = (event: React.ChangeEvent) => {
updateColumnName(event.target.value);
};
const handleColumnNameUpdate = () => {
props.handleSave(props.columnIndex, columnName);
};
return (
onKeyPress(e.key)}
onBlur={e => handleColumnNameUpdate()}
/>
);
};
export const renderEmptyRows = (
rowCount: number,
columns: any,
tableWidth: number,
) => {
const rows: string[] = new Array(rowCount).fill("");
const tableColumns = columns.length
? columns
: new Array(3).fill({ width: tableWidth / 3, isHidden: false });
return (
{rows.map((row: string, index: number) => {
return (
{tableColumns.map((column: any, colIndex: number) => {
return (
);
})}
);
})}
);
};
export const TableHeaderCell = (props: {
columnName: string;
columnIndex: number;
isHidden: boolean;
displayColumnActions: boolean;
handleColumnNameUpdate: (columnIndex: number, name: string) => void;
getColumnMenu: (columnIndex: number) => ColumnMenuOptionProps[];
handleResizeColumn: Function;
column: any;
}) => {
const { column } = props;
const [renameColumn, toggleRenameColumn] = React.useState(false);
const handleSaveColumnName = (columnIndex: number, columName: string) => {
props.handleColumnNameUpdate(columnIndex, columName);
toggleRenameColumn(false);
};
if (column.isResizing) {
props.handleResizeColumn(
props.columnIndex,
column.getHeaderProps().style.width,
);
}
return (
{renameColumn && (
)}
{!renameColumn && (
{column.render("Header")}
)}
{props.displayColumnActions && (
toggleRenameColumn(true)}
/>
)}
);
};