feat(organization-chart): update statistics display and improve layout
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 4m44s
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:
@@ -11,7 +11,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
|
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
|
||||||
<!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf -->
|
<!-- 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" />-->
|
<!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />-->
|
||||||
<PackageReference Include="MudBlazor" Version="8.14.0" />
|
<PackageReference Include="MudBlazor" Version="8.14.0" />
|
||||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||||
|
|||||||
@@ -52,29 +52,47 @@
|
|||||||
<div id="org-chart-container" class="org-chart-container"></div>
|
<div id="org-chart-container" class="org-chart-container"></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@* Stats Bar *@
|
@* Stats Bar — فقط آمار خود کاربر (نه نودهای درخت) *@
|
||||||
@if (_statistics != null && !_isLoading)
|
@if (_statistics != null && !_isLoading)
|
||||||
{
|
{
|
||||||
<div class="org-chart-stats">
|
<div class="org-chart-stats">
|
||||||
<div class="stat-item">
|
<div class="org-chart-stats-row">
|
||||||
<span class="stat-label">کل اعضا:</span>
|
<div class="stat-item">
|
||||||
<span class="stat-value">@_statistics.TotalMembers</span>
|
<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>
|
||||||
<div class="stat-item">
|
<div class="org-chart-stats-row leg-scores">
|
||||||
<span class="stat-label">سازمان چپ:</span>
|
<div class="stat-item leg-score-gold">
|
||||||
<span class="stat-value left">@_statistics.LeftLegCount</span>
|
<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>
|
||||||
<div class="stat-item">
|
<div class="org-chart-stats-row leg-scores">
|
||||||
<span class="stat-label">سازمان راست:</span>
|
<div class="stat-item leg-score-silver">
|
||||||
<span class="stat-value right">@_statistics.RightLegCount</span>
|
<span class="stat-label">امتیاز نقرهای:</span>
|
||||||
</div>
|
<span class="stat-value left">چپ @_statistics.SilverLeftLegTotal</span>
|
||||||
<div class="stat-item">
|
<span class="stat-sep">·</span>
|
||||||
<span class="stat-label">عمق:</span>
|
<span class="stat-value right">راست @_statistics.SilverRightLegTotal</span>
|
||||||
<span class="stat-value">@_statistics.TreeDepth</span>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="stat-label">پای ضعیف:</span>
|
|
||||||
<span class="stat-value">@(_statistics.WeakerLeg == "Left" ? "چپ" : "راست")</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,11 +110,7 @@ public partial class OrganizationChart : IAsyncDisposable
|
|||||||
activationWeekNumber = n.ActivationWeekNumber,
|
activationWeekNumber = n.ActivationWeekNumber,
|
||||||
joinedAt = n.JoinedAt,
|
joinedAt = n.JoinedAt,
|
||||||
referralCode = n.ReferralCode,
|
referralCode = n.ReferralCode,
|
||||||
packageName = n.PackageName ?? string.Empty,
|
packageName = n.PackageName ?? string.Empty
|
||||||
goldLeftLegTotal = n.GoldLeftLegTotal,
|
|
||||||
goldRightLegTotal = n.GoldRightLegTotal,
|
|
||||||
silverLeftLegTotal = n.SilverLeftLegTotal,
|
|
||||||
silverRightLegTotal = n.SilverRightLegTotal
|
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
await JSRuntime.InvokeVoidAsync("OrgChart.init", "org-chart-container", flatData, _dotNetHelper);
|
await JSRuntime.InvokeVoidAsync("OrgChart.init", "org-chart-container", flatData, _dotNetHelper);
|
||||||
|
|||||||
@@ -152,4 +152,10 @@ public class NetworkStatisticsDto
|
|||||||
public int TreeDepth { get; set; }
|
public int TreeDepth { get; set; }
|
||||||
public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right"
|
public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right"
|
||||||
public LastMemberDto? LastMember { get; set; }
|
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,
|
TotalMembers = response.TotalMembers,
|
||||||
TreeDepth = response.MaxDepth,
|
TreeDepth = response.MaxDepth,
|
||||||
WeakerLeg = response.WeakerLeg,
|
WeakerLeg = response.WeakerLeg,
|
||||||
|
GoldLeftLegTotal = response.GoldLeftLegTotal,
|
||||||
|
GoldRightLegTotal = response.GoldRightLegTotal,
|
||||||
|
SilverLeftLegTotal = response.SilverLeftLegTotal,
|
||||||
|
SilverRightLegTotal = response.SilverRightLegTotal,
|
||||||
LastMember = response.LastMember != null ? new LastMemberDto
|
LastMember = response.LastMember != null ? new LastMemberDto
|
||||||
{
|
{
|
||||||
UserId = response.LastMember.UserId,
|
UserId = response.LastMember.UserId,
|
||||||
|
|||||||
@@ -72,10 +72,10 @@
|
|||||||
/* Compact Header */
|
/* Compact Header */
|
||||||
.node-header-compact {
|
.node-header-compact {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
min-height: 100%;
|
height: 100%;
|
||||||
background: linear-gradient(135deg, #f8f9fa 0%, #fff 100%);
|
background: linear-gradient(135deg, #f8f9fa 0%, #fff 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,22 +141,7 @@
|
|||||||
max-width: 120px;
|
max-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* D3: طلایی / نقرهای — پای چپ و راست */
|
/* D3: امتیاز طلایی/نقرهای فقط در نوار پایین شجره (.org-chart-stats) */
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Referral Code - only for club active members */
|
/* Referral Code - only for club active members */
|
||||||
.node-referral {
|
.node-referral {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -386,14 +371,27 @@
|
|||||||
/* Stats Bar */
|
/* Stats Bar */
|
||||||
.org-chart-stats {
|
.org-chart-stats {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 24px;
|
gap: 8px;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
border-top: 1px solid #e9ecef;
|
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 {
|
.stat-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -401,6 +399,21 @@
|
|||||||
font-size: 13px;
|
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 {
|
.stat-label {
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
}
|
}
|
||||||
@@ -464,10 +477,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.org-chart-stats {
|
.org-chart-stats {
|
||||||
flex-wrap: wrap;
|
gap: 8px;
|
||||||
gap: 12px;
|
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.org-chart-stats-row {
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.stat-item {
|
.stat-item {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ window.OrgChart = {
|
|||||||
this.chart = new d3.OrgChart()
|
this.chart = new d3.OrgChart()
|
||||||
.container('#' + containerId)
|
.container('#' + containerId)
|
||||||
.data(data)
|
.data(data)
|
||||||
.nodeWidth((d) => 150)
|
.nodeWidth((d) => 140)
|
||||||
.nodeHeight((d) => 112)
|
.nodeHeight((d) => 85)
|
||||||
.childrenMargin((d) => 50)
|
.childrenMargin((d) => 50)
|
||||||
.compactMarginBetween((d) => 15)
|
.compactMarginBetween((d) => 15)
|
||||||
.compactMarginPair((d) => 15)
|
.compactMarginPair((d) => 15)
|
||||||
@@ -80,16 +80,6 @@ window.OrgChart = {
|
|||||||
</div>`
|
</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 `
|
return `
|
||||||
<div class="org-node-card ${positionClass} ${activeClass} ${clubActiveClass}" data-user-id="${data.id}">
|
<div class="org-node-card ${positionClass} ${activeClass} ${clubActiveClass}" data-user-id="${data.id}">
|
||||||
<div class="node-header-compact ${isRoot ? 'root' : ''}">
|
<div class="node-header-compact ${isRoot ? 'root' : ''}">
|
||||||
@@ -98,7 +88,6 @@ window.OrgChart = {
|
|||||||
<div class="node-name-sm">${data.fullName || 'بدون نام'}</div>
|
<div class="node-name-sm">${data.fullName || 'بدون نام'}</div>
|
||||||
<div class="node-level-sm">L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}</div>
|
<div class="node-level-sm">L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}</div>
|
||||||
${packageBadge}
|
${packageBadge}
|
||||||
${legScoresHtml}
|
|
||||||
${referralCodeHtml}
|
${referralCodeHtml}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user