Provisioning: Prevent duplicate source links (#114577)

This commit is contained in:
Alex Khomenko
2025-11-28 13:32:25 +02:00
committed by GitHub
parent 49175bb2cb
commit 026a000304
3 changed files with 21 additions and 5 deletions
+3 -2
View File
@@ -21,7 +21,7 @@ import {
} from 'app/features/apiserver/types';
import { getDashboardUrl } from 'app/features/dashboard-scene/utils/getDashboardUrl';
import { DeleteDashboardResponse } from 'app/features/manage-dashboards/types';
import { buildSourceLink } from 'app/features/provisioning/utils/sourceLink';
import { buildSourceLink, removeExistingSourceLinks } from 'app/features/provisioning/utils/sourceLink';
import { DashboardDataDTO, DashboardDTO, SaveDashboardResponseDTO } from 'app/types/dashboard';
import { SaveDashboardCommand } from '../components/SaveDashboard/types';
@@ -164,7 +164,8 @@ export class K8sDashboardAPI implements DashboardAPI<DashboardDTO, Dashboard> {
// Inject source link for repo-managed dashboards
const sourceLink = await buildSourceLink(annotations);
if (sourceLink) {
result.dashboard.links = [sourceLink, ...(result.dashboard.links || [])];
const linksWithoutSource = removeExistingSourceLinks(result.dashboard.links);
result.dashboard.links = [sourceLink, ...linksWithoutSource];
}
if (dash.metadata.labels?.[DeprecatedInternalId]) {
+4 -3
View File
@@ -9,8 +9,8 @@ import {
AnnoKeyFolder,
AnnoKeyFolderTitle,
AnnoKeyFolderUrl,
AnnoKeyMessage,
AnnoKeyGrantPermissions,
AnnoKeyMessage,
DeprecatedInternalId,
Resource,
ResourceClient,
@@ -18,7 +18,7 @@ import {
} from 'app/features/apiserver/types';
import { getDashboardUrl } from 'app/features/dashboard-scene/utils/getDashboardUrl';
import { DeleteDashboardResponse } from 'app/features/manage-dashboards/types';
import { buildSourceLink } from 'app/features/provisioning/utils/sourceLink';
import { buildSourceLink, removeExistingSourceLinks } from 'app/features/provisioning/utils/sourceLink';
import { DashboardDTO, SaveDashboardResponseDTO } from 'app/types/dashboard';
import { SaveDashboardCommand } from '../components/SaveDashboard/types';
@@ -79,7 +79,8 @@ export class K8sDashboardV2API
// Inject source link for repo-managed dashboards
const sourceLink = await buildSourceLink(dashboard.metadata.annotations);
if (sourceLink) {
dashboard.spec.links = [sourceLink, ...(dashboard.spec.links || [])];
const linksWithoutSource = removeExistingSourceLinks(dashboard.spec.links);
dashboard.spec.links = [sourceLink, ...linksWithoutSource];
}
return dashboard;
@@ -16,6 +16,20 @@ import { isValidRepoType } from '../guards';
import { getHasTokenInstructions, getRepoFileUrl } from './git';
/**
* Find and remove existing source links from the links array.
* A source link is identified by its tooltip matching the source link tooltip translation.
* Returns the links array with source links removed.
*/
export function removeExistingSourceLinks(links: DashboardLink[] | undefined): DashboardLink[] {
if (!links) {
return [];
}
// TODO This is a pretty hacky way to match the source links, needs a better alternative
const sourceLinkTooltip = t('dashboard.source-link.tooltip', 'View source file in repository');
return links.filter((link) => link.tooltip !== sourceLinkTooltip);
}
/**
* Build a source link for a repo-managed dashboard.
* Returns undefined if the dashboard is not repo-managed or if the repository is not a git provider.