chore: removed some of the stage logic in the query builder (#2682)

This commit is contained in:
Palash Gupta 2023-05-11 14:14:17 +05:30 committed by GitHub
parent 25398d9d35
commit 10e47b5bff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 223 deletions

View File

@ -1,39 +0,0 @@
import { Tooltip } from 'antd';
import React from 'react';
interface ITabHeaderProps {
tabName: string;
hasUnstagedChanges: boolean;
}
function TabHeader({
tabName,
hasUnstagedChanges,
}: ITabHeaderProps): JSX.Element {
return (
<div
style={{
display: 'flex',
gap: '0.5rem',
justifyContent: 'center',
alignItems: 'center',
}}
>
{tabName}
{hasUnstagedChanges && (
<Tooltip title="Looks like you have un-staged changes. Make sure you click 'Stage & Run Query' if you want to save these changes.">
<div
style={{
height: '0.6rem',
width: '0.6rem',
borderRadius: '1rem',
background: 'orange',
}}
/>
</Tooltip>
)}
</div>
);
}
export default TabHeader;

View File

@ -1,11 +1,9 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ import { Button, Tabs, Typography } from 'antd';
import { Button, Tabs } from 'antd';
import TextToolTip from 'components/TextToolTip'; import TextToolTip from 'components/TextToolTip';
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider'; import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
import { timePreferance } from 'container/NewWidget/RightContainer/timeItems';
import { QueryBuilder } from 'container/QueryBuilder'; import { QueryBuilder } from 'container/QueryBuilder';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { cloneDeep, isEqual } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { connect, useSelector } from 'react-redux'; import { connect, useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
@ -28,15 +26,9 @@ import {
} from './constants'; } from './constants';
import ClickHouseQueryContainer from './QueryBuilder/clickHouse'; import ClickHouseQueryContainer from './QueryBuilder/clickHouse';
import PromQLQueryContainer from './QueryBuilder/promQL'; import PromQLQueryContainer from './QueryBuilder/promQL';
import TabHeader from './TabHeader';
import { IHandleUpdatedQuery } from './types'; import { IHandleUpdatedQuery } from './types';
import { showUnstagedStashConfirmBox } from './utils/userSettings';
function QuerySection({ function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
handleUnstagedChanges,
updateQuery,
selectedGraph,
}: QueryProps): JSX.Element {
const { queryBuilderData, initQueryBuilderData } = useQueryBuilder(); const { queryBuilderData, initQueryBuilderData } = useQueryBuilder();
const [localQueryChanges, setLocalQueryChanges] = useState<Query>({} as Query); const [localQueryChanges, setLocalQueryChanges] = useState<Query>({} as Query);
const [rctTabKey, setRctTabKey] = useState< const [rctTabKey, setRctTabKey] = useState<
@ -67,19 +59,11 @@ function QuerySection({
); );
const { query } = selectedWidget || {}; const { query } = selectedWidget || {};
useEffect(() => { useEffect(() => {
initQueryBuilderData(query.builder); initQueryBuilderData(query.builder);
setLocalQueryChanges(cloneDeep(query) as Query); setLocalQueryChanges(cloneDeep(query) as Query);
}, [query, initQueryBuilderData]); }, [query, initQueryBuilderData]);
const queryDiff = (
queryA: Query,
queryB: Query,
queryCategory: EQueryType,
): boolean => !isEqual(queryA[queryCategory], queryB[queryCategory]);
useEffect(() => {
handleUnstagedChanges(queryDiff(query, localQueryChanges, queryCategory));
}, [handleUnstagedChanges, localQueryChanges, query, queryCategory]);
const regenRctKeys = (): void => { const regenRctKeys = (): void => {
setRctTabKey((prevState) => { setRctTabKey((prevState) => {
@ -104,17 +88,6 @@ function QuerySection({
}; };
const handleQueryCategoryChange = (qCategory: string): void => { const handleQueryCategoryChange = (qCategory: string): void => {
// If true, then it means that the user has made some changes and haven't staged them
const unstagedChanges = queryDiff(query, localQueryChanges, queryCategory);
if (unstagedChanges && showUnstagedStashConfirmBox()) {
// eslint-disable-next-line no-alert
window.confirm(
"You are trying to navigate to different tab with unstaged changes. Your current changes will be purged. Press 'Stage & Run Query' to stage them.",
);
return;
}
setQueryCategory(qCategory as EQueryType); setQueryCategory(qCategory as EQueryType);
const newLocalQuery = { const newLocalQuery = {
...cloneDeep(query), ...cloneDeep(query),
@ -139,31 +112,13 @@ function QuerySection({
{ {
key: EQueryType.QUERY_BUILDER, key: EQueryType.QUERY_BUILDER,
label: 'Query Builder', label: 'Query Builder',
tab: ( tab: <Typography>Query Builder</Typography>,
<TabHeader
tabName="Query Builder"
hasUnstagedChanges={queryDiff(
query,
localQueryChanges,
EQueryType.QUERY_BUILDER,
)}
/>
),
children: <QueryBuilder panelType={selectedGraph} />, children: <QueryBuilder panelType={selectedGraph} />,
}, },
{ {
key: EQueryType.CLICKHOUSE, key: EQueryType.CLICKHOUSE,
label: 'ClickHouse Query', label: 'ClickHouse Query',
tab: ( tab: <Typography>ClickHouse Query</Typography>,
<TabHeader
tabName="ClickHouse Query"
hasUnstagedChanges={queryDiff(
query,
localQueryChanges,
EQueryType.CLICKHOUSE,
)}
/>
),
children: ( children: (
<ClickHouseQueryContainer <ClickHouseQueryContainer
key={rctTabKey.CLICKHOUSE} key={rctTabKey.CLICKHOUSE}
@ -178,12 +133,7 @@ function QuerySection({
{ {
key: EQueryType.PROM, key: EQueryType.PROM,
label: 'PromQL', label: 'PromQL',
tab: ( tab: <Typography>PromQL</Typography>,
<TabHeader
tabName="PromQL"
hasUnstagedChanges={queryDiff(query, localQueryChanges, EQueryType.PROM)}
/>
),
children: ( children: (
<PromQLQueryContainer <PromQLQueryContainer
key={rctTabKey.PROM} key={rctTabKey.PROM}
@ -198,8 +148,6 @@ function QuerySection({
]; ];
return ( return (
<>
<div style={{ display: 'flex' }}>
<Tabs <Tabs
type="card" type="card"
style={{ width: '100%' }} style={{ width: '100%' }}
@ -208,11 +156,7 @@ function QuerySection({
onChange={handleQueryCategoryChange} onChange={handleQueryCategoryChange}
tabBarExtraContent={ tabBarExtraContent={
<span style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}> <span style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
<TextToolTip <TextToolTip text="This will temporarily save the current query and graph state. This will persist across tab change" />
{...{
text: `This will temporarily save the current query and graph state. This will persist across tab change`,
}}
/>
<Button <Button
loading={isLoadingQueryResult} loading={isLoadingQueryResult}
type="primary" type="primary"
@ -224,60 +168,23 @@ function QuerySection({
} }
items={items} items={items}
/> />
</div>
{/* {localQueryChanges.map((e, index) => (
// <Query
// name={e.name}
// currentIndex={index}
// selectedTime={selectedTime}
// key={JSON.stringify(e)}
// queryInput={e}
// updatedLocalQuery={handleLocalQueryUpdate}
// queryCategory={queryCategory}
// />
<QueryBuilder
key={`${JSON.stringify(e)}`}
name={e.name}
updateQueryData={(updatedQuery) =>
handleLocalQueryUpdate({ currentIndex: index, updatedQuery })
}
onDelete={() => handleDeleteQuery({ currentIndex: index })}
queryData={e}
queryCategory={queryCategory}
/>
))} */}
</>
); );
} }
interface DispatchProps { interface DispatchProps {
// createQuery: ({
// widgetId,
// }: CreateQueryProps) => (dispatch: Dispatch<AppActions>) => void;
updateQuery: ( updateQuery: (
props: UpdateQueryProps, props: UpdateQueryProps,
) => (dispatch: Dispatch<AppActions>) => void; ) => (dispatch: Dispatch<AppActions>) => void;
// getQueryResults: (
// props: GetQueryResultsProps,
// ) => (dispatch: Dispatch<AppActions>) => void;
// updateQueryType: (
// props: UpdateQueryTypeProps,
// ) => (dispatch: Dispatch<AppActions>) => void;
} }
const mapDispatchToProps = ( const mapDispatchToProps = (
dispatch: ThunkDispatch<unknown, unknown, AppActions>, dispatch: ThunkDispatch<unknown, unknown, AppActions>,
): DispatchProps => ({ ): DispatchProps => ({
// createQuery: bindActionCreators(CreateQuery, dispatch),
updateQuery: bindActionCreators(UpdateQuery, dispatch), updateQuery: bindActionCreators(UpdateQuery, dispatch),
// getQueryResults: bindActionCreators(GetQueryResults, dispatch),
// updateQueryType: bindActionCreators(UpdateQueryType, dispatch),
}); });
interface QueryProps extends DispatchProps { interface QueryProps extends DispatchProps {
selectedGraph: GRAPH_TYPES; selectedGraph: GRAPH_TYPES;
selectedTime: timePreferance;
handleUnstagedChanges: (arg0: boolean) => void;
} }
export default connect(null, mapDispatchToProps)(QuerySection); export default connect(null, mapDispatchToProps)(QuerySection);

View File

@ -1,23 +0,0 @@
import getLocalStorageApi from 'api/browser/localstorage/get';
import setLocalStorageApi from 'api/browser/localstorage/set';
const UNSTAGE_CONFIRM_BOX_SHOW_COUNT = 2;
const UNSTAGE_CONFIRM_BOX_KEY =
'DASHBOARD_METRICS_BUILDER_UNSTAGE_STASH_CONFIRM_SHOW_COUNT';
export const showUnstagedStashConfirmBox = (): boolean => {
const showCountTillNow: number = parseInt(
getLocalStorageApi(UNSTAGE_CONFIRM_BOX_KEY) || '',
10,
);
if (Number.isNaN(showCountTillNow)) {
setLocalStorageApi(UNSTAGE_CONFIRM_BOX_KEY, '1');
return true;
}
if (showCountTillNow >= UNSTAGE_CONFIRM_BOX_SHOW_COUNT) {
return false;
}
setLocalStorageApi(UNSTAGE_CONFIRM_BOX_KEY, `${showCountTillNow + 1}`);
return true;
};

View File

@ -3,9 +3,6 @@ import { EQueryType } from 'types/common/dashboard';
import { Tag } from '../styles'; import { Tag } from '../styles';
interface IQueryTypeTagProps {
queryType: EQueryType | undefined;
}
function QueryTypeTag({ queryType }: IQueryTypeTagProps): JSX.Element { function QueryTypeTag({ queryType }: IQueryTypeTagProps): JSX.Element {
switch (queryType) { switch (queryType) {
case EQueryType.QUERY_BUILDER: case EQueryType.QUERY_BUILDER:
@ -32,4 +29,12 @@ function QueryTypeTag({ queryType }: IQueryTypeTagProps): JSX.Element {
} }
} }
interface IQueryTypeTagProps {
queryType?: EQueryType;
}
QueryTypeTag.defaultProps = {
queryType: EQueryType.QUERY_BUILDER,
};
export default QueryTypeTag; export default QueryTypeTag;

View File

@ -1,34 +1,22 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { NewWidgetProps } from '../index'; import { NewWidgetProps } from '../index';
import { timePreferance } from '../RightContainer/timeItems';
import QuerySection from './QuerySection'; import QuerySection from './QuerySection';
import { QueryContainer } from './styles'; import { QueryContainer } from './styles';
import WidgetGraph from './WidgetGraph'; import WidgetGraph from './WidgetGraph';
function LeftContainer({ function LeftContainer({
selectedGraph, selectedGraph,
selectedTime,
yAxisUnit, yAxisUnit,
handleUnstagedChanges, }: NewWidgetProps): JSX.Element {
}: LeftContainerProps): JSX.Element {
return ( return (
<> <>
<WidgetGraph selectedGraph={selectedGraph} yAxisUnit={yAxisUnit} /> <WidgetGraph selectedGraph={selectedGraph} yAxisUnit={yAxisUnit} />
<QueryContainer> <QueryContainer>
<QuerySection <QuerySection selectedGraph={selectedGraph} />
selectedTime={selectedTime}
handleUnstagedChanges={handleUnstagedChanges}
selectedGraph={selectedGraph}
/>
</QueryContainer> </QueryContainer>
</> </>
); );
} }
interface LeftContainerProps extends NewWidgetProps {
selectedTime: timePreferance;
handleUnstagedChanges: (arg0: boolean) => void;
}
export default memo(LeftContainer); export default memo(LeftContainer);

View File

@ -35,7 +35,6 @@ import {
LeftContainerWrapper, LeftContainerWrapper,
PanelContainer, PanelContainer,
RightContainerWrapper, RightContainerWrapper,
Tag,
} from './styles'; } from './styles';
function NewWidget({ function NewWidget({
@ -85,7 +84,6 @@ function NewWidget({
selectedWidget?.nullZeroValues || 'zero', selectedWidget?.nullZeroValues || 'zero',
); );
const [saveModal, setSaveModal] = useState(false); const [saveModal, setSaveModal] = useState(false);
const [hasUnstagedChanges, setHasUnstagedChanges] = useState(false);
const [graphType, setGraphType] = useState(selectedGraph); const [graphType, setGraphType] = useState(selectedGraph);
const getSelectedTime = useCallback( const getSelectedTime = useCallback(
@ -181,12 +179,7 @@ function NewWidget({
<PanelContainer> <PanelContainer>
<LeftContainerWrapper flex={5}> <LeftContainerWrapper flex={5}>
<LeftContainer <LeftContainer selectedGraph={graphType} yAxisUnit={yAxisUnit} />
handleUnstagedChanges={setHasUnstagedChanges}
selectedTime={selectedTime}
selectedGraph={graphType}
yAxisUnit={yAxisUnit}
/>
</LeftContainerWrapper> </LeftContainerWrapper>
<RightContainerWrapper flex={1}> <RightContainerWrapper flex={1}>
@ -219,26 +212,16 @@ function NewWidget({
destroyOnClose destroyOnClose
closable closable
onCancel={(): void => setSaveModal(false)} onCancel={(): void => setSaveModal(false)}
onOk={(): void => { onOk={onClickSaveHandler}
onClickSaveHandler();
}}
centered centered
open={saveModal} open={saveModal}
width={600} width={600}
> >
{hasUnstagedChanges ? (
<Typography>
Looks like you have unstaged changes. Would you like to SAVE the last
staged changes? If you want to stage new changes - Press{' '}
<Tag>Stage & Run Query</Tag> and then try saving again.
</Typography>
) : (
<Typography> <Typography>
Your graph built with{' '} Your graph built with{' '}
<QueryTypeTag queryType={selectedWidget?.query.queryType} /> query will be <QueryTypeTag queryType={selectedWidget?.query.queryType} /> query will be
saved. Press OK to confirm. saved. Press OK to confirm.
</Typography> </Typography>
)}
</Modal> </Modal>
</Container> </Container>
); );