Skip to content

Commit

Permalink
feat: feature flag is updated (#2666)
Browse files Browse the repository at this point in the history
* feat: flag is updated

* feat: feature flag is updated

* feat: onrefetch is added on several actions on app

* chore: tab is updated

* chore: creating dashbaord error is handled

* fix: message is fixed

* chore: jest test is updated
  • Loading branch information
palashgdev committed May 19, 2023
1 parent e7f5adc commit 604d98b
Show file tree
Hide file tree
Showing 38 changed files with 646 additions and 324 deletions.
23 changes: 0 additions & 23 deletions frontend/src/api/features/getFeatures.ts

This file was deleted.

7 changes: 0 additions & 7 deletions frontend/src/constants/featureKeys.ts

This file was deleted.

9 changes: 7 additions & 2 deletions frontend/src/constants/features.ts
@@ -1,6 +1,11 @@
// keep this consistent with backend constants.go
export enum FeatureKeys {
SSO = 'SSO',
ENTERPRISE_PLAN = 'ENTERPRISE_PLAN',
BASIC_PLAN = 'BASIC_PLAN',
DurationSort = 'DurationSort',
TimestampSort = 'TimestampSort',
SMART_TRACE_DETAIL = 'SMART_TRACE_DETAIL',
CUSTOM_METRICS_FUNCTION = 'CUSTOM_METRICS_FUNCTION',
QUERY_BUILDER_PANELS = 'QUERY_BUILDER_PANELS',
QUERY_BUILDER_ALERTS = 'QUERY_BUILDER_ALERTS',
DISABLE_UPSELL = 'DISABLE_UPSELL',
}
3 changes: 3 additions & 0 deletions frontend/src/constants/reactQueryKeys.ts
@@ -0,0 +1,3 @@
export const REACT_QUERY_KEY = {
GET_ALL_LICENCES: 'GET_ALL_LICENCES',
};
52 changes: 24 additions & 28 deletions frontend/src/container/AppLayout/index.tsx
Expand Up @@ -18,7 +18,7 @@ import {
UPDATE_CONFIGS,
UPDATE_CURRENT_ERROR,
UPDATE_CURRENT_VERSION,
UPDATE_FEATURE_FLAGS,
UPDATE_FEATURE_FLAG_RESPONSE,
UPDATE_LATEST_VERSION,
UPDATE_LATEST_VERSION_ERROR,
} from 'types/actions/app';
Expand Down Expand Up @@ -129,19 +129,6 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
message: t('oops_something_went_wrong_version'),
});
}
if (
getFeaturesResponse.isFetched &&
getFeaturesResponse.isSuccess &&
getFeaturesResponse.data &&
getFeaturesResponse.data.payload
) {
dispatch({
type: UPDATE_FEATURE_FLAGS,
payload: {
...getFeaturesResponse.data.payload,
},
});
}

if (
getUserVersionResponse.isFetched &&
Expand Down Expand Up @@ -173,20 +160,6 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
});
}

if (
getFeaturesResponse.isFetched &&
getFeaturesResponse.isSuccess &&
getFeaturesResponse.data &&
getFeaturesResponse.data.payload
) {
dispatch({
type: UPDATE_FEATURE_FLAGS,
payload: {
...getFeaturesResponse.data.payload,
},
});
}

if (
getDynamicConfigsResponse.isFetched &&
getDynamicConfigsResponse.isSuccess &&
Expand Down Expand Up @@ -226,6 +199,29 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
notifications,
]);

useEffect(() => {
if (
getFeaturesResponse.isFetched &&
getFeaturesResponse.isSuccess &&
getFeaturesResponse.data &&
getFeaturesResponse.data.payload
) {
dispatch({
type: UPDATE_FEATURE_FLAG_RESPONSE,
payload: {
featureFlag: getFeaturesResponse.data.payload,
refetch: getFeaturesResponse.refetch,
},
});
}
}, [
dispatch,
getFeaturesResponse.data,
getFeaturesResponse.isFetched,
getFeaturesResponse.isSuccess,
getFeaturesResponse.refetch,
]);

const isToDisplayLayout = isLoggedIn;

return (
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/container/CreateAlertRule/defaults.ts
Expand Up @@ -36,8 +36,16 @@ export const alertDefaults: AlertDef = {
},
},
promQueries: {},
chQueries: {},
queryType: EQueryType.QUERY_BUILDER,
chQueries: {
A: {
name: 'A',
query: ``,
rawQuery: ``,
legend: '',
disabled: false,
},
},
queryType: EQueryType.CLICKHOUSE,
panelType: PANEL_TYPES.TIME_SERIES,
},
op: defaultCompareOp,
Expand Down
15 changes: 9 additions & 6 deletions frontend/src/container/FormAlertRules/QuerySection.tsx
Expand Up @@ -2,7 +2,7 @@ import { Button, Tabs } from 'antd';
import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { QueryBuilder } from 'container/QueryBuilder';
import React from 'react';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { AlertTypes } from 'types/api/alerts/alertTypes';
import { IChQueries, IPromQueries } from 'types/api/alerts/compositeQuery';
Expand Down Expand Up @@ -91,11 +91,14 @@ function QuerySection({
},
];

const items = [
{ label: t('tab_qb'), key: EQueryType.QUERY_BUILDER },
{ label: t('tab_chquery'), key: EQueryType.CLICKHOUSE },
{ label: t('tab_promql'), key: EQueryType.PROM },
];
const items = useMemo(
() => [
{ label: t('tab_qb'), key: EQueryType.QUERY_BUILDER },
{ label: t('tab_chquery'), key: EQueryType.CLICKHOUSE },
{ label: t('tab_promql'), key: EQueryType.PROM },
],
[t],
);

const renderTabs = (typ: AlertTypes): JSX.Element | null => {
switch (typ) {
Expand Down
35 changes: 26 additions & 9 deletions frontend/src/container/FormAlertRules/index.tsx
@@ -1,11 +1,13 @@
import { ExclamationCircleOutlined, SaveOutlined } from '@ant-design/icons';
import { Col, FormInstance, Modal, Typography } from 'antd';
import { Col, FormInstance, Modal, Tooltip, Typography } from 'antd';
import saveAlertApi from 'api/alerts/save';
import testAlertApi from 'api/alerts/testAlert';
import { FeatureKeys } from 'constants/features';
import ROUTES from 'constants/routes';
import QueryTypeTag from 'container/NewWidget/LeftContainer/QueryTypeTag';
import PlotTag from 'container/NewWidget/LeftContainer/WidgetGraph/PlotTag';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
import { useNotifications } from 'hooks/useNotifications';
import history from 'lib/history';
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
Expand Down Expand Up @@ -145,6 +147,7 @@ function FormAlertRules({
// onQueryCategoryChange handles changes to query category
// in state as well as sets additional defaults
const onQueryCategoryChange = (val: EQueryType): void => {
console.log('onQueryCategoryChange', val);
setQueryCategory(val);
if (val === EQueryType.PROM) {
setAlertDef({
Expand Down Expand Up @@ -298,6 +301,10 @@ function FormAlertRules({
initQuery,
]);

const isAlertAvialable = useIsFeatureDisabled(
FeatureKeys.QUERY_BUILDER_ALERTS,
);

const saveRule = useCallback(async () => {
if (!isFormValid()) {
return;
Expand Down Expand Up @@ -437,6 +444,12 @@ function FormAlertRules({
selectedInterval={toChartInterval(alertDef.evalWindow)}
/>
);

const isNewRule = ruleId === 0;

const isAlertAvialableToSave =
isAlertAvialable && isNewRule && queryCategory === EQueryType.QUERY_BUILDER;

return (
<>
{Element}
Expand Down Expand Up @@ -469,14 +482,18 @@ function FormAlertRules({

{renderBasicInfo()}
<ButtonContainer>
<ActionButton
loading={loading || false}
type="primary"
onClick={onSaveHandler}
icon={<SaveOutlined />}
>
{ruleId > 0 ? t('button_savechanges') : t('button_createrule')}
</ActionButton>
<Tooltip title={isAlertAvialableToSave ? MESSAGE.ALERT : ''}>
<ActionButton
loading={loading || false}
type="primary"
onClick={onSaveHandler}
icon={<SaveOutlined />}
disabled={isAlertAvialableToSave}
>
{isNewRule ? t('button_createrule') : t('button_savechanges')}
</ActionButton>
</Tooltip>

<ActionButton
loading={loading || false}
type="default"
Expand Down
40 changes: 32 additions & 8 deletions frontend/src/container/GridGraphLayout/Graph/index.tsx
Expand Up @@ -2,12 +2,14 @@ import { Typography } from 'antd';
import { ChartData } from 'chart.js';
import Spinner from 'components/Spinner';
import GridGraphComponent from 'container/GridGraphComponent';
import { useNotifications } from 'hooks/useNotifications';
import usePreviousValue from 'hooks/usePreviousValue';
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
import getChartData from 'lib/getChartData';
import isEmpty from 'lodash-es/isEmpty';
import React, { memo, useCallback, useMemo, useState } from 'react';
import { Layout } from 'react-grid-layout';
import { useTranslation } from 'react-i18next';
import { useInView } from 'react-intersection-observer';
import { useQuery } from 'react-query';
import { connect, useSelector } from 'react-redux';
Expand All @@ -20,8 +22,8 @@ import {
import { GetMetricQueryRange } from 'store/actions/dashboard/getQueryResults';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { GlobalTime } from 'types/actions/globalTime';
import { Widgets } from 'types/api/dashboard/getAll';
import AppReducer from 'types/reducer/app';
import DashboardReducer from 'types/reducer/dashboards';
import { GlobalReducer } from 'types/reducer/globalTime';

Expand All @@ -46,18 +48,22 @@ function GridCardGraph({
initialInView: true,
});

const { notifications } = useNotifications();

const { t } = useTranslation(['common']);

const [errorMessage, setErrorMessage] = useState<string | undefined>('');
const [hovered, setHovered] = useState(false);
const [modal, setModal] = useState(false);
const [deleteModal, setDeleteModal] = useState(false);

const { minTime, maxTime } = useSelector<AppState, GlobalTime>(
(state) => state.globalTime,
);
const { selectedTime: globalSelectedInterval } = useSelector<
const { minTime, maxTime, selectedTime: globalSelectedInterval } = useSelector<
AppState,
GlobalReducer
>((state) => state.globalTime);
const { featureResponse } = useSelector<AppState, AppReducer>(
(state) => state.app,
);
const { dashboards } = useSelector<AppState, DashboardReducer>(
(state) => state.dashboards,
);
Expand Down Expand Up @@ -122,9 +128,27 @@ function GridCardGraph({

const widgetId = isEmptyWidget ? layout[0].i : widget?.id;

deleteWidget({ widgetId, setLayout });
onToggleModal(setDeleteModal);
}, [deleteWidget, layout, onToggleModal, setLayout, widget]);
featureResponse
.refetch()
.then(() => {
deleteWidget({ widgetId, setLayout });
onToggleModal(setDeleteModal);
})
.catch(() => {
notifications.error({
message: t('common:something_went_wrong'),
});
});
}, [
widget,
layout,
featureResponse,
deleteWidget,
setLayout,
onToggleModal,
notifications,
t,
]);

const getModals = (): JSX.Element => (
<>
Expand Down
30 changes: 29 additions & 1 deletion frontend/src/container/GridGraphLayout/GraphLayout.tsx
@@ -1,6 +1,9 @@
import { PlusOutlined, SaveFilled } from '@ant-design/icons';
import { Typography } from 'antd';
import { FeatureKeys } from 'constants/features';
import useComponentPermission from 'hooks/useComponentPermission';
import { useIsDarkMode } from 'hooks/useDarkMode';
import useFeatureFlag, { MESSAGE } from 'hooks/useFeatureFlag';
import React from 'react';
import { Layout } from 'react-grid-layout';
import { useSelector } from 'react-redux';
Expand All @@ -14,6 +17,7 @@ import {
ButtonContainer,
Card,
CardContainer,
NoPanelAvialable,
ReactGridLayout,
} from './styles';

Expand All @@ -35,6 +39,8 @@ function GraphLayout({
role,
);

const queryBuilderFeature = useFeatureFlag(FeatureKeys.QUERY_BUILDER_PANELS);

return (
<>
<ButtonContainer>
Expand Down Expand Up @@ -74,9 +80,31 @@ function GraphLayout({
onLayoutChange={onLayoutChangeHandler}
draggableHandle=".drag-handle"
>
{layouts.map(({ Component, ...rest }) => {
{layouts.map(({ Component, ...rest }, layoutIndex) => {
const currentWidget = (widgets || [])?.find((e) => e.id === rest.i);

const usageLimit = queryBuilderFeature?.usage_limit || 0;

const isPanelNotAvialable = usageLimit > 0 && usageLimit <= layoutIndex;

if (isPanelNotAvialable) {
return (
<CardContainer
data-grid={rest}
isDarkMode={isDarkMode}
key={currentWidget?.id}
>
<Card>
<Typography.Text type="danger">
<NoPanelAvialable isDarkMode={isDarkMode}>
{MESSAGE.WIDGET.replace('{{widget}}', usageLimit.toString())}
</NoPanelAvialable>
</Typography.Text>
</Card>
</CardContainer>
);
}

return (
<CardContainer
isDarkMode={isDarkMode}
Expand Down

0 comments on commit 604d98b

Please sign in to comment.