Skip to content

Commit

Permalink
Merge pull request #1614 from merico-dev/current-view-filters-value
Browse files Browse the repository at this point in the history
add useVisibleFilters
  • Loading branch information
GerilLeto authored Feb 7, 2025
2 parents 4e0739b + 8718c35 commit 03bedbb
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 14 deletions.
27 changes: 16 additions & 11 deletions dashboard/src/components/filter/filter-date-range/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,25 @@ const fallbackValue: DateRangeValue = {
shortcut: null,
};

export const formatDateRangeValue = (value: DateRangeValue) => {
const valueFromShortcut = getDateRangeShortcutValue(value.shortcut);
if (valueFromShortcut) {
return valueFromShortcut;
}
if (Array.isArray(value.value)) {
return value;
}
return fallbackValue;
};

const useFormattedDateRangeValue = (value: DateRangeValue) => {
const formattedValue: DateRangeValue = useMemo(() => formatDateRangeValue(value), [value]);
return formattedValue;
};
export const FilterDateRange = observer(
({ label, config, value = fallbackValue, onChange, disabled }: IFilterDateRange) => {
const { inputFormat, required, max_days, allowSingleDateInRange } = config;

const formattedValue: DateRangeValue = useMemo(() => {
const valueFromShortcut = getDateRangeShortcutValue(value.shortcut);
if (valueFromShortcut) {
return valueFromShortcut;
}
if (Array.isArray(value.value)) {
return value;
}
return fallbackValue;
}, [value]);
const formattedValue = useFormattedDateRangeValue(value);

return (
<DateRangeWidget
Expand Down
4 changes: 3 additions & 1 deletion dashboard/src/components/filter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import _ from 'lodash';
import { observer } from 'mobx-react-lite';
import { useEffect, useMemo } from 'react';
import { Controller, useForm, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useRenderContentModelContext } from '~/contexts';
import { FilterMetaInstance, ViewMetaInstance } from '~/model';
import { Filter } from './filter';
import { SearchButton } from './search-button';
import { useUpdateFilterPreviewValues } from './use-update-filter-preview-values';
import { useTranslation } from 'react-i18next';

export { type IFormattedFilter, useVisibleFilters } from './use-visible-filters';

const FilterToggler = ({ opened, toggle }: { opened: boolean; toggle: () => void }) => {
const { t } = useTranslation();
Expand Down
91 changes: 91 additions & 0 deletions dashboard/src/components/filter/use-visible-filters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import dayjs from 'dayjs';
import { useMemo } from 'react';
import { useDashboardContext } from '../../contexts';
import {
DashboardFilterType,
DateRangeValue,
EViewComponentType,
FilterDateRangeConfigInstance,
FilterMetaInstance,
FilterSelectConfigInstance,
} from '../../model';
import { formatDateRangeValue } from './filter-date-range/render';

const NOT_AVAILABLE = 'N/A';

/**
* Returns the formatted filter values in the current view.
*/
export function useVisibleFilters(): IFormattedFilter[] {
const model = useDashboardContext();
const visibleViews = model.content.views.visibleViews;
return useMemo(() => {
const viewIds = visibleViews.map((it) => {
if (it.type === EViewComponentType.Tabs) {
return it.tabView?.view_id;
}
return it.id;
});
const filters = viewIds
.filter(Boolean)
.flatMap((it) => model.content.filters.visibleInView(it!))
.filter(Boolean);
return filters.map((it) => formatFilter(it));
}, [visibleViews]);
}

export interface IFormattedFilter {
label: string;
value: string | string[];
}

function formatFilter(filter: FilterMetaInstance): IFormattedFilter {
switch (filter.type) {
case DashboardFilterType.Select:
case DashboardFilterType.MultiSelect:
case DashboardFilterType.TreeSelect:
case DashboardFilterType.TreeSingleSelect:
return { label: filter.label, value: valueOfSelect(filter.config, filter.value) };
case DashboardFilterType.TextInput:
return { label: filter.label, value: valueOfTextInput(filter.value) };
case DashboardFilterType.DateRange:
return { label: filter.label, value: valueOfDateRange(filter.config, filter.value) };
case DashboardFilterType.Checkbox:
return { label: filter.label, value: valueOfCheckbox(filter.value) };
default:
return { label: filter.label, value: filter.value };
}
}

function valueOfSelect(config: FilterSelectConfigInstance, value: string | string[]): string {
const set = new Set();
if (Array.isArray(value)) {
value.forEach((it) => set.add(it));
} else {
set.add(value);
}
if (set.size === 0) {
return NOT_AVAILABLE;
}
return config.options
.filter((it) => set.has(it.value))
.map((it) => it.label)
.join(', ');
}

function valueOfTextInput(value: string): string {
return value;
}

function valueOfDateRange(config: FilterDateRangeConfigInstance, value: DateRangeValue): string {
const formattedValue = formatDateRangeValue(value);
const dateValues = formattedValue.value.filter((it) => !!it).map((it) => dayjs(it).format(config.inputFormat));
if (dateValues.length === 0) {
return NOT_AVAILABLE;
}
return dateValues.join(' - ');
}

function valueOfCheckbox(value: boolean): string {
return value ? '✔️' : '❌';
}
1 change: 1 addition & 0 deletions dashboard/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from './dashboard-editor';
export * from './dashboard-render';
export * from './components/view';
export * from './components/panel';
export { type IFormattedFilter, useVisibleFilters } from './components/filter';
export * from './contexts';
export * from './types';
export * from './model';
Expand Down
5 changes: 3 additions & 2 deletions website/src/utils/install-dashboard-website-plugin.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IPanelAddonRenderProps, pluginManager } from '@devtable/dashboard';
import { IPanelAddonRenderProps, pluginManager, useVisibleFilters } from '@devtable/dashboard';
import { ActionIcon } from '@mantine/core';
import { IconBug } from '@tabler/icons-react';
import React from 'react';
Expand All @@ -15,6 +15,7 @@ export const PrintEChartsOptionAddon = ({ viz, isInEditMode }: IPanelAddonRender
channel.off('rendered', listener);
};
}, [viz.messageChannels]);
const formattedFilters = useVisibleFilters();
if (!renderOptions || isInEditMode) {
return null;
}
Expand All @@ -24,7 +25,7 @@ export const PrintEChartsOptionAddon = ({ viz, isInEditMode }: IPanelAddonRender
onClick={(ev) => {
ev.stopPropagation();
ev.preventDefault();
console.log('ask ai', renderOptions);
console.log('debug', renderOptions, 'filters', formattedFilters);
}}
size="sm"
variant="transparent"
Expand Down

0 comments on commit 03bedbb

Please sign in to comment.