1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-20 05:49:40 +02:00
portainer/app/react/kubernetes/helm/queries/useHelmRepoVersions.ts

101 lines
2.8 KiB
TypeScript

import { useQueries } from '@tanstack/react-query';
import { useMemo } from 'react';
import { compact, flatMap } from 'lodash';
import { withGlobalError } from '@/react-tools/react-query';
import axios, { parseAxiosError } from '@/portainer/services/axios';
interface HelmSearch {
entries: Entries;
}
interface Entries {
[key: string]: { version: string; appVersion: string }[];
}
export interface ChartVersion {
Chart?: string;
Repo: string;
Label?: string;
Version: string;
AppVersion?: string;
}
type RepoSource = {
repo?: string;
};
/**
* React hook to get a list of available versions for a chart from specified repositories
*
* @param chart The chart name to get versions for
* @param repositories Array of repository URLs to search in
* @param staleTime Stale time for the query
* @param useCache Whether to use the cache for the query
*/
export function useHelmRepoVersions(
chart: string,
staleTime: number,
repoSources: RepoSource[] = [],
useCache: boolean = true
) {
// Fetch versions from each repository in parallel as separate queries
const versionQueries = useQueries({
queries: useMemo(
() =>
repoSources.map(({ repo }) => ({
queryKey: ['helm', 'repositories', chart, repo, useCache],
queryFn: () => getSearchHelmRepo({ repo, chart, useCache }),
enabled: !!chart && repoSources.length > 0,
staleTime,
...withGlobalError(`Unable to retrieve versions from ${repo}`),
})),
[repoSources, chart, staleTime, useCache]
),
});
// Combine the results from all repositories for easier consumption
const allVersions = useMemo(() => {
const successfulResults = compact(versionQueries.map((q) => q.data));
return flatMap(successfulResults);
}, [versionQueries]);
return {
data: allVersions,
isInitialLoading: versionQueries.some((q) => q.isInitialLoading),
isError: versionQueries.some((q) => q.isError),
isFetching: versionQueries.some((q) => q.isFetching),
refetch: () => Promise.all(versionQueries.map((q) => q.refetch())),
};
}
type SearchRepoParams = {
repo?: string;
chart: string;
useCache?: boolean;
};
/**
* Get Helm repositories for user
*/
async function getSearchHelmRepo(
params: SearchRepoParams
): Promise<ChartVersion[]> {
try {
const { data } = await axios.get<HelmSearch>(`templates/helm`, {
params,
});
// if separated by '/', take the last part
const chartKey = params.chart.split('/').pop() || params.chart;
const versions = data.entries[chartKey];
return (
versions?.map((v) => ({
Repo: params.repo ?? '',
Version: v.version,
AppVersion: v.appVersion,
})) ?? []
);
} catch (err) {
throw parseAxiosError(err, 'Unable to retrieve helm repositories for user');
}
}