feat(organization-chart): update statistics display and improve layout
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 4m44s

- Updated the organization chart to include additional statistics such as left and right leg counts, tree depth, and weaker leg identification for enhanced user insights.
- Improved the layout and styling of the statistics bar for better visibility and user experience.
- Adjusted the CSS for the organization chart to refine the overall presentation and responsiveness.

These changes enhance the clarity and usability of the organization chart, providing users with essential metrics at a glance.
This commit is contained in:
masoodafar-web
2026-08-27 21:30:06 +03:30
parent 307302e33d
commit 101687f9db
7 changed files with 87 additions and 58 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
<ItemGroup>
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
<!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf -->
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.210" />
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.211" />
<!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />-->
<PackageReference Include="MudBlazor" Version="8.14.0" />
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
@@ -52,29 +52,47 @@
<div id="org-chart-container" class="org-chart-container"></div>
}
@* Stats Bar *@
@* Stats Bar — فقط آمار خود کاربر (نه نودهای درخت) *@
@if (_statistics != null && !_isLoading)
{
<div class="org-chart-stats">
<div class="stat-item">
<span class="stat-label">کل اعضا:</span>
<span class="stat-value">@_statistics.TotalMembers</span>
<div class="org-chart-stats-row">
<div class="stat-item">
<span class="stat-label">کل اعضا:</span>
<span class="stat-value">@_statistics.TotalMembers</span>
</div>
<div class="stat-item">
<span class="stat-label">سازمان چپ:</span>
<span class="stat-value left">@_statistics.LeftLegCount</span>
</div>
<div class="stat-item">
<span class="stat-label">سازمان راست:</span>
<span class="stat-value right">@_statistics.RightLegCount</span>
</div>
<div class="stat-item">
<span class="stat-label">عمق:</span>
<span class="stat-value">@_statistics.TreeDepth</span>
</div>
<div class="stat-item">
<span class="stat-label">پای ضعیف:</span>
<span class="stat-value">@(_statistics.WeakerLeg == "Left" ? "چپ" : "راست")</span>
</div>
</div>
<div class="stat-item">
<span class="stat-label">سازمان چپ:</span>
<span class="stat-value left">@_statistics.LeftLegCount</span>
<div class="org-chart-stats-row leg-scores">
<div class="stat-item leg-score-gold">
<span class="stat-label">امتیاز طلایی:</span>
<span class="stat-value left">چپ @_statistics.GoldLeftLegTotal</span>
<span class="stat-sep">·</span>
<span class="stat-value right">راست @_statistics.GoldRightLegTotal</span>
</div>
</div>
<div class="stat-item">
<span class="stat-label">سازمان راست:</span>
<span class="stat-value right">@_statistics.RightLegCount</span>
</div>
<div class="stat-item">
<span class="stat-label">عمق:</span>
<span class="stat-value">@_statistics.TreeDepth</span>
</div>
<div class="stat-item">
<span class="stat-label">پای ضعیف:</span>
<span class="stat-value">@(_statistics.WeakerLeg == "Left" ? "چپ" : "راست")</span>
<div class="org-chart-stats-row leg-scores">
<div class="stat-item leg-score-silver">
<span class="stat-label">امتیاز نقره‌ای:</span>
<span class="stat-value left">چپ @_statistics.SilverLeftLegTotal</span>
<span class="stat-sep">·</span>
<span class="stat-value right">راست @_statistics.SilverRightLegTotal</span>
</div>
</div>
</div>
}
@@ -110,11 +110,7 @@ public partial class OrganizationChart : IAsyncDisposable
activationWeekNumber = n.ActivationWeekNumber,
joinedAt = n.JoinedAt,
referralCode = n.ReferralCode,
packageName = n.PackageName ?? string.Empty,
goldLeftLegTotal = n.GoldLeftLegTotal,
goldRightLegTotal = n.GoldRightLegTotal,
silverLeftLegTotal = n.SilverLeftLegTotal,
silverRightLegTotal = n.SilverRightLegTotal
packageName = n.PackageName ?? string.Empty
}).ToArray();
await JSRuntime.InvokeVoidAsync("OrgChart.init", "org-chart-container", flatData, _dotNetHelper);
@@ -152,4 +152,10 @@ public class NetworkStatisticsDto
public int TreeDepth { get; set; }
public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right"
public LastMemberDto? LastMember { get; set; }
/// <summary>آخرین امتیاز پای چپ/راست — فقط خود کاربر (نوار پایین شجره)</summary>
public int GoldLeftLegTotal { get; set; }
public int GoldRightLegTotal { get; set; }
public int SilverLeftLegTotal { get; set; }
public int SilverRightLegTotal { get; set; }
}
@@ -96,6 +96,10 @@ public class NetworkMembershipService
TotalMembers = response.TotalMembers,
TreeDepth = response.MaxDepth,
WeakerLeg = response.WeakerLeg,
GoldLeftLegTotal = response.GoldLeftLegTotal,
GoldRightLegTotal = response.GoldRightLegTotal,
SilverLeftLegTotal = response.SilverLeftLegTotal,
SilverRightLegTotal = response.SilverRightLegTotal,
LastMember = response.LastMember != null ? new LastMemberDto
{
UserId = response.LastMember.UserId,
+37 -21
View File
@@ -72,10 +72,10 @@
/* Compact Header */
.node-header-compact {
display: flex;
align-items: flex-start;
align-items: center;
gap: 6px;
padding: 6px 8px;
min-height: 100%;
height: 100%;
background: linear-gradient(135deg, #f8f9fa 0%, #fff 100%);
}
@@ -141,22 +141,7 @@
max-width: 120px;
}
/* D3: طلایی / نقره‌ای — پای چپ و راست */
.node-leg-scores {
margin-top: 3px;
line-height: 1.25;
font-size: 8px;
font-weight: 600;
}
.node-leg-scores .leg-score-line.gold {
color: #b8860b;
}
.node-leg-scores .leg-score-line.silver {
color: #607d8b;
}
/* D3: امتیاز طلایی/نقره‌ای فقط در نوار پایین شجره (.org-chart-stats) */
/* Referral Code - only for club active members */
.node-referral {
display: flex;
@@ -386,14 +371,27 @@
/* Stats Bar */
.org-chart-stats {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
gap: 8px;
padding: 12px 16px;
background: #f8f9fa;
border-top: 1px solid #e9ecef;
}
.org-chart-stats-row {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 24px;
}
.org-chart-stats-row.leg-scores {
gap: 12px;
}
.stat-item {
display: flex;
align-items: center;
@@ -401,6 +399,21 @@
font-size: 13px;
}
.stat-item.leg-score-gold .stat-label {
color: #b8860b;
font-weight: 600;
}
.stat-item.leg-score-silver .stat-label {
color: #607d8b;
font-weight: 600;
}
.stat-sep {
color: #adb5bd;
margin: 0 2px;
}
.stat-label {
color: #6c757d;
}
@@ -464,11 +477,14 @@
}
.org-chart-stats {
flex-wrap: wrap;
gap: 12px;
gap: 8px;
padding: 10px;
}
.org-chart-stats-row {
gap: 12px;
}
.stat-item {
font-size: 12px;
}
+2 -13
View File
@@ -37,8 +37,8 @@ window.OrgChart = {
this.chart = new d3.OrgChart()
.container('#' + containerId)
.data(data)
.nodeWidth((d) => 150)
.nodeHeight((d) => 112)
.nodeWidth((d) => 140)
.nodeHeight((d) => 85)
.childrenMargin((d) => 50)
.compactMarginBetween((d) => 15)
.compactMarginPair((d) => 15)
@@ -80,16 +80,6 @@ window.OrgChart = {
</div>`
: '';
const gL = data.goldLeftLegTotal ?? 0;
const gR = data.goldRightLegTotal ?? 0;
const sL = data.silverLeftLegTotal ?? 0;
const sR = data.silverRightLegTotal ?? 0;
const legScoresHtml = `
<div class="node-leg-scores" title="آخرین امتیاز هفتگی پای چپ / راست">
<div class="leg-score-line gold">طلایی: چپ ${gL} · راست ${gR}</div>
<div class="leg-score-line silver">نقره‌ای: چپ ${sL} · راست ${sR}</div>
</div>`;
return `
<div class="org-node-card ${positionClass} ${activeClass} ${clubActiveClass}" data-user-id="${data.id}">
<div class="node-header-compact ${isRoot ? 'root' : ''}">
@@ -98,7 +88,6 @@ window.OrgChart = {
<div class="node-name-sm">${data.fullName || 'بدون نام'}</div>
<div class="node-level-sm">L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}</div>
${packageBadge}
${legScoresHtml}
${referralCodeHtml}
</div>
</div>