diff --git a/packages/constants/src/dashboards/dashboards.ts b/packages/constants/src/dashboards/dashboards.ts index 787f451e02..50ee6ebc33 100644 --- a/packages/constants/src/dashboards/dashboards.ts +++ b/packages/constants/src/dashboards/dashboards.ts @@ -361,3 +361,8 @@ export const TEXT_WIDGET_Y_AXIS_METRICS_LIST: EWidgetYAxisMetric[] = [ EWidgetYAxisMetric.WORK_ITEM_DUE_THIS_WEEK_COUNT, EWidgetYAxisMetric.WORK_ITEM_DUE_TODAY_COUNT, ]; + +export const TO_CAPITALIZE_PROPERTIES: EWidgetXAxisProperty[] = [ + EWidgetXAxisProperty.PRIORITY, + EWidgetXAxisProperty.STATE_GROUPS, +]; diff --git a/packages/i18n/src/locales/en/translations-extended.json b/packages/i18n/src/locales/en/translations-extended.json index a9fe73a3bd..29fdd50d8c 100644 --- a/packages/i18n/src/locales/en/translations-extended.json +++ b/packages/i18n/src/locales/en/translations-extended.json @@ -998,7 +998,7 @@ "common": { "add_widget": "Add widget", "widget_title": { - "label": "Widget title", + "label": "Name this widget", "placeholder": "e.g., \"To-do yesterday\", \"All Complete\"" }, "chart_type": "Chart type", diff --git a/packages/propel/src/charts/pie-chart/root.tsx b/packages/propel/src/charts/pie-chart/root.tsx index 32b68df113..3d7eceef71 100644 --- a/packages/propel/src/charts/pie-chart/root.tsx +++ b/packages/propel/src/charts/pie-chart/root.tsx @@ -19,6 +19,7 @@ export const PieChart = React.memo((props: T outerRadius, showTooltip = true, showLabel, + customLabel, centerLabel, } = props; @@ -56,7 +57,30 @@ export const PieChart = React.memo((props: T cy="50%" innerRadius={innerRadius} outerRadius={outerRadius} - label={!!showLabel} + label={ + showLabel + ? (payload) => { + const { cx, cy, fill, innerRadius, midAngle, outerRadius, value } = payload; + const RADIAN = Math.PI / 180; + const radius = 25 + innerRadius + (outerRadius - innerRadius); + const x = cx + radius * Math.cos(-midAngle * RADIAN); + const y = cy + radius * Math.sin(-midAngle * RADIAN); + + return ( + cx ? "start" : "end"} + dominantBaseline="central" + > + {customLabel?.(value) ?? value} + + ); + } + : undefined + } > {renderCells} {centerLabel && ( diff --git a/packages/types/src/charts.d.ts b/packages/types/src/charts.d.ts index 3666462a6c..245cdefe7b 100644 --- a/packages/types/src/charts.d.ts +++ b/packages/types/src/charts.d.ts @@ -105,6 +105,7 @@ export type TPieChartProps = Pick< innerRadius?: number; outerRadius?: number; showLabel: boolean; + customLabel?: (value: any) => string; centerLabel?: { className?: string; fill: string; diff --git a/web/ee/components/dashboards/details/widgets-grid-root.tsx b/web/ee/components/dashboards/details/widgets-grid-root.tsx index e8692439bd..7f72ba5b93 100644 --- a/web/ee/components/dashboards/details/widgets-grid-root.tsx +++ b/web/ee/components/dashboards/details/widgets-grid-root.tsx @@ -28,7 +28,8 @@ export const DashboardsWidgetsGridRoot: React.FC = observer((props) => { const { getDashboardById } = useDashboards(); // derived values const dashboardDetails = getDashboardById(dashboardId); - const { allWidgetIds, layoutItems, updateWidgetsLayout } = dashboardDetails?.widgetsStore ?? {}; + const { canCurrentUserEditDashboard, isViewModeEnabled, widgetsStore } = dashboardDetails ?? {}; + const { allWidgetIds, layoutItems, updateWidgetsLayout } = widgetsStore ?? {}; const handleLayoutChange = useCallback( async (_: Layout[], allLayouts: Layouts) => { @@ -71,8 +72,8 @@ export const DashboardsWidgetsGridRoot: React.FC = observer((props) => { margin={[32, 32]} containerPadding={[0, 0]} draggableHandle=".widget-drag-handle" - isDraggable - isResizable + isDraggable={!isViewModeEnabled && canCurrentUserEditDashboard && activeBreakpoint === EWidgetGridBreakpoints.MD} + isResizable={!isViewModeEnabled && canCurrentUserEditDashboard && activeBreakpoint === EWidgetGridBreakpoints.MD} onBreakpointChange={handleBreakpointChange} onLayoutChange={handleLayoutChange} > diff --git a/web/ee/components/dashboards/widgets/chart-types/area-chart.tsx b/web/ee/components/dashboards/widgets/chart-types/area-chart.tsx index ed1c7d11b5..6013ad6bf9 100644 --- a/web/ee/components/dashboards/widgets/chart-types/area-chart.tsx +++ b/web/ee/components/dashboards/widgets/chart-types/area-chart.tsx @@ -6,7 +6,7 @@ import { useTheme } from "next-themes"; import { CHART_COLOR_PALETTES, DEFAULT_WIDGET_COLOR, EWidgetChartModels } from "@plane/constants"; import { TAreaChartWidgetConfig, TAreaItem } from "@plane/types"; // local imports -import { parseWidgetData, generateExtendedColors, TWidgetComponentProps } from "."; +import { generateExtendedColors, TWidgetComponentProps } from "."; const AreaChart = dynamic(() => import("@plane/propel/charts/area-chart").then((mod) => ({ @@ -15,13 +15,12 @@ const AreaChart = dynamic(() => ); export const DashboardAreaChartWidget: React.FC = observer((props) => { - const { widget } = props; + const { parsedData, widget } = props; // derived values - const { chart_model, data } = widget ?? {}; + const { chart_model } = widget ?? {}; const widgetConfig = widget?.config as TAreaChartWidgetConfig | undefined; const showLegends = !!widgetConfig?.show_legends; const isComparisonModel = chart_model === EWidgetChartModels.COMPARISON; - const parsedData = parseWidgetData(data); // next-themes const { resolvedTheme } = useTheme(); // Get current palette colors and extend if needed diff --git a/web/ee/components/dashboards/widgets/chart-types/bar-chart.tsx b/web/ee/components/dashboards/widgets/chart-types/bar-chart.tsx index a98f0e5393..421c28c703 100644 --- a/web/ee/components/dashboards/widgets/chart-types/bar-chart.tsx +++ b/web/ee/components/dashboards/widgets/chart-types/bar-chart.tsx @@ -6,7 +6,7 @@ import { useTheme } from "next-themes"; import { CHART_COLOR_PALETTES, DEFAULT_WIDGET_COLOR, EWidgetChartModels } from "@plane/constants"; import { TBarChartWidgetConfig, TBarItem } from "@plane/types"; // local imports -import { generateExtendedColors, parseWidgetData, TWidgetComponentProps } from "."; +import { generateExtendedColors, TWidgetComponentProps } from "."; const BarChart = dynamic(() => import("@plane/propel/charts/bar-chart").then((mod) => ({ @@ -15,12 +15,11 @@ const BarChart = dynamic(() => ); export const DashboardBarChartWidget: React.FC = observer((props) => { - const { widget } = props; + const { parsedData, widget } = props; // derived values - const { chart_model, data } = widget ?? {}; + const { chart_model } = widget ?? {}; const widgetConfig = widget?.config as TBarChartWidgetConfig | undefined; const showLegends = !!widgetConfig?.show_legends; - const parsedData = parseWidgetData(data); // next-themes const { resolvedTheme } = useTheme(); // Get current palette colors and extend if needed diff --git a/web/ee/components/dashboards/widgets/chart-types/donut-chart.tsx b/web/ee/components/dashboards/widgets/chart-types/donut-chart.tsx index f0bb19d432..228931b5ac 100644 --- a/web/ee/components/dashboards/widgets/chart-types/donut-chart.tsx +++ b/web/ee/components/dashboards/widgets/chart-types/donut-chart.tsx @@ -41,7 +41,7 @@ export const parseDonutChartData = ( }; export const DashboardDonutChartWidget: React.FC = observer((props) => { - const { widget } = props; + const { parsedData, widget } = props; // derived values const { chart_model, data, height, width } = widget ?? {}; const widgetConfig = widget?.config as TDonutChartWidgetConfig | undefined; @@ -50,7 +50,10 @@ export const DashboardDonutChartWidget: React.FC = observ const showLegends = !!widgetConfig?.show_legends && !isOfUnitHeight; const legendPosition = (width ?? 1) >= (height ?? 1) ? "right" : "bottom"; const showCenterLabel = !!widgetConfig?.center_value; - const parsedData = useMemo(() => parseDonutChartData(data?.data, chart_model), [chart_model, data?.data]); + const donutParsedData = useMemo(() => { + const secondParse = parseDonutChartData(parsedData.data, chart_model); + return secondParse; + }, [chart_model, parsedData]); const totalCount = data?.data?.reduce((acc, curr) => acc + curr.count, 0); const totalCountDigits = totalCount?.toString().length ?? 1; // next-themes @@ -62,10 +65,10 @@ export const DashboardDonutChartWidget: React.FC = observ const cells: TCellItem[] = useMemo(() => { let parsedCells: TCellItem[]; - const extendedColors = generateExtendedColors(baseColors ?? [], parsedData.length); + const extendedColors = generateExtendedColors(baseColors ?? [], donutParsedData.length); if (chart_model === EWidgetChartModels.BASIC) { - parsedCells = parsedData.map((datum, index) => ({ + parsedCells = donutParsedData.map((datum, index) => ({ key: datum.key, className: "stroke-transparent", fill: extendedColors[index], @@ -87,7 +90,7 @@ export const DashboardDonutChartWidget: React.FC = observ parsedCells = []; } return parsedCells; - }, [baseColors, chart_model, parsedData, resolvedTheme, widgetConfig]); + }, [baseColors, chart_model, donutParsedData, resolvedTheme, widgetConfig]); if (!widget) return null; @@ -100,7 +103,7 @@ export const DashboardDonutChartWidget: React.FC = observ bottom: isOfUnitHeight ? 12 : 20, left: 16, }} - data={parsedData} + data={donutParsedData} dataKey="count" cells={cells} innerRadius={isOfUnitHeight ? 10 : (height ?? 1) * 20} diff --git a/web/ee/components/dashboards/widgets/chart-types/header.tsx b/web/ee/components/dashboards/widgets/chart-types/header.tsx index f76ade28e8..5a9f23ac28 100644 --- a/web/ee/components/dashboards/widgets/chart-types/header.tsx +++ b/web/ee/components/dashboards/widgets/chart-types/header.tsx @@ -84,16 +84,17 @@ export const DashboardWidgetHeader: React.FC = observer((props) => {
{widget.name}
- {!isViewModeEnabled && ( + {!isViewModeEnabled && canCurrentUserEditWidget && ( @@ -103,7 +104,11 @@ export const DashboardWidgetHeader: React.FC = observer((props) => {