From 2d1ccd1127d68a95ce8ddac176bdeaa6ec8f03f3 Mon Sep 17 00:00:00 2001 From: Aleix Soler Date: Wed, 16 Jul 2025 18:36:01 +0200 Subject: [PATCH] chore: unified status display system --- .../ChangeStatusModal/CurrentStatusChips.tsx | 6 +- .../GroupedStatusView/GroupedStatusView.tsx | 2 +- .../components/StatusGroup.tsx | 5 +- components/SettingsUI.tsx/TemplateItem.tsx | 4 +- .../SettingsUI.tsx/TemplateStatusChip.tsx | 18 --- components/StatusBar/StatusBarGroup.tsx | 5 +- .../StatusDashboard/CurrentNoteSection.tsx | 5 +- .../StatusDistributionChart.tsx | 7 +- .../StatusFileInfoPopup.tsx | 7 +- components/atoms/StatusBadge.tsx | 25 ---- components/atoms/StatusChip.tsx | 74 ---------- components/atoms/StatusDisplay.tsx | 132 ++++++++++++++++++ 12 files changed, 158 insertions(+), 132 deletions(-) delete mode 100644 components/SettingsUI.tsx/TemplateStatusChip.tsx delete mode 100644 components/atoms/StatusBadge.tsx delete mode 100644 components/atoms/StatusChip.tsx create mode 100644 components/atoms/StatusDisplay.tsx diff --git a/components/ChangeStatusModal/CurrentStatusChips.tsx b/components/ChangeStatusModal/CurrentStatusChips.tsx index 99c4e14..6155e0b 100644 --- a/components/ChangeStatusModal/CurrentStatusChips.tsx +++ b/components/ChangeStatusModal/CurrentStatusChips.tsx @@ -1,6 +1,6 @@ import React from "react"; import { NoteStatus } from "@/types/noteStatus"; -import { StatusChip } from "../atoms/StatusChip"; +import { StatusDisplay } from "../atoms/StatusDisplay"; import { SettingItem } from "../SettingsUI.tsx/SettingItem"; interface Props { @@ -25,9 +25,11 @@ export const CurrentStatusChips: React.FC = ({ }} > {currentStatuses.map((status) => ( - onRemoveStatus(status)} /> ))} diff --git a/components/GroupedStatusView/GroupedStatusView.tsx b/components/GroupedStatusView/GroupedStatusView.tsx index 071f604..fc1f797 100644 --- a/components/GroupedStatusView/GroupedStatusView.tsx +++ b/components/GroupedStatusView/GroupedStatusView.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useMemo } from "react"; +import { useState, useCallback, useMemo } from "react"; import { FilterSection } from "./components/FilterSection"; import { TagSection } from "./components/TagSection"; import { LoadingSpinner } from "./components/LoadingSpinner"; diff --git a/components/GroupedStatusView/components/StatusGroup.tsx b/components/GroupedStatusView/components/StatusGroup.tsx index b5ac851..b398053 100644 --- a/components/GroupedStatusView/components/StatusGroup.tsx +++ b/components/GroupedStatusView/components/StatusGroup.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import { StatusBadge } from "@/components/atoms/StatusBadge"; +import { StatusDisplay } from "@/components/atoms/StatusDisplay"; import { CollapsibleCounter } from "@/components/atoms/CollapsibleCounter"; import { FileItem, StatusItem } from "../GroupedStatusView"; import { FileList } from "./FileList"; @@ -43,10 +43,11 @@ export const StatusGroup = ({ return (
-
= ({
{template.description}:
{template.statuses.map((status, index) => ( - + ))}
diff --git a/components/SettingsUI.tsx/TemplateStatusChip.tsx b/components/SettingsUI.tsx/TemplateStatusChip.tsx deleted file mode 100644 index f83d18b..0000000 --- a/components/SettingsUI.tsx/TemplateStatusChip.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NoteStatus } from "@/types/noteStatus"; -import React from "react"; - -interface StatusChipProps { - status: NoteStatus; -} - -export const TemplateStatusChip: React.FC = ({ status }) => ( -
- - - {status.icon} {status.name} - -
-); diff --git a/components/StatusBar/StatusBarGroup.tsx b/components/StatusBar/StatusBarGroup.tsx index 0fc109d..c2e94e0 100644 --- a/components/StatusBar/StatusBarGroup.tsx +++ b/components/StatusBar/StatusBarGroup.tsx @@ -3,7 +3,7 @@ import { NoteStatus } from "@/types/noteStatus"; import { StatusTemplate } from "@/types/pluginSettings"; import { GroupLabel } from "../atoms/GroupLabel"; import { CollapsibleCounter } from "../atoms/CollapsibleCounter"; -import { StatusBadge } from "../atoms/StatusBadge"; +import { StatusDisplay } from "../atoms/StatusDisplay"; import { useStatusBarContext } from "./StatusBarContext"; export interface StatusBarGroupProps { @@ -39,8 +39,9 @@ export const StatusBarGroup: FC = ({ }} title={status.description} > - { onStatusClick(status); }} diff --git a/components/StatusDashboard/CurrentNoteSection.tsx b/components/StatusDashboard/CurrentNoteSection.tsx index 9e7bf27..fe2a5c5 100644 --- a/components/StatusDashboard/CurrentNoteSection.tsx +++ b/components/StatusDashboard/CurrentNoteSection.tsx @@ -1,6 +1,6 @@ import { TFile } from "obsidian"; import { NoteStatus } from "@/types/noteStatus"; -import { StatusBadge } from "@/components/atoms/StatusBadge"; +import { StatusDisplay } from "@/components/atoms/StatusDisplay"; import { GroupLabel } from "@/components/atoms/GroupLabel"; interface CurrentNoteInfo { @@ -50,9 +50,10 @@ export const CurrentNoteSection = ({
{statuses.length > 0 ? ( statuses.map((status) => ( - )) ) : ( diff --git a/components/StatusDashboard/StatusDistributionChart.tsx b/components/StatusDashboard/StatusDistributionChart.tsx index cacb71d..694538d 100644 --- a/components/StatusDashboard/StatusDistributionChart.tsx +++ b/components/StatusDashboard/StatusDistributionChart.tsx @@ -1,6 +1,6 @@ import { useMemo } from "react"; import { BaseNoteStatusService } from "@/core/noteStatusService"; -import { StatusBadge } from "@/components/atoms/StatusBadge"; +import { StatusDisplay } from "@/components/atoms/StatusDisplay"; import { VaultStats } from "./useVaultStats"; interface StatusDistributionChartProps { @@ -50,7 +50,10 @@ export const StatusDistributionChart = ({
{status && ( - + )} {count} notes ({percentage}%) diff --git a/components/StatusFileInfoPopup/StatusFileInfoPopup.tsx b/components/StatusFileInfoPopup/StatusFileInfoPopup.tsx index 4d80e08..6cd42c7 100644 --- a/components/StatusFileInfoPopup/StatusFileInfoPopup.tsx +++ b/components/StatusFileInfoPopup/StatusFileInfoPopup.tsx @@ -1,6 +1,6 @@ import React from "react"; import { GroupedStatuses } from "@/types/noteStatus"; -import { StatusBadge } from "../atoms/StatusBadge"; +import { StatusDisplay } from "../atoms/StatusDisplay"; export interface Props { statuses: GroupedStatuses; @@ -44,7 +44,10 @@ export const StatusFileInfoPopup: React.FC = ({ statuses }) => { key={`${groupName}-${index}`} className="status-item" > - + {status.description && (
void; -} - -export const StatusBadge: FC = ({ status, onClick }) => { - return ( -
-
- {status.icon} - {status.name} -
-
- ); -}; diff --git a/components/atoms/StatusChip.tsx b/components/atoms/StatusChip.tsx deleted file mode 100644 index 7d76cd6..0000000 --- a/components/atoms/StatusChip.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { NoteStatus } from "@/types/noteStatus"; -import { FC, memo, useState } from "react"; - -interface Props { - status: NoteStatus; - onRemove: () => void; -} - -export const StatusChip: FC = memo(({ status, onRemove }) => { - const [isRemoving, setIsRemoving] = useState(false); - - const handleRemove = (e: React.MouseEvent) => { - e.stopPropagation(); - setIsRemoving(true); - setTimeout(() => { - onRemove(); - }, 150); - }; - - return ( -
- {status.icon} - {status.name} -
- - - - -
-
- ); -}); diff --git a/components/atoms/StatusDisplay.tsx b/components/atoms/StatusDisplay.tsx new file mode 100644 index 0000000..9fd987f --- /dev/null +++ b/components/atoms/StatusDisplay.tsx @@ -0,0 +1,132 @@ +import { NoteStatus } from "@/types/noteStatus"; +import { FC, memo, useState } from "react"; + +export type StatusDisplayVariant = "chip" | "badge" | "template"; + +interface StatusDisplayProps { + status: NoteStatus; + variant: StatusDisplayVariant; + removable?: boolean; + onRemove?: () => void; + onClick?: () => void; +} + +export const StatusDisplay: FC = memo( + ({ status, variant, removable = false, onRemove, onClick }) => { + const [isRemoving, setIsRemoving] = useState(false); + + const handleRemove = (e: React.MouseEvent) => { + e.stopPropagation(); + if (onRemove) { + setIsRemoving(true); + setTimeout(() => { + onRemove(); + }, 150); + } + }; + + const handleClick = () => { + if (onClick) { + onClick(); + } + }; + + if (variant === "chip") { + return ( +
+ {status.icon} + {status.name} + {removable && ( +
+ + + + +
+ )} +
+ ); + } + + if (variant === "badge") { + return ( +
+
+ {status.icon} + {status.name} +
+
+ ); + } + + if (variant === "template") { + return ( +
+ + + {status.icon} {status.name} + +
+ ); + } + + return null; + }, +);