fix(chart): ensure samples data is displayed (#16900)

* initial fix

* use data keys for cols

* add e2e test

* remove code

* trim logic
This commit is contained in:
Phillip Kelley-Dotson 2021-11-12 14:23:46 -08:00 committed by GitHub
parent f10bc6d8fe
commit e6ff25c980
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 109 additions and 64 deletions

View File

@ -113,6 +113,25 @@ describe('VizType control', () => {
}); });
}); });
describe('Test datatable', () => {
beforeEach(() => {
cy.login();
interceptChart({ legacy: false }).as('tableChartData');
interceptChart({ legacy: true }).as('lineChartData');
});
it('Data Pane opens and loads results', () => {
cy.get('[data-test="data-tab"]').click();
cy.get('[data-test="row-count-label"]').contains('27 rows retrieved');
cy.contains('View results');
cy.get('.ant-empty-description').should('not.exist');
});
it('Datapane loads view samples', () => {
cy.contains('View samples').click();
cy.get('[data-test="row-count-label"]').contains('1k rows retrieved');
cy.get('.ant-empty-description').should('not.exist');
});
});
describe('Time range filter', () => { describe('Time range filter', () => {
beforeEach(() => { beforeEach(() => {
cy.login(); cy.login();

View File

@ -150,5 +150,5 @@ export const useTableColumns = (
} as Column), } as Column),
) )
: [], : [],
[data, moreConfigs], [data, colnames, moreConfigs],
); );

View File

@ -106,6 +106,58 @@ const Error = styled.pre`
margin-top: ${({ theme }) => `${theme.gridUnit * 4}px`}; margin-top: ${({ theme }) => `${theme.gridUnit * 4}px`};
`; `;
interface DataTableProps {
columnNames: string[];
filterText: string;
data: object[] | undefined;
isLoading: boolean;
error: string | undefined;
errorMessage: React.ReactElement | undefined;
}
const DataTable = ({
columnNames,
filterText,
data,
isLoading,
error,
errorMessage,
}: DataTableProps) => {
// this is to preserve the order of the columns, even if there are integer values,
// while also only grabbing the first column's keys
const columns = useTableColumns(columnNames, data);
const filteredData = useFilteredTableData(filterText, data);
if (isLoading) {
return <Loading />;
}
if (error) {
return <Error>{error}</Error>;
}
if (data) {
if (data.length === 0) {
return <span>No data</span>;
}
return (
<TableView
columns={columns}
data={filteredData}
pageSize={DATA_TABLE_PAGE_SIZE}
noDataText={t('No data')}
emptyWrapperType={EmptyWrapperType.Small}
className="table-condensed"
isPaginationSticky
showRowCount={false}
small
/>
);
}
if (errorMessage) {
return <Error>{errorMessage}</Error>;
}
return null;
};
export const DataTablesPane = ({ export const DataTablesPane = ({
queryFormData, queryFormData,
tableSectionHeight, tableSectionHeight,
@ -131,7 +183,13 @@ export const DataTablesPane = ({
[RESULT_TYPES.results]: true, [RESULT_TYPES.results]: true,
[RESULT_TYPES.samples]: true, [RESULT_TYPES.samples]: true,
}); });
const [columnNames, setColumnNames] = useState<string[]>([]); const [columnNames, setColumnNames] = useState<{
[RESULT_TYPES.results]: string[];
[RESULT_TYPES.samples]: string[];
}>({
[RESULT_TYPES.results]: [],
[RESULT_TYPES.samples]: [],
});
const [error, setError] = useState(NULLISH_RESULTS_STATE); const [error, setError] = useState(NULLISH_RESULTS_STATE);
const [filterText, setFilterText] = useState(''); const [filterText, setFilterText] = useState('');
const [activeTabKey, setActiveTabKey] = useState<string>( const [activeTabKey, setActiveTabKey] = useState<string>(
@ -192,7 +250,13 @@ export const DataTablesPane = ({
[resultType]: json.result[0].data, [resultType]: json.result[0].data,
})); }));
} }
const checkCols = json?.result[0]?.data?.length
? Object.keys(json.result[0].data[0])
: null;
setColumnNames(prevColumnNames => ({
...prevColumnNames,
[resultType]: json.result[0].columns || checkCols,
}));
setIsLoading(prevIsLoading => ({ setIsLoading(prevIsLoading => ({
...prevIsLoading, ...prevIsLoading,
[resultType]: false, [resultType]: false,
@ -215,7 +279,7 @@ export const DataTablesPane = ({
}); });
}); });
}, },
[queryFormData], [queryFormData, columnNames],
); );
useEffect(() => { useEffect(() => {
@ -239,7 +303,10 @@ export const DataTablesPane = ({
useEffect(() => { useEffect(() => {
if (queriesResponse && chartStatus === 'success') { if (queriesResponse && chartStatus === 'success') {
const { colnames } = queriesResponse[0]; const { colnames } = queriesResponse[0];
setColumnNames([...colnames]); setColumnNames({
...columnNames,
[RESULT_TYPES.results]: [...colnames],
});
} }
}, [queriesResponse]); }, [queriesResponse]);
@ -289,67 +356,12 @@ export const DataTablesPane = ({
errorMessage, errorMessage,
]); ]);
const filteredData = {
[RESULT_TYPES.results]: useFilteredTableData(
filterText,
formattedData[RESULT_TYPES.results],
),
[RESULT_TYPES.samples]: useFilteredTableData(
filterText,
formattedData[RESULT_TYPES.samples],
),
};
// this is to preserve the order of the columns, even if there are integer values,
// while also only grabbing the first column's keys
const columns = {
[RESULT_TYPES.results]: useTableColumns(
columnNames,
data[RESULT_TYPES.results],
),
[RESULT_TYPES.samples]: useTableColumns(
columnNames,
data[RESULT_TYPES.samples],
),
};
const renderDataTable = (type: string) => {
if (isLoading[type]) {
return <Loading />;
}
if (error[type]) {
return <Error>{error[type]}</Error>;
}
if (data[type]) {
if (data[type]?.length === 0) {
return <span>No data</span>;
}
return (
<TableView
columns={columns[type]}
data={filteredData[type]}
pageSize={DATA_TABLE_PAGE_SIZE}
noDataText={t('No data')}
emptyWrapperType={EmptyWrapperType.Small}
className="table-condensed"
isPaginationSticky
showRowCount={false}
small
/>
);
}
if (errorMessage) {
return <Error>{errorMessage}</Error>;
}
return null;
};
const TableControls = ( const TableControls = (
<TableControlsWrapper> <TableControlsWrapper>
<RowCount data={data[activeTabKey]} loading={isLoading[activeTabKey]} /> <RowCount data={data[activeTabKey]} loading={isLoading[activeTabKey]} />
<CopyToClipboardButton <CopyToClipboardButton
data={formattedData[activeTabKey]} data={formattedData[activeTabKey]}
columns={columnNames} columns={columnNames[activeTabKey]}
/> />
<FilterInput onChangeHandler={setFilterText} /> <FilterInput onChangeHandler={setFilterText} />
</TableControlsWrapper> </TableControlsWrapper>
@ -363,7 +375,7 @@ export const DataTablesPane = ({
return ( return (
<SouthPane data-test="some-purposeful-instance"> <SouthPane data-test="some-purposeful-instance">
<TabsWrapper contentHeight={tableSectionHeight}> <TabsWrapper contentHeight={tableSectionHeight}>
<CollapseWrapper> <CollapseWrapper data-test="data-tab">
<Collapse <Collapse
accordion accordion
bordered={false} bordered={false}
@ -384,13 +396,27 @@ export const DataTablesPane = ({
tab={t('View results')} tab={t('View results')}
key={RESULT_TYPES.results} key={RESULT_TYPES.results}
> >
{renderDataTable(RESULT_TYPES.results)} <DataTable
isLoading={isLoading[RESULT_TYPES.results]}
data={data[RESULT_TYPES.results]}
columnNames={columnNames[RESULT_TYPES.results]}
filterText={filterText}
error={error[RESULT_TYPES.results]}
errorMessage={errorMessage}
/>
</Tabs.TabPane> </Tabs.TabPane>
<Tabs.TabPane <Tabs.TabPane
tab={t('View samples')} tab={t('View samples')}
key={RESULT_TYPES.samples} key={RESULT_TYPES.samples}
> >
{renderDataTable(RESULT_TYPES.samples)} <DataTable
isLoading={isLoading[RESULT_TYPES.samples]}
data={data[RESULT_TYPES.samples]}
columnNames={columnNames[RESULT_TYPES.samples]}
filterText={filterText}
error={error[RESULT_TYPES.samples]}
errorMessage={errorMessage}
/>
</Tabs.TabPane> </Tabs.TabPane>
</Tabs> </Tabs>
</Collapse.Panel> </Collapse.Panel>