fix: CRM 다이얼로그의 ClientId 바인딩을 Nullable int? 로 변경하고 CompanyName null 대비 Fallback 이름을 Name으로 매핑하여 MudSelect 초기 렌더링 Circuit 크래시 원천 차단
TaxBaik CI/CD / build-and-deploy (push) Failing after 37s

This commit is contained in:
2026-06-29 17:14:07 +09:00
parent d9766cb5ef
commit 682e2db3a3
4 changed files with 23 additions and 21 deletions
@@ -107,10 +107,10 @@
</TitleContent> </TitleContent>
<DialogContent> <DialogContent>
<MudForm @ref="form"> <MudForm @ref="form">
<MudSelect T="int" @bind-Value="contractForm.ClientId" Label="고객" Required="true" Variant="Variant.Outlined" FullWidth="true" Class="mb-4"> <MudSelect T="int?" @bind-Value="contractForm.ClientId" Label="고객" Required="true" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" RequiredError="고객을 선택하세요.">
@foreach (var client in clients) @foreach (var client in clients)
{ {
<MudSelectItem Value="@client.Id">@client.CompanyName</MudSelectItem> <MudSelectItem Value="@((int?)client.Id)">@(string.IsNullOrEmpty(client.CompanyName) ? client.Name : client.CompanyName)</MudSelectItem>
} }
</MudSelect> </MudSelect>
<MudTextField T="string" @bind-Value="contractForm.ContractNumber" Label="계약번호" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" Required="true" /> <MudTextField T="string" @bind-Value="contractForm.ContractNumber" Label="계약번호" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" Required="true" />
@@ -180,7 +180,7 @@
{ {
contractForm = new ContractForm contractForm = new ContractForm
{ {
ClientId = clients.FirstOrDefault()?.Id ?? 0, ClientId = clients.FirstOrDefault()?.Id,
StartDate = DateTime.Today StartDate = DateTime.Today
}; };
isDialogOpen = true; isDialogOpen = true;
@@ -200,8 +200,9 @@
try try
{ {
if (contractForm.ClientId == null) return;
var newId = await ContractClient.CreateAsync( var newId = await ContractClient.CreateAsync(
contractForm.ClientId, contractForm.ClientId.Value,
contractForm.ContractNumber, contractForm.ContractNumber,
contractForm.ServiceType, contractForm.ServiceType,
contractForm.StartDate ?? DateTime.Now, contractForm.StartDate ?? DateTime.Now,
@@ -254,7 +255,7 @@
private class ContractForm private class ContractForm
{ {
public int ClientId { get; set; } public int? ClientId { get; set; }
public string ContractNumber { get; set; } = ""; public string ContractNumber { get; set; } = "";
public string ServiceType { get; set; } = ""; public string ServiceType { get; set; } = "";
public DateTime? StartDate { get; set; } public DateTime? StartDate { get; set; }
@@ -117,16 +117,17 @@
</TitleContent> </TitleContent>
<DialogContent> <DialogContent>
<MudForm @ref="form"> <MudForm @ref="form">
<MudSelect T="int" <MudSelect T="int?"
@bind-Value="scheduleForm.ClientId" @bind-Value="scheduleForm.ClientId"
Label="고객" Label="고객"
Required="true" Required="true"
Variant="Variant.Outlined" Variant="Variant.Outlined"
FullWidth="true" FullWidth="true"
Class="mb-4"> Class="mb-4"
RequiredError="고객을 선택하세요.">
@foreach (var client in clients) @foreach (var client in clients)
{ {
<MudSelectItem Value="@client.Id">@client.CompanyName</MudSelectItem> <MudSelectItem Value="@((int?)client.Id)">@(string.IsNullOrEmpty(client.CompanyName) ? client.Name : client.CompanyName)</MudSelectItem>
} }
</MudSelect> </MudSelect>
<MudSelect T="string" @bind-Value="scheduleForm.FilingType" Label="신고 유형" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" Required="true"> <MudSelect T="string" @bind-Value="scheduleForm.FilingType" Label="신고 유형" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" Required="true">
@@ -197,7 +198,7 @@
{ {
FilingYear = DateTime.Now.Year, FilingYear = DateTime.Now.Year,
DueDate = DateTime.Today, DueDate = DateTime.Today,
ClientId = clients.FirstOrDefault()?.Id ?? 0 ClientId = clients.FirstOrDefault()?.Id
}; };
isDialogOpen = true; isDialogOpen = true;
} }
@@ -216,8 +217,9 @@
try try
{ {
if (scheduleForm.ClientId == null) return;
var newId = await TaxFilingClient.CreateAsync( var newId = await TaxFilingClient.CreateAsync(
scheduleForm.ClientId, scheduleForm.ClientId.Value,
scheduleForm.FilingType, scheduleForm.FilingType,
scheduleForm.DueDate ?? DateTime.Today, scheduleForm.DueDate ?? DateTime.Today,
scheduleForm.FilingYear); scheduleForm.FilingYear);
@@ -84,10 +84,10 @@ else
</TitleContent> </TitleContent>
<DialogContent> <DialogContent>
<MudForm @ref="form"> <MudForm @ref="form">
<MudSelect T="int" @bind-Value="profileForm.ClientId" Label="고객" Required="true" Variant="Variant.Outlined" FullWidth="true" Class="mb-4"> <MudSelect T="int?" @bind-Value="profileForm.ClientId" Label="고객" Required="true" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" RequiredError="고객을 선택하세요.">
@foreach (var client in clients) @foreach (var client in clients)
{ {
<MudSelectItem Value="@client.Id">@client.CompanyName</MudSelectItem> <MudSelectItem Value="@((int?)client.Id)">@(string.IsNullOrEmpty(client.CompanyName) ? client.Name : client.CompanyName)</MudSelectItem>
} }
</MudSelect> </MudSelect>
<MudSelect T="string" @bind-Value="profileForm.BusinessType" Label="사업 유형" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" Required="true"> <MudSelect T="string" @bind-Value="profileForm.BusinessType" Label="사업 유형" Variant="Variant.Outlined" FullWidth="true" Class="mb-4" Required="true">
@@ -166,7 +166,7 @@ else
editingProfile = null; editingProfile = null;
profileForm = new TaxProfileForm profileForm = new TaxProfileForm
{ {
ClientId = clients.FirstOrDefault()?.Id ?? 0, ClientId = clients.FirstOrDefault()?.Id,
TaxRiskLevel = "normal", TaxRiskLevel = "normal",
NextFilingDueDate = DateTime.Today.AddMonths(1) NextFilingDueDate = DateTime.Today.AddMonths(1)
}; };
@@ -202,15 +202,11 @@ else
try try
{ {
if (isEditMode) if (isEditMode && editingProfile != null)
{ {
await TaxProfileClient.UpdateAsync( await TaxProfileClient.UpdateAsync(editingProfile.Id, profileForm.BusinessType,
editingProfile!.Id, null, profileForm.NextFilingDueDate, profileForm.TaxRiskLevel);
profileForm.BusinessType, Snackbar.Add("세무 프로필이 수정되었습니다.", Severity.Success);
null,
profileForm.NextFilingDueDate,
profileForm.TaxRiskLevel);
Snackbar.Add("세무 프로필이 업데이트되었습니다.", Severity.Success);
} }
else else
{ {
+3
View File
@@ -62,6 +62,9 @@ export async function navigateInBlazor(page: Page, targetUrl: string) {
// Wait until Blazor Server completes connection and hides the loading spinner overlay // Wait until Blazor Server completes connection and hides the loading spinner overlay
await page.locator('#blazor-loading').waitFor({ state: 'hidden', timeout: 15000 }).catch(() => {}); await page.locator('#blazor-loading').waitFor({ state: 'hidden', timeout: 15000 }).catch(() => {});
// Give the SPA router a brief window to unmount the previous page and mount the loading spinner
await page.waitForTimeout(500);
// Also wait for MudBlazor's dynamic loading spinners to disappear (ensuring the grid is interactive) // Also wait for MudBlazor's dynamic loading spinners to disappear (ensuring the grid is interactive)
const spinner = page.locator('.mud-progress-circular, .mud-progress-linear-bar'); const spinner = page.locator('.mud-progress-circular, .mud-progress-linear-bar');
try { try {