Show template inheritance overrides
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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[];
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user