Fix-Open image in new tab on clicking it in table widget. (#119)

* Added Button component in Table widget for actions

* Action button state loading added for Table widget

* Action button font-weight made as normal

* Created header for common functionalities in Table Widget

* Client side searching added in Table Widget. Action created for server side searching also.

* Columns visibility feature initial commit

* Column visibility list added in Table Widget

* Changed pagination designs in accordance with new layout. This enable user to jump page as well.

* Using colors values from constants

* Table widget pagination, numeric input page number clamped between 1 and total pages

* Adding tool tip to truncated values in table widget. Added AutoToolTipComponent that adds tooltip when text is truncated.

* Table data download changes. Added downlaod icon and button to table widget.

* Table data download changes

* Table button loading state fixed. Table code refactored, rendering from props instead of state in ReactTableComponent

* Table widget action button alignment fixed

* Handled actions column changes

* added proper keys to useMemo for react table widget

* Download table data as CSV implemented

* table data download, unused code removed

* Code refactors and added dependency map with meta props and table data for computing columns

* Table UI breakages on scroll and empty cells fixed

* Handled empty rows in table widget

* Fixed last row cut issue

* Code review changes

* Code review changes

* Added table widget component heights as enum

* code review changes

* Search component in Table widget updated with support for clearing data, renamed properties

* Opening image in new tab on clicking in table widget

* Fixed table craching due to empty data filtering

* Empty extra space on loading removed in table widget

* Removed stopping of event propagation on table widget action button click

* Table header UI overflow fixed

* Clearing selected row on searching data in table widget

* fix for cypress test

Co-authored-by: Arpit Mohan <me@arpitmohan.com>
This commit is contained in:
vicky-primathon 2020-07-24 16:02:31 +05:30 committed by GitHub
parent 61c62c9212
commit a2673aaa87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 24 deletions

View File

@ -33,6 +33,7 @@ const SearchComponent = (props: SearchProps) => {
return ( return (
<SearchInputWrapper <SearchInputWrapper
leftIcon="search" leftIcon="search"
type="search"
onChange={handleSearch} onChange={handleSearch}
placeholder={props.placeholder} placeholder={props.placeholder}
value={value} value={value}

View File

@ -11,6 +11,7 @@ export const TableWrapper = styled.div<{ width: number; height: number }>`
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
flex-direction: column; flex-direction: column;
overflow: hidden;
.tableWrap { .tableWrap {
height: 100%; height: 100%;
display: block; display: block;
@ -22,7 +23,8 @@ export const TableWrapper = styled.div<{ width: number; height: number }>`
color: ${Colors.BLUE_BAYOUX}; color: ${Colors.BLUE_BAYOUX};
position: relative; position: relative;
overflow-y: auto; overflow-y: auto;
height: ${props => props.height - TABLE_SIZES.TABLE_HEADER_HEIGHT}px; /* Subtracting 9px to handling widget padding */
height: ${props => props.height - TABLE_SIZES.TABLE_HEADER_HEIGHT - 9}px;
.thead, .thead,
.tbody { .tbody {
overflow: hidden; overflow: hidden;
@ -255,6 +257,7 @@ export const TableHeaderWrapper = styled.div`
align-items: center; align-items: center;
width: 100%; width: 100%;
border-bottom: 1px solid ${Colors.GEYSER_LIGHT}; border-bottom: 1px solid ${Colors.GEYSER_LIGHT};
min-width: 700px;
`; `;
export const CommonFunctionsMenuWrapper = styled.div` export const CommonFunctionsMenuWrapper = styled.div`

View File

@ -334,11 +334,18 @@ export const renderCell = (
.map((item: string, index: number) => { .map((item: string, index: number) => {
if (imageRegex.test(item)) { if (imageRegex.test(item)) {
return ( return (
<div <a
key={index} onClick={e => e.stopPropagation()}
className="image-cell" target="_blank"
style={{ backgroundImage: `url("${item}")` }} rel="noopener noreferrer"
/> href={item}
>
<div
key={index}
className="image-cell"
style={{ backgroundImage: `url("${item}")` }}
/>
</a>
); );
} else { } else {
return <div>Invalid Image</div>; return <div>Invalid Image</div>;
@ -401,11 +408,7 @@ const TableAction = (props: {
setLoading(false); setLoading(false);
}; };
return ( return (
<ActionWrapper <ActionWrapper>
onClick={e => {
e.stopPropagation();
}}
>
<Button <Button
loading={loading} loading={loading}
onClick={() => { onClick={() => {

View File

@ -88,6 +88,7 @@ export const StyledDropDownContainer = styled.div`
word-break: break-word; word-break: break-word;
display: block; display: block;
overflow: auto; overflow: auto;
overflow-y: hidden;
} }
} }
} }

View File

@ -14,7 +14,7 @@ import {
} from "components/designSystems/appsmith/TableUtilities"; } from "components/designSystems/appsmith/TableUtilities";
import { TABLE_SIZES } from "components/designSystems/appsmith/Table"; import { TABLE_SIZES } from "components/designSystems/appsmith/Table";
import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { RenderMode, RenderModes } from "constants/WidgetConstants"; import { RenderModes } from "constants/WidgetConstants";
import { import {
WidgetPropertyValidationType, WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION, BASE_WIDGET_VALIDATION,
@ -33,7 +33,7 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
prevPageKey: VALIDATION_TYPES.TEXT, prevPageKey: VALIDATION_TYPES.TEXT,
label: VALIDATION_TYPES.TEXT, label: VALIDATION_TYPES.TEXT,
selectedRowIndex: VALIDATION_TYPES.NUMBER, selectedRowIndex: VALIDATION_TYPES.NUMBER,
searchKey: VALIDATION_TYPES.TEXT, searchKeyword: VALIDATION_TYPES.TEXT,
// columnActions: VALIDATION_TYPES.ARRAY_ACTION_SELECTOR, // columnActions: VALIDATION_TYPES.ARRAY_ACTION_SELECTOR,
// onRowSelected: VALIDATION_TYPES.ACTION_SELECTOR, // onRowSelected: VALIDATION_TYPES.ACTION_SELECTOR,
// onPageChange: VALIDATION_TYPES.ACTION_SELECTOR, // onPageChange: VALIDATION_TYPES.ACTION_SELECTOR,
@ -50,7 +50,7 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
pageNo: 1, pageNo: 1,
pageSize: undefined, pageSize: undefined,
selectedRowIndex: -1, selectedRowIndex: -1,
searchKey: "", searchKeyword: "",
}; };
} }
@ -58,7 +58,7 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
return { return {
onRowSelected: true, onRowSelected: true,
onPageChange: true, onPageChange: true,
onSearch: true, onSearchTextChanged: true,
}; };
} }
@ -198,9 +198,12 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
}; };
searchTableData = (tableData: object[]) => { searchTableData = (tableData: object[]) => {
if (!tableData || !tableData.length) {
return [];
}
const searchKey = const searchKey =
this.props.searchKey !== undefined this.props.searchKeyword !== undefined
? this.props.searchKey.toString().toUpperCase() ? this.props.searchKeyword.toString().toUpperCase()
: ""; : "";
return tableData.filter((item: object) => { return tableData.filter((item: object) => {
return Object.values(item) return Object.values(item)
@ -246,7 +249,7 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
isLoading={this.props.isLoading} isLoading={this.props.isLoading}
widgetId={this.props.widgetId} widgetId={this.props.widgetId}
widgetName={this.props.widgetName} widgetName={this.props.widgetName}
searchKey={this.props.searchKey} searchKey={this.props.searchKeyword}
renderMode={this.props.renderMode} renderMode={this.props.renderMode}
hiddenColumns={hiddenColumns} hiddenColumns={hiddenColumns}
columnActions={this.props.columnActions} columnActions={this.props.columnActions}
@ -297,11 +300,12 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
} }
handleSearchTable = (searchKey: any) => { handleSearchTable = (searchKey: any) => {
const { onSearch } = this.props; const { onSearchTextChanged } = this.props;
super.updateWidgetMetaProperty("searchKey", searchKey); this.resetSelectedRowIndex();
if (onSearch) { super.updateWidgetMetaProperty("searchKeyword", searchKey);
if (onSearchTextChanged) {
super.executeAction({ super.executeAction({
dynamicString: onSearch, dynamicString: onSearchTextChanged,
event: { event: {
type: EventType.ON_SEARCH, type: EventType.ON_SEARCH,
}, },
@ -381,12 +385,12 @@ export interface TableWidgetProps extends WidgetProps {
nextPageKey?: string; nextPageKey?: string;
prevPageKey?: string; prevPageKey?: string;
label: string; label: string;
searchKey: string; searchKeyword: string;
tableData: object[]; tableData: object[];
onPageChange?: string; onPageChange?: string;
pageSize: number; pageSize: number;
onRowSelected?: string; onRowSelected?: string;
onSearch: string; onSearchTextChanged: string;
selectedRowIndex?: number; selectedRowIndex?: number;
columnActions?: ColumnAction[]; columnActions?: ColumnAction[];
serverSidePaginationEnabled?: boolean; serverSidePaginationEnabled?: boolean;