mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-02 13:43:22 +00:00
UI: Converted data insight dropdown to checkbox dropdown (#9368)
* UI: Converted data insight dropdown to checkbox dropdown * addressing comments
This commit is contained in:
parent
0bd96bc115
commit
d0efcef6b0
@ -87,28 +87,13 @@ export const DAY_FILTER = [
|
||||
},
|
||||
];
|
||||
|
||||
export const TIER_FILTER = [
|
||||
{
|
||||
value: 'Tier.Tier1',
|
||||
label: i18n.t('label.tier-number', { tier: 1 }),
|
||||
},
|
||||
{
|
||||
value: 'Tier.Tier2',
|
||||
label: i18n.t('label.tier-number', { tier: 2 }),
|
||||
},
|
||||
{
|
||||
value: 'Tier.Tier3',
|
||||
label: i18n.t('label.tier-number', { tier: 3 }),
|
||||
},
|
||||
{
|
||||
value: 'Tier.Tier4',
|
||||
label: i18n.t('label.tier-number', { tier: 4 }),
|
||||
},
|
||||
{
|
||||
value: 'Tier.Tier5',
|
||||
label: i18n.t('label.tier-number', { tier: 5 }),
|
||||
},
|
||||
];
|
||||
export const TIER_FILTER = {
|
||||
[i18n.t('label.tier-number', { tier: 1 })]: 'Tier.Tier1',
|
||||
[i18n.t('label.tier-number', { tier: 2 })]: 'Tier.Tier2',
|
||||
[i18n.t('label.tier-number', { tier: 3 })]: 'Tier.Tier3',
|
||||
[i18n.t('label.tier-number', { tier: 4 })]: 'Tier.Tier4',
|
||||
[i18n.t('label.tier-number', { tier: 5 })]: 'Tier.Tier5',
|
||||
};
|
||||
|
||||
export const INITIAL_CHART_FILTER: ChartFilter = {
|
||||
startTs: getPastDaysDateTimeMillis(DEFAULT_DAYS),
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2022 Collate
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type TeamStateType = {
|
||||
defaultOptions: string[];
|
||||
selectedOptions: string[];
|
||||
options: string[];
|
||||
};
|
||||
export type TierStateType = Omit<TeamStateType, 'defaultOptions'>;
|
@ -17,13 +17,14 @@ import {
|
||||
Col,
|
||||
Row,
|
||||
Select,
|
||||
SelectProps,
|
||||
Space,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { t } from 'i18next';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { useEffect, useLayoutEffect, useMemo, useState } from 'react';
|
||||
import { ListItem } from 'react-awesome-query-builder';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { getListKPIs } from '../../axiosAPIs/KpiAPI';
|
||||
import { searchQuery } from '../../axiosAPIs/searchAPI';
|
||||
@ -38,8 +39,9 @@ import TierInsight from '../../components/DataInsightDetail/TierInsight';
|
||||
import TopActiveUsers from '../../components/DataInsightDetail/TopActiveUsers';
|
||||
import TopViewEntities from '../../components/DataInsightDetail/TopViewEntities';
|
||||
import TotalEntityInsight from '../../components/DataInsightDetail/TotalEntityInsight';
|
||||
import SearchDropdown from '../../components/SearchDropdown/SearchDropdown';
|
||||
import { autocomplete } from '../../constants/AdvancedSearch.constants';
|
||||
import { ROUTES } from '../../constants/constants';
|
||||
import { PAGE_SIZE, ROUTES } from '../../constants/constants';
|
||||
import {
|
||||
DAY_FILTER,
|
||||
DEFAULT_DAYS,
|
||||
@ -65,6 +67,7 @@ import {
|
||||
getFormattedDateFromMilliSeconds,
|
||||
getPastDaysDateTimeMillis,
|
||||
} from '../../utils/TimeUtils';
|
||||
import { TeamStateType, TierStateType } from './DataInsight.interface';
|
||||
import './DataInsight.less';
|
||||
import DataInsightLeftPanel from './DataInsightLeftPanel';
|
||||
import KPIList from './KPIList';
|
||||
@ -77,7 +80,16 @@ const DataInsightPage = () => {
|
||||
const { isAdminUser } = useAuth();
|
||||
const history = useHistory();
|
||||
|
||||
const [teamsOptions, setTeamOptions] = useState<SelectProps['options']>([]);
|
||||
const [teamsOptions, setTeamOptions] = useState<TeamStateType>({
|
||||
defaultOptions: [],
|
||||
selectedOptions: [],
|
||||
options: [],
|
||||
});
|
||||
const [tierOptions, setTierOptions] = useState<TierStateType>({
|
||||
selectedOptions: [],
|
||||
options: [],
|
||||
});
|
||||
|
||||
const [activeTab, setActiveTab] = useState(DataInsightTabs.DATA_ASSETS);
|
||||
const [chartFilter, setChartFilter] =
|
||||
useState<ChartFilter>(INITIAL_CHART_FILTER);
|
||||
@ -85,6 +97,10 @@ const DataInsightPage = () => {
|
||||
|
||||
const [selectedChart, setSelectedChart] = useState<DataInsightChartType>();
|
||||
|
||||
const defaultTierOptions = useMemo(() => {
|
||||
return Object.keys(TIER_FILTER);
|
||||
}, []);
|
||||
|
||||
const { descriptionKpi, ownerKpi } = useMemo(() => {
|
||||
return {
|
||||
descriptionKpi: kpiList.find(
|
||||
@ -101,9 +117,12 @@ const DataInsightPage = () => {
|
||||
}, [kpiList]);
|
||||
|
||||
const handleTierChange = (tiers: string[] = []) => {
|
||||
setTierOptions((prev) => ({ ...prev, selectedOptions: tiers }));
|
||||
setChartFilter((previous) => ({
|
||||
...previous,
|
||||
tier: tiers.length ? tiers.join(',') : undefined,
|
||||
tier: tiers.length
|
||||
? tiers.map((tier) => TIER_FILTER[tier]).join(',')
|
||||
: undefined,
|
||||
}));
|
||||
};
|
||||
|
||||
@ -116,6 +135,10 @@ const DataInsightPage = () => {
|
||||
};
|
||||
|
||||
const handleTeamChange = (teams: string[] = []) => {
|
||||
setTeamOptions((prev) => ({
|
||||
...prev,
|
||||
selectedOptions: teams,
|
||||
}));
|
||||
setChartFilter((previous) => ({
|
||||
...previous,
|
||||
team: teams.length ? teams.join(',') : undefined,
|
||||
@ -123,38 +146,79 @@ const DataInsightPage = () => {
|
||||
};
|
||||
|
||||
const handleTeamSearch = async (query: string) => {
|
||||
if (fetchTeamSuggestions) {
|
||||
if (fetchTeamSuggestions && !isEmpty(query)) {
|
||||
try {
|
||||
const response = await fetchTeamSuggestions(query, 5);
|
||||
setTeamOptions(getTeamFilter(response.values));
|
||||
const response = await fetchTeamSuggestions(query, PAGE_SIZE);
|
||||
setTeamOptions((prev) => ({
|
||||
...prev,
|
||||
options: getTeamFilter(response.values as ListItem[]),
|
||||
}));
|
||||
} catch (_error) {
|
||||
// we will not show the toast error message for suggestion API
|
||||
}
|
||||
} else {
|
||||
setTeamOptions((prev) => ({
|
||||
...prev,
|
||||
options: prev.defaultOptions,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const handleTierSearch = async (query: string) => {
|
||||
if (query) {
|
||||
setTierOptions((prev) => ({
|
||||
...prev,
|
||||
options: prev.options.filter((value) =>
|
||||
value.toLocaleLowerCase().includes(query.toLocaleLowerCase())
|
||||
),
|
||||
}));
|
||||
} else {
|
||||
setTierOptions((prev) => ({
|
||||
...prev,
|
||||
options: defaultTierOptions,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const fetchDefaultTeamOptions = async () => {
|
||||
if (teamsOptions.defaultOptions.length) {
|
||||
setTeamOptions((prev) => ({
|
||||
...prev,
|
||||
options: prev.defaultOptions,
|
||||
}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await searchQuery({
|
||||
searchIndex: SearchIndex.TEAM,
|
||||
query: '*',
|
||||
pageSize: 5,
|
||||
pageSize: PAGE_SIZE,
|
||||
});
|
||||
const hits = response.hits.hits;
|
||||
const teamFilterOptions = hits.map((hit) => {
|
||||
const source = hit._source;
|
||||
|
||||
return {
|
||||
label: source.displayName || source.name,
|
||||
value: source.fullyQualifiedName || source.name,
|
||||
};
|
||||
return source.name;
|
||||
});
|
||||
setTeamOptions(teamFilterOptions);
|
||||
setTeamOptions((prev) => ({
|
||||
...prev,
|
||||
defaultOptions: teamFilterOptions,
|
||||
options: teamFilterOptions,
|
||||
}));
|
||||
} catch (_error) {
|
||||
// we will not show the toast error message for search API
|
||||
}
|
||||
};
|
||||
|
||||
const fetchDefaultTierOptions = () => {
|
||||
setTierOptions((prev) => ({
|
||||
...prev,
|
||||
options: defaultTierOptions,
|
||||
}));
|
||||
};
|
||||
|
||||
const fetchKpiList = async () => {
|
||||
try {
|
||||
const response = await getListKPIs({ fields: 'dataInsightChart' });
|
||||
@ -230,26 +294,24 @@ const DataInsightPage = () => {
|
||||
<Card>
|
||||
<Space className="w-full justify-between">
|
||||
<Space className="w-full">
|
||||
<Select
|
||||
allowClear
|
||||
showArrow
|
||||
className="data-insight-select-dropdown"
|
||||
mode="multiple"
|
||||
notFoundContent={null}
|
||||
options={teamsOptions}
|
||||
placeholder={t('label.select-teams')}
|
||||
<SearchDropdown
|
||||
label={t('label.team')}
|
||||
options={teamsOptions.options}
|
||||
searchKey="teams"
|
||||
selectedKeys={teamsOptions.selectedOptions}
|
||||
onChange={handleTeamChange}
|
||||
onGetInitialOptions={fetchDefaultTeamOptions}
|
||||
onSearch={handleTeamSearch}
|
||||
/>
|
||||
<Select
|
||||
allowClear
|
||||
showArrow
|
||||
className="data-insight-select-dropdown"
|
||||
mode="multiple"
|
||||
notFoundContent={null}
|
||||
options={TIER_FILTER}
|
||||
placeholder={t('label.select-tiers')}
|
||||
|
||||
<SearchDropdown
|
||||
label={t('label.tier')}
|
||||
options={tierOptions.options}
|
||||
searchKey="tier"
|
||||
selectedKeys={tierOptions.selectedOptions}
|
||||
onChange={handleTierChange}
|
||||
onGetInitialOptions={fetchDefaultTierOptions}
|
||||
onSearch={handleTierSearch}
|
||||
/>
|
||||
</Space>
|
||||
<Space>
|
||||
|
@ -26,7 +26,7 @@ import {
|
||||
} from 'lodash';
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { ListItem, ListValues } from 'react-awesome-query-builder';
|
||||
import { ListItem } from 'react-awesome-query-builder';
|
||||
import { LegendProps, Surface } from 'recharts';
|
||||
import {
|
||||
GRAYED_OUT_COLOR,
|
||||
@ -421,11 +421,8 @@ export const getGraphDataByTierType = (rawData: TotalEntitiesByTier[]) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const getTeamFilter = (suggestionValues: ListValues = []) => {
|
||||
return (suggestionValues as ListItem[]).map((suggestion: ListItem) => ({
|
||||
label: suggestion.title,
|
||||
value: suggestion.value,
|
||||
}));
|
||||
export const getTeamFilter = (suggestionValues: ListItem[]): string[] => {
|
||||
return suggestionValues.map((suggestion) => suggestion.value);
|
||||
};
|
||||
|
||||
export const getFormattedActiveUsersData = (
|
||||
|
Loading…
x
Reference in New Issue
Block a user