Skip to content

Commit

Permalink
RN-1130: Update types for dashboard item presentation options (#5380)
Browse files Browse the repository at this point in the history
* Update types

* Use new types in ui-chart-components

* Use new types for matrix

* Update types

* Revert "Use new types for matrix"

This reverts commit c366962.

* Revert "Use new types in ui-chart-components"

This reverts commit 320a3c4.

* Fix broken builds

* Update types

* Update types

* Update index.ts

* Update ui-chart-components to use the correct types

* Generate types

* Update type in ui-chart-components

* Updates for ui-chart-components

* Update types in tupaia-web

* Fix error

* Fix tests

* RN-1130: Added typeguards to use for casting chartTypes

* Fix types across chart components

* Generate types

* Fix test

* Fix tests

* Fix build error

---------

Co-authored-by: Rohan Port <rohan@bes.au>
  • Loading branch information
alexd-bes and Rohan Port authored Feb 15, 2024
1 parent d4b555e commit 568bdfc
Show file tree
Hide file tree
Showing 67 changed files with 14,496 additions and 11,567 deletions.
5 changes: 3 additions & 2 deletions packages/tupaia-web/src/api/queries/useMapOverlayReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@tupaia/ui-map-components';
import { get } from '../api';
import { EntityCode, ProjectCode } from '../../types';
import { Moment } from 'moment';

type SingleMapOverlayItem = TupaiaWebMapOverlaysRequest.TranslatedMapOverlay;

Expand Down Expand Up @@ -67,8 +68,8 @@ export const useMapOverlayReport = (
entityCode?: EntityCode,
mapOverlay?: SingleMapOverlayItem,
params?: {
startDate?: string;
endDate?: string;
startDate?: string | Moment;
endDate?: string | Moment;
},
keepPreviousData?: boolean,
) => {
Expand Down
9 changes: 4 additions & 5 deletions packages/tupaia-web/src/components/DateRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@

import React from 'react';
import { Moment } from 'moment';
import { GRANULARITIES } from '@tupaia/utils';
import { VizPeriodGranularity } from '@tupaia/types';
import { DateRangePicker as DateRangePickerComponent, TextButton } from '@tupaia/ui-components';
import styled from 'styled-components';
import { ValueOf } from '../types';

const Wrapper = styled.div`
margin-top: 0.5rem;
Expand Down Expand Up @@ -77,9 +76,9 @@ const DialogPaperComponent = styled.div`
`;

interface DateRangePickerProps {
startDate?: Moment;
endDate?: Moment;
granularity?: ValueOf<typeof GRANULARITIES>;
startDate?: Moment | string;
endDate?: Moment | string;
granularity?: `${VizPeriodGranularity}`;
onSetDates?: (startDate: string, endDate: string) => void;
minDate?: string;
maxDate?: string;
Expand Down
32 changes: 20 additions & 12 deletions packages/tupaia-web/src/features/DashboardItem/DashboardItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { Moment } from 'moment';
import { useParams } from 'react-router';
import { Typography } from '@material-ui/core';
import { getDefaultDates } from '@tupaia/utils';
import { MultiValueViewConfig } from '@tupaia/types';
import { DashboardItemConfig, DashboardItem as DashboardItemType } from '../../types';
import { DashboardItemConfig } from '@tupaia/types';
import { DashboardItem as DashboardItemType } from '../../types';
import { useReport } from '../../api/queries';
import { useDashboard } from '../Dashboard';
import { DashboardItemContent } from './DashboardItemContent';
Expand Down Expand Up @@ -50,17 +50,25 @@ const Title = styled(Typography).attrs({
line-height: 1.4;
`;

const getShowDashboardItemTitle = (config: DashboardItemConfig, legacy?: boolean) => {
const { presentationOptions, type, viewType, name } = config;
const getShowDashboardItemTitle = (config?: DashboardItemConfig, legacy?: boolean) => {
if (!config) return false;
const { type, name } = config;
if (!name) return false;
if (viewType === 'multiValue') {
// if report is legacy, show title because it won't have the config set
return (
(presentationOptions as MultiValueViewConfig['presentationOptions'])?.isTitleVisible || legacy
);
if (type === 'component') return false;
if (type === 'view') {
const { viewType } = config;
if (
viewType === 'multiValue' &&
'presentationOptions' in config &&
config.presentationOptions
) {
const { presentationOptions } = config;
// if report is legacy, show title because it won't have the config set
return presentationOptions?.isTitleVisible || legacy;
}
if (viewType?.includes('Download') || viewType === 'multiSingleValue') return false;
}
if (viewType?.includes('Download') || type === 'component' || viewType === 'multiSingleValue')
return false;

return true;
};

Expand Down Expand Up @@ -92,7 +100,7 @@ export const DashboardItem = ({ dashboardItem }: { dashboardItem: DashboardItemT
legacy: dashboardItem?.legacy,
});

const { config = {}, legacy } = dashboardItem;
const { config, legacy } = dashboardItem;

const showTitle = getShowDashboardItemTitle(config, legacy);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

import React, { useContext } from 'react';
import { NoData } from '@tupaia/ui-components';
import { BaseReport } from '@tupaia/types';
import { BaseReport, DashboardItemConfig } from '@tupaia/types';
import { FetchErrorAlert } from '../../components';
import { DashboardItemReport, DashboardItemConfig } from '../../types';
import { DashboardItemReport } from '../../types';
import {
View,
Chart,
Expand All @@ -30,7 +30,7 @@ const DisplayComponents = {
NoDataAtLevelDashboard,
};

const getHasNoData = (report: DashboardItemReport, type: DashboardItemConfig['type']) => {
const getHasNoData = (report: DashboardItemReport, type?: DashboardItemConfig['type']) => {
// If there is no report, if means it is loading or there is an error, which is handled elsewhere
if (!report) return false;
if (type === 'view' || type === 'chart') {
Expand All @@ -44,9 +44,17 @@ const getHasNoData = (report: DashboardItemReport, type: DashboardItemConfig['ty
export const DashboardItemContent = () => {
const { config, report, isExport, isLoading, error, refetch } = useContext(DashboardItemContext);

const { type, componentName } = config || {};
const getComponentKey = () => {
if (config?.type === 'component' && config) {
const { componentName } = config;
if (componentName) {
return componentName;
}
}
return config?.type;
};

const componentKey = componentName || type;
const componentKey = getComponentKey();

const DisplayComponent = DisplayComponents[componentKey as keyof typeof DisplayComponents];

Expand All @@ -58,7 +66,7 @@ export const DashboardItemContent = () => {
return <DashboardItemLoader name={config?.name} isExport={isExport} />;

// if there is no data for the selected dates, then we want to show a message to the user
const showNoDataMessage = isLoading ? false : getHasNoData(report!, type);
const showNoDataMessage = isLoading ? false : getHasNoData(report!, config?.type);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
*/

import { createContext } from 'react';
import { DashboardItem, DashboardItemConfig, DashboardItemReport } from '../../types';
import { UseQueryResult } from 'react-query';
import { DashboardItemConfig } from '@tupaia/types';
import { DashboardItem, DashboardItemReport } from '../../types';

type DashboardItemState = {
config?: DashboardItemConfig | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ export const DashboardItemDateDisplay = () => {

if (!config || !report || isExport || isLoading) return null;

const { type } = config;
const { period } = report!;
const { showPeriodRange } = config;
const showPeriodRange = type === 'chart' ? config?.showPeriodRange : null;

if (!period || !period?.latestAvailable) return null;
const showLatestAvailable = isEnlarged ? showPeriodRange === 'all' : !!showPeriodRange;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import React from 'react';
import styled from 'styled-components';
import { SpinningLoader } from '@tupaia/ui-components';
import { DashboardItemConfig } from '../../types';
import { DashboardItemConfig } from '@tupaia/types';

const LoadingContainer = styled.div<{
$isExporting?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
URL_SEARCH_PARAMS,
ViewVizTypes,
} from '../../constants';
import { DashboardItemConfig } from '../../types';
import { DashboardItemContext } from './DashboardItemContext';

const ExpandableButton = styled(Button).attrs({
Expand Down Expand Up @@ -76,20 +75,24 @@ const EXPANDABLE_TYPES = [
export const ExpandItemButton = () => {
const { config, isEnlarged, isExport, report, reportCode } = useContext(DashboardItemContext);

const { viewType, type, periodGranularity } = config || ({} as DashboardItemConfig);
const { type, periodGranularity } = config || {};
const [urlSearchParams, setUrlSearchParams] = useSearchParams();

if (isEnlarged || isExport) return null;

const viewType = config?.type === 'view' ? config.viewType : undefined;

const getIsExpandable = () => {
if (periodGranularity) return true;
// always allow matrix to be expanded
else if (type === DashboardItemVizTypes.Matrix) return true;
if (type === DashboardItemVizTypes.Matrix) return true;

const comparisonType = viewType || type;
// only expand expandable types if they have data, if they don't have periodGranularity set
else if (EXPANDABLE_TYPES.includes(type) || (viewType && EXPANDABLE_TYPES.includes(viewType))) {
if (comparisonType && EXPANDABLE_TYPES.includes(comparisonType)) {
const { data } = report as ViewReport;
return data && data.length > 0;
} else if (viewType === ViewVizTypes.QRCode) {
} else if (comparisonType === ViewVizTypes.QRCode) {
const { data } = report as ViewReport;
return data && data.length > 1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import React, { useContext } from 'react';
import styled from 'styled-components';
import { useSearchParams } from 'react-router-dom';
import { BaseReport, ViewConfig } from '@tupaia/types';
import { BaseReport, ChartPresentationOptions, ViewConfig } from '@tupaia/types';
import { URL_SEARCH_PARAMS } from '../../constants';
import { Modal } from '../../components';
import { Entity } from '../../types';
Expand Down Expand Up @@ -57,13 +57,28 @@ export const EnlargedDashboardItem = ({ entityName }: { entityName?: Entity['nam
const { reportCode, currentDashboardItem, isLoadingDashboards, reportData } =
useEnlargedDashboardItem();

const { type, presentationOptions } = currentDashboardItem?.config || {};
const { type } = currentDashboardItem?.config || {};

const {
exportWithLabels = false,
exportWithTable = true,
exportWithTableDisabled = false,
} = presentationOptions || {};
const getPresentationOptions = () => {
if (currentDashboardItem?.config && 'presentationOptions' in currentDashboardItem?.config) {
return currentDashboardItem?.config?.presentationOptions;
}
return {};
};

const presentationOptions = getPresentationOptions();

// not all dashboard item types have these export settings. Realistically, only charts use these
const getExportSetting = (setting: keyof ChartPresentationOptions, defaultValue: boolean) => {
if (presentationOptions && setting in presentationOptions) {
return presentationOptions[setting];
}
return defaultValue;
};

const exportWithLabels = getExportSetting('exportWithLabels', false);
const exportWithTable = getExportSetting('exportWithTable', true);
const exportWithTableDisabled = getExportSetting('exportWithTableDisabled', false);

if (!reportCode || (!isLoadingDashboards && !currentDashboardItem)) return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,32 @@ export const EnlargedDashboardVisual = ({

// today's date for export
const date = String(moment());

const getMergedConfig = () => {
// gauge charts don't have presentation options
if (config?.type !== 'chart' || config?.chartType === 'gauge') return config;
// only apply these changes to chart types, as they are not relevant to other types
if ('presentationOptions' in currentDashboardItem?.config) {
return {
...config,
presentationOptions: {
...config?.presentationOptions,
exportWithLabels,
exportWithTable,
},
};
}
return {
...config,
presentationOptions: {
exportWithLabels,
exportWithTable,
},
};
};

const mergedConfig = getMergedConfig();

return (
<Container $isExportMode={isExportMode}>
<TitleWrapper>
Expand Down Expand Up @@ -145,14 +171,7 @@ export const EnlargedDashboardVisual = ({
isEnlarged: true,
isExport: isPreview,
reportCode: currentDashboardItem?.reportCode,
config: {
...currentDashboardItem?.config,
presentationOptions: {
...currentDashboardItem?.config?.presentationOptions,
exportWithLabels,
exportWithTable,
},
},
config: mergedConfig,
}}
>
<DashboardItemContent />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,20 @@ export const ExportButton = () => {
const [urlSearchParams] = useSearchParams();
const { isExportMode, setIsExportMode } = useContext(ExportDashboardItemContext);
const { currentDashboardItem } = useEnlargedDashboardItem();
const { type, viewType } = currentDashboardItem?.config || {};
const displayType = viewType || type;
const getDisplayType = () => {
if (!currentDashboardItem?.config) return null;
const { config } = currentDashboardItem;
if (config.type === 'view') {
const { viewType } = config;
return viewType;
}
return config.type;
};
const displayType = getDisplayType();

// Only show export button if the current dashboard item is a chart, matrix or multi-value view AND it is not a drilldown
const canExport =
displayType &&
EXPORTABLE_TYPES.includes(displayType) &&
!urlSearchParams.get(URL_SEARCH_PARAMS.REPORT_DRILLDOWN_ID);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import React, { useContext, useRef } from 'react';
import styled from 'styled-components';
import { Typography } from '@material-ui/core';
import { Button as BaseButton, SpinningLoader } from '@tupaia/ui-components';
import { DashboardItemVizTypes, ViewVizTypes } from '../../constants';
import { ViewVizTypes } from '../../constants';
import { Entity } from '../../types';
import { DisplayOptionsSettings, ExportFormatSettings, ExportFormats } from '../ExportSettings';
import {
Expand Down Expand Up @@ -75,14 +75,27 @@ export const ExportDashboardItem = ({ entityName }: { entityName?: Entity['name'
},
];

const { type, viewType } = currentDashboardItem?.config ?? {};
const isChart = type === DashboardItemVizTypes.Chart;
const isChart = currentDashboardItem?.config?.type === 'chart';

// PNG export is not available for matrix reports
const availableExportOptions =
isChart || viewType === ViewVizTypes.MultiValue
? exportOptions
: exportOptions.filter(option => option.value !== ExportFormats.PNG);
const getHasPNGExportOption = () => {
if (!currentDashboardItem?.config) return false;
const { type } = currentDashboardItem?.config;
if (isChart) {
return true;
}
if (type === 'view') {
const { viewType } = currentDashboardItem?.config;
return viewType === ViewVizTypes.MultiValue;
}
return false;
};

const hasPNGExportOption = getHasPNGExportOption();

const availableExportOptions = hasPNGExportOption
? exportOptions
: exportOptions.filter(option => option.value !== ExportFormats.PNG);

return (
<Wrapper>
Expand Down
Loading

0 comments on commit 568bdfc

Please sign in to comment.