[CLAUDE] Infra: Mig 27 — Chunk A MenuItem +IsVisible +DisplayLabel
Some checks failed
Deploy SOLUTION_ERP / build-deploy (push) Has been cancelled

Session 20 turn 7: admin có thể Ẩn/Hiện + Đổi tên hiển thị menu cho fe-user
(eOffice). Admin sidebar luôn giữ Label gốc (user Q2=b "chỉ của eOffice thôi").

Domain MenuItem: +IsVisible bool=true +DisplayLabel string?(200)
EF Configuration: HasDefaultValue(true) + HasMaxLength(200)
Migration 27 AddVisibilityAndDisplayLabelToMenuItems — 3-file rule:
  + AddColumn IsVisible bit NOT NULL DEFAULT 1
  + AddColumn DisplayLabel nvarchar(200) NULL

Verify:
- dotnet build SolutionErp.slnx — 0 warn / 0 err
- dotnet ef database update --connection SolutionErp_Dev — applied OK
- dotnet ef database update SolutionErp_Design — applied OK

Pending: B (BE API) → C (FE admin page) → D (FE user render) → E (Docs)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-11 11:29:50 +07:00
parent f568945069
commit 2ea2d27785
5 changed files with 3962 additions and 1 deletions

View File

@ -3,11 +3,18 @@ namespace SolutionErp.Domain.Identity;
public class MenuItem
{
public string Key { get; set; } = string.Empty; // PK, PascalCase
public string Label { get; set; } = string.Empty; // Tiếng Việt display
public string Label { get; set; } = string.Empty; // Tiếng Việt display (label gốc — admin sidebar luôn dùng)
public string? ParentKey { get; set; } // NULL nếu root
public int Order { get; set; }
public string? Icon { get; set; } // lucide-react icon name
// Session 20 Mig 27 — admin có thể custom hiển thị menu cho fe-user (eOffice):
// IsVisible = false → ẩn khỏi response /menus/me FE-user, fe-admin vẫn thấy
// DisplayLabel = "X" → fe-user render "X" thay Label gốc, fe-admin giữ Label
// Admin null/true mặc định cho menu mới seed.
public bool IsVisible { get; set; } = true;
public string? DisplayLabel { get; set; } // override label fe-user, null = dùng Label gốc
public MenuItem? Parent { get; set; }
public List<MenuItem> Children { get; set; } = new();
public List<Permission> Permissions { get; set; } = new();

View File

@ -15,6 +15,8 @@ public class MenuItemConfiguration : IEntityTypeConfiguration<MenuItem>
b.Property(x => x.Label).HasMaxLength(200).IsRequired();
b.Property(x => x.ParentKey).HasMaxLength(50);
b.Property(x => x.Icon).HasMaxLength(50);
b.Property(x => x.IsVisible).HasDefaultValue(true);
b.Property(x => x.DisplayLabel).HasMaxLength(200);
b.HasOne(x => x.Parent)
.WithMany(x => x.Children)

View File

@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SolutionErp.Infrastructure.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddVisibilityAndDisplayLabelToMenuItems : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "DisplayLabel",
table: "MenuItems",
type: "nvarchar(200)",
maxLength: 200,
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsVisible",
table: "MenuItems",
type: "bit",
nullable: false,
defaultValue: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DisplayLabel",
table: "MenuItems");
migrationBuilder.DropColumn(
name: "IsVisible",
table: "MenuItems");
}
}
}

View File

@ -1799,10 +1799,19 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("DisplayLabel")
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Icon")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<bool>("IsVisible")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(true);
b.Property<string>("Label")
.IsRequired()
.HasMaxLength(200)