Show template inheritance overrides

This commit is contained in:
2026-09-08 10:25:52 +00:00
committed by Twyco
parent fef82cb88f
commit 831014f7fe
16 changed files with 334 additions and 4 deletions
+26
View File
@@ -110,6 +110,32 @@ const projectAreas = [
</div>
</div>
<Card v-if="templateState?.inheritsFromTemplate">
<CardHeader>
<CardTitle>
Built from template {{ templateState.templateName }}
</CardTitle>
<CardDescription>
This project keeps its template link. Inherited areas follow the template baseline; overridden areas were customized locally.
</CardDescription>
</CardHeader>
<CardContent class="flex flex-wrap gap-2">
<Badge
v-for="area in templateState.inheritedAreas"
:key="`inherited-${area.value}`"
variant="outline"
>
{{ area.label }} · inherited
</Badge>
<Badge
v-for="area in templateState.overriddenAreas"
:key="`overridden-${area.value}`"
>
{{ area.label }} · overridden
</Badge>
</CardContent>
</Card>
<div v-if="canManageAccess" class="flex flex-wrap gap-3">
<Button as-child>
<Link :href="boardSettings(project.id)">
@@ -138,6 +138,32 @@ const statusAllowsTarget = (
{{ status }}
</div>
<Card v-if="templateState?.inheritsFromTemplate">
<CardHeader>
<CardTitle>
Template inheritance: {{ templateState.templateName }}
</CardTitle>
<CardDescription>
This project stays linked to its template. Sections below show whether the current configuration is still inherited or has local overrides.
</CardDescription>
</CardHeader>
<CardContent class="flex flex-wrap gap-2">
<Badge
v-for="area in templateState.inheritedAreas"
:key="`inherited-${area.value}`"
variant="outline"
>
{{ area.label }} · inherited
</Badge>
<Badge
v-for="area in templateState.overriddenAreas"
:key="`overridden-${area.value}`"
>
{{ area.label }} · overridden
</Badge>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Workflow model</CardTitle>
@@ -115,6 +115,32 @@ const replacementTicketTypes = (ticketTypeId: number) =>
{{ status }}
</div>
<Card v-if="templateState?.inheritsFromTemplate">
<CardHeader>
<CardTitle>
Template inheritance: {{ templateState.templateName }}
</CardTitle>
<CardDescription>
Inherited sections stay synced with the template baseline. Local edits in these settings are treated as project-specific overrides.
</CardDescription>
</CardHeader>
<CardContent class="flex flex-wrap gap-2">
<Badge
v-for="area in templateState.inheritedAreas"
:key="`inherited-${area.value}`"
variant="outline"
>
{{ area.label }} · inherited
</Badge>
<Badge
v-for="area in templateState.overriddenAreas"
:key="`overridden-${area.value}`"
>
{{ area.label }} · overridden
</Badge>
</CardContent>
</Card>
<div class="grid gap-6 xl:grid-cols-2">
<Card class="gap-0 overflow-hidden">
<CardHeader class="border-b">
@@ -305,6 +305,32 @@ const notificationActionTimestamp = (
{{ status }}
</div>
<Card v-if="templateState?.inheritsFromTemplate">
<CardHeader>
<CardTitle>
Template inheritance: {{ templateState.templateName }}
</CardTitle>
<CardDescription>
Notification rules can remain inherited from the template or diverge here as project-level overrides.
</CardDescription>
</CardHeader>
<CardContent class="flex flex-wrap gap-2">
<Badge
v-for="area in templateState.inheritedAreas"
:key="`inherited-${area.value}`"
variant="outline"
>
{{ area.label }} · inherited
</Badge>
<Badge
v-for="area in templateState.overriddenAreas"
:key="`overridden-${area.value}`"
>
{{ area.label }} · overridden
</Badge>
</CardContent>
</Card>
<div class="grid gap-6 xl:grid-cols-[24rem_minmax(0,1fr)]">
<div class="space-y-6">
<Card>
@@ -277,6 +277,32 @@ const submitUpdate = (): void => {
{{ status }}
</div>
<Card v-if="templateState?.inheritsFromTemplate">
<CardHeader>
<CardTitle>
Template inheritance: {{ templateState.templateName }}
</CardTitle>
<CardDescription>
Repository links can stay inherited from the template or be replaced with project-specific overrides.
</CardDescription>
</CardHeader>
<CardContent class="flex flex-wrap gap-2">
<Badge
v-for="area in templateState.inheritedAreas"
:key="`inherited-${area.value}`"
variant="outline"
>
{{ area.label }} · inherited
</Badge>
<Badge
v-for="area in templateState.overriddenAreas"
:key="`overridden-${area.value}`"
>
{{ area.label }} · overridden
</Badge>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Personal Git access</CardTitle>
+20
View File
@@ -61,9 +61,25 @@ export type ProjectTemplatesCreatePageProps = {
project: ProjectModel;
};
export type ProjectTemplateStateArea = {
label: string;
value: string;
};
export type ProjectTemplateState = {
effectiveConfiguration: Record<string, unknown>;
inheritedAreas: ProjectTemplateStateArea[];
inheritsFromTemplate: boolean;
overriddenAreas: ProjectTemplateStateArea[];
templateId: number;
templateName: string;
templateSlug: string;
};
export type ProjectShowPageProps = {
canManageAccess: boolean;
project: ProjectModel;
templateState?: ProjectTemplateState | null;
};
export type PermissionOption = {
@@ -95,6 +111,7 @@ export type ProjectBoardSettingsPageProps = {
boardColumns: BoardColumnModel[];
project: ProjectModel;
status?: string | null;
templateState?: ProjectTemplateState | null;
ticketStatuses: TicketStatusModel[];
};
@@ -121,6 +138,7 @@ export type ProjectTicketMetadataSettingsPageProps = {
project: ProjectModel;
error?: boolean;
status?: string | null;
templateState?: ProjectTemplateState | null;
ticketFieldDefinitions: TicketFieldDefinitionModel[];
ticketLinkTypes: TicketLinkTypeModel[];
ticketPriorities: TicketPriorityModel[];
@@ -132,6 +150,7 @@ export type ProjectRepositorySettingsPageProps = {
project: ProjectModel;
repositoryConnections: RepositoryConnectionModel[];
status?: string | null;
templateState?: ProjectTemplateState | null;
};
export type ProjectNotificationSettingsPageProps = {
@@ -143,6 +162,7 @@ export type ProjectNotificationSettingsPageProps = {
notificationActions: NotificationActionModel[];
project: ProjectModel;
status?: string | null;
templateState?: ProjectTemplateState | null;
templateVariables: NotificationActionTemplateVariableModel[];
};