UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: восстановление компактной сводки аналитики

This commit is contained in:
DCCONSTRUCTIONS 2026-04-24 14:03:22 +03:00
parent 52bd017d82
commit ad1d9c34ea
2 changed files with 123 additions and 6 deletions

View File

@ -22,6 +22,29 @@ import InsightCard from "./insight-card";
const analyticsService = new AnalyticsService();
const WORK_ITEM_SUMMARY_FIELDS: IInsightField[] = [
{
key: "total_work_items",
i18nKey: "workspace_analytics.total",
},
{
key: "started_work_items",
i18nKey: "workspace_analytics.started_work_items",
},
{
key: "backlog_work_items",
i18nKey: "workspace_analytics.backlog_work_items",
},
{
key: "un_started_work_items",
i18nKey: "workspace_analytics.un_started_work_items",
},
{
key: "completed_work_items",
i18nKey: "workspace_analytics.completed_work_items",
},
];
const getInsightLabel = (
analyticsType: TAnalyticsTabsBase,
item: IInsightField,
@ -61,6 +84,13 @@ const TotalInsights = observer(function TotalInsights({
const workspaceSlug = params.workspaceSlug.toString();
const { t } = useTranslation();
const { selectedDuration, selectedProjects, selectedCycle, selectedModule, isPeekView, isEpic } = useAnalytics();
const insightFields =
analyticsType === "work-items"
? ANALYTICS_INSIGHTS_FIELDS[analyticsType]?.length
? ANALYTICS_INSIGHTS_FIELDS[analyticsType]
: WORK_ITEM_SUMMARY_FIELDS
: (ANALYTICS_INSIGHTS_FIELDS[analyticsType] ?? []);
const shouldUseSummaryCard = analyticsType === "work-items";
const { data: totalInsightsData, isLoading } = useSWR(
`total-insights-${analyticsType}-${selectedDuration}-${selectedProjects}-${selectedCycle}-${selectedModule}-${isEpic}`,
() =>
@ -77,18 +107,38 @@ const TotalInsights = observer(function TotalInsights({
isPeekView
)
);
if (shouldUseSummaryCard) {
return (
<section
className={cn("nodedc-analytics-summary-card", peekView && "nodedc-analytics-summary-card-peek")}
aria-label="Сводка аналитики"
>
{insightFields.map((item) => (
<div
key={`${analyticsType}-${item.key}`}
className="nodedc-analytics-summary-item flex min-h-[5.75rem] min-w-0 flex-col justify-between gap-3 px-4 py-3.5"
>
<div className="nodedc-analytics-summary-label text-[0.72rem] font-medium text-secondary">
{getInsightLabel(analyticsType, item, isEpic, t)}
</div>
<div className="nodedc-analytics-summary-value text-[1.55rem] font-semibold text-primary">
{totalInsightsData?.[item.key]?.count ?? 0}
</div>
</div>
))}
</section>
);
}
return (
<div
className={cn(
"grid grid-cols-1 gap-8 sm:grid-cols-2 md:gap-10",
!peekView
? ANALYTICS_INSIGHTS_FIELDS[analyticsType]?.length % 5 === 0
? "gap-10 lg:grid-cols-5"
: "gap-8 lg:grid-cols-4"
: "grid-cols-2"
!peekView ? (insightFields.length % 5 === 0 ? "gap-10 lg:grid-cols-5" : "gap-8 lg:grid-cols-4") : "grid-cols-2"
)}
>
{ANALYTICS_INSIGHTS_FIELDS[analyticsType]?.map((item) => (
{insightFields.map((item) => (
<InsightCard
key={`${analyticsType}-${item.key}`}
isLoading={isLoading}

View File

@ -2768,6 +2768,73 @@
color: var(--text-color-primary) !important;
}
.nodedc-analytics-summary-card {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: repeat(5, minmax(8.75rem, 1fr));
width: 100%;
min-height: 5.75rem;
overflow-x: auto;
border: 0 !important;
border-radius: 1.45rem !important;
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%), rgba(255, 255, 255, 0.024) !important;
box-shadow:
0 16px 38px rgba(0, 0, 0, 0.16),
inset 0 1px 0 rgba(255, 255, 255, 0.018) !important;
-webkit-backdrop-filter: blur(18px);
backdrop-filter: blur(18px);
scrollbar-color: rgba(var(--nodedc-card-active-rgb), 0.62) rgba(255, 255, 255, 0.035);
scrollbar-width: thin;
}
.nodedc-analytics-summary-card::-webkit-scrollbar {
height: 0.45rem;
}
.nodedc-analytics-summary-card::-webkit-scrollbar-track {
border-radius: 999px;
background: rgba(255, 255, 255, 0.035);
}
.nodedc-analytics-summary-card::-webkit-scrollbar-thumb {
border-radius: 999px;
background: rgba(var(--nodedc-card-active-rgb), 0.62);
}
.nodedc-analytics-summary-item {
position: relative;
min-width: 0;
}
.nodedc-analytics-summary-item + .nodedc-analytics-summary-item::before {
position: absolute;
top: 1rem;
bottom: 1rem;
left: 0;
width: 1px;
background: rgba(255, 255, 255, 0.06);
content: "";
}
.nodedc-analytics-summary-label {
display: -webkit-box;
overflow: hidden;
line-height: 1.28;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.nodedc-analytics-summary-value {
position: relative;
z-index: 1;
display: block;
min-height: 1.65rem;
color: var(--text-color-primary) !important;
line-height: 1;
}
.nodedc-attachment-upload {
min-height: 4.5rem;
border: 0 !important;