Skip to content

Commit 89eea29

Browse files
antosubashclaude
authored andcommitted
Extract shared helpers and import types from generated types.ts
- Use CrudEndpoints.Delete in RemoveHostEndpoint instead of manual implementation - Extract TenantFeatureHelper for shared override fetching logic (dedup 2 endpoints + 1 view) - Import Tenant/TenantHost types from generated types.ts instead of redeclaring inline - Extract statusLabels/statusColors to shared tenantStatus.ts
1 parent 2f6393f commit 89eea29

10 files changed

Lines changed: 51 additions & 90 deletions

File tree

‎modules/Tenants/src/SimpleModule.Tenants/Endpoints/TenantFeatures/DeleteTenantFeatureEndpoint.cs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ public void Map(IEndpointRouteBuilder app) =>
2222
return Results.NotFound();
2323
}
2424

25-
var tenantIdStr = id.Value.ToString(
26-
System.Globalization.CultureInfo.InvariantCulture
27-
);
25+
var tenantIdStr = id.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);
2826
var overrides = await featureFlags.GetOverridesAsync(flagName);
2927
var tenantOverride = overrides.FirstOrDefault(o =>
3028
o.OverrideType == OverrideType.Tenant

‎modules/Tenants/src/SimpleModule.Tenants/Endpoints/TenantFeatures/GetTenantFeaturesEndpoint.cs‎

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,8 @@ public void Map(IEndpointRouteBuilder app) =>
2323
}
2424

2525
var flags = (await featureFlags.GetAllFlagsAsync()).ToList();
26-
var tenantIdStr = id.Value.ToString(
27-
System.Globalization.CultureInfo.InvariantCulture
28-
);
29-
30-
var overrideTasks = flags
31-
.Where(f => !f.IsDeprecated)
32-
.Select(f => featureFlags.GetOverridesAsync(f.Name));
33-
var allOverrides = await Task.WhenAll(overrideTasks);
34-
35-
var tenantOverrides = allOverrides
36-
.SelectMany(o => o)
37-
.Where(o =>
38-
o.OverrideType == OverrideType.Tenant
39-
&& string.Equals(o.OverrideValue, tenantIdStr, StringComparison.Ordinal)
40-
)
41-
.ToList();
26+
var tenantOverrides = await TenantFeatureHelper.GetOverridesForTenantAsync(
27+
featureFlags, flags, id);
4228

4329
return Results.Ok(new TenantFeaturesResponse(flags, tenantOverrides));
4430
}

‎modules/Tenants/src/SimpleModule.Tenants/Endpoints/TenantFeatures/SetTenantFeatureEndpoint.cs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,12 @@ public void Map(IEndpointRouteBuilder app) =>
2222
return Results.NotFound();
2323
}
2424

25-
var tenantIdStr = id.Value.ToString(
26-
System.Globalization.CultureInfo.InvariantCulture
27-
);
2825
var result = await featureFlags.SetOverrideAsync(
2926
flagName,
3027
new SetOverrideRequest
3128
{
3229
OverrideType = OverrideType.Tenant,
33-
OverrideValue = tenantIdStr,
30+
OverrideValue = id.Value.ToString(System.Globalization.CultureInfo.InvariantCulture),
3431
IsEnabled = request.IsEnabled,
3532
}
3633
);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using SimpleModule.FeatureFlags.Contracts;
2+
using SimpleModule.Tenants.Contracts;
3+
4+
namespace SimpleModule.Tenants.Endpoints.TenantFeatures;
5+
6+
internal static class TenantFeatureHelper
7+
{
8+
public static async Task<List<FeatureFlagOverride>> GetOverridesForTenantAsync(
9+
IFeatureFlagContracts featureFlags,
10+
IEnumerable<FeatureFlag> flags,
11+
TenantId tenantId)
12+
{
13+
var tenantIdStr = tenantId.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);
14+
var overrideTasks = flags
15+
.Where(f => !f.IsDeprecated)
16+
.Select(f => featureFlags.GetOverridesAsync(f.Name));
17+
var allOverrides = await Task.WhenAll(overrideTasks);
18+
return allOverrides
19+
.SelectMany(o => o)
20+
.Where(o =>
21+
o.OverrideType == OverrideType.Tenant
22+
&& string.Equals(o.OverrideValue, tenantIdStr, StringComparison.Ordinal))
23+
.ToList();
24+
}
25+
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using Microsoft.AspNetCore.Builder;
2-
using Microsoft.AspNetCore.Http;
32
using Microsoft.AspNetCore.Routing;
43
using SimpleModule.Core;
54
using SimpleModule.Core.Authorization;
5+
using SimpleModule.Core.Endpoints;
66
using SimpleModule.Tenants.Contracts;
77

88
namespace SimpleModule.Tenants.Endpoints.Tenants;
@@ -12,11 +12,8 @@ public class RemoveHostEndpoint : IEndpoint
1212
public void Map(IEndpointRouteBuilder app) =>
1313
app.MapDelete(
1414
"/{id}/hosts/{hostId}",
15-
async (TenantId id, TenantHostId hostId, ITenantContracts contracts) =>
16-
{
17-
await contracts.RemoveHostAsync(id, hostId);
18-
return TypedResults.NoContent();
19-
}
15+
(TenantId id, TenantHostId hostId, ITenantContracts contracts) =>
16+
CrudEndpoints.Delete(() => contracts.RemoveHostAsync(id, hostId))
2017
)
2118
.RequirePermission(TenantsPermissions.ManageHosts);
2219
}

‎modules/Tenants/src/SimpleModule.Tenants/Views/Browse.tsx‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Card, CardContent, PageShell } from '@simplemodule/ui';
2+
import { statusColors, statusLabels } from './tenantStatus';
23

34
interface BrowseTenant {
45
id: number;
@@ -8,13 +9,6 @@ interface BrowseTenant {
89
hostCount: number;
910
}
1011

11-
const statusLabels: Record<number, string> = { 0: 'Active', 1: 'Suspended', 2: 'Inactive' };
12-
const statusColors: Record<number, string> = {
13-
0: 'text-green-600',
14-
1: 'text-yellow-600',
15-
2: 'text-red-600',
16-
};
17-
1812
export default function Browse({ tenants }: { tenants: BrowseTenant[] }) {
1913
return (
2014
<PageShell title="Tenants" description="Browse all tenants.">

‎modules/Tenants/src/SimpleModule.Tenants/Views/Edit.tsx‎

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,8 @@ import {
2222
TableRow,
2323
} from '@simplemodule/ui';
2424
import { useState } from 'react';
25-
26-
interface TenantHost {
27-
id: number;
28-
tenantId: number;
29-
hostName: string;
30-
isActive: boolean;
31-
}
32-
33-
interface Tenant {
34-
id: number;
35-
name: string;
36-
slug: string;
37-
status: number;
38-
adminEmail: string | null;
39-
editionName: string | null;
40-
connectionString: string | null;
41-
validUpTo: string | null;
42-
hosts: TenantHost[];
43-
}
44-
45-
const statusLabels: Record<number, string> = { 0: 'Active', 1: 'Suspended', 2: 'Inactive' };
25+
import type { Tenant } from '../types';
26+
import { statusLabels } from './tenantStatus';
4627

4728
export default function Edit({ tenant }: { tenant: Tenant }) {
4829
const [newHost, setNewHost] = useState('');

‎modules/Tenants/src/SimpleModule.Tenants/Views/FeaturesEndpoint.cs‎

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using SimpleModule.Core.Inertia;
88
using SimpleModule.FeatureFlags.Contracts;
99
using SimpleModule.Tenants.Contracts;
10+
using SimpleModule.Tenants.Endpoints.TenantFeatures;
1011

1112
namespace SimpleModule.Tenants.Views;
1213

@@ -35,22 +36,8 @@ public void Map(IEndpointRouteBuilder app)
3536
}
3637

3738
var flags = (await featureFlags.GetAllFlagsAsync()).ToList();
38-
var tenantIdStr = id.Value.ToString(
39-
System.Globalization.CultureInfo.InvariantCulture
40-
);
41-
42-
var overrideTasks = flags
43-
.Where(f => !f.IsDeprecated)
44-
.Select(f => featureFlags.GetOverridesAsync(f.Name));
45-
var allOverrides = await Task.WhenAll(overrideTasks);
46-
47-
var tenantOverrides = allOverrides
48-
.SelectMany(o => o)
49-
.Where(o =>
50-
o.OverrideType == OverrideType.Tenant
51-
&& string.Equals(o.OverrideValue, tenantIdStr, StringComparison.Ordinal)
52-
)
53-
.ToList();
39+
var tenantOverrides = await TenantFeatureHelper.GetOverridesForTenantAsync(
40+
featureFlags, flags, id);
5441

5542
return Inertia.Render(
5643
"Tenants/Features",

‎modules/Tenants/src/SimpleModule.Tenants/Views/Manage.tsx‎

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,8 @@ import {
1616
TableRow,
1717
} from '@simplemodule/ui';
1818
import { useState } from 'react';
19-
20-
interface Tenant {
21-
id: number;
22-
name: string;
23-
slug: string;
24-
status: number;
25-
adminEmail: string | null;
26-
editionName: string | null;
27-
hosts: { id: number; hostName: string; isActive: boolean }[];
28-
}
29-
30-
const statusLabels: Record<number, string> = { 0: 'Active', 1: 'Suspended', 2: 'Inactive' };
31-
const statusColors: Record<number, string> = {
32-
0: 'text-green-600',
33-
1: 'text-yellow-600',
34-
2: 'text-red-600',
35-
};
19+
import type { Tenant } from '../types';
20+
import { statusColors, statusLabels } from './tenantStatus';
3621

3722
export default function Manage({ tenants }: { tenants: Tenant[] }) {
3823
const [deleteTarget, setDeleteTarget] = useState<{ id: number; name: string } | null>(null);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const statusLabels: Record<number, string> = {
2+
0: 'Active',
3+
1: 'Suspended',
4+
2: 'Inactive',
5+
};
6+
7+
export const statusColors: Record<number, string> = {
8+
0: 'text-green-600',
9+
1: 'text-yellow-600',
10+
2: 'text-red-600',
11+
};

0 commit comments

Comments
 (0)