mirror of
https://github.com/portainer/portainer.git
synced 2025-08-04 21:35:23 +02:00
chore(kubernetes): Migrate Helm Templates View to React R8S-239 (#587)
This commit is contained in:
parent
ad89df4d0d
commit
264ff5457b
20 changed files with 635 additions and 372 deletions
|
@ -0,0 +1,40 @@
|
|||
import { useMutation } from '@tanstack/react-query';
|
||||
|
||||
import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import {
|
||||
queryClient,
|
||||
withGlobalError,
|
||||
withInvalidate,
|
||||
} from '@/react-tools/react-query';
|
||||
import { queryKeys } from '@/react/kubernetes/applications/queries/query-keys';
|
||||
|
||||
import { InstallChartPayload } from '../../types';
|
||||
|
||||
async function installHelmChart(
|
||||
payload: InstallChartPayload,
|
||||
environmentId: EnvironmentId
|
||||
) {
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`endpoints/${environmentId}/kubernetes/helm`,
|
||||
payload
|
||||
);
|
||||
return response.data;
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err as Error, 'Installation error');
|
||||
}
|
||||
}
|
||||
|
||||
export function useHelmChartInstall() {
|
||||
const environmentId = useEnvironmentId();
|
||||
|
||||
return useMutation(
|
||||
(values: InstallChartPayload) => installHelmChart(values, environmentId),
|
||||
{
|
||||
...withGlobalError('Unable to install Helm chart'),
|
||||
...withInvalidate(queryClient, [queryKeys.applications(environmentId)]),
|
||||
}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
import { compact } from 'lodash';
|
||||
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { withGlobalError } from '@/react-tools/react-query';
|
||||
|
||||
import {
|
||||
Chart,
|
||||
HelmChartsResponse,
|
||||
HelmRepositoriesResponse,
|
||||
} from '../../types';
|
||||
|
||||
async function getHelmRepositories(userId: number): Promise<string[]> {
|
||||
try {
|
||||
const response = await axios.get<HelmRepositoriesResponse>(
|
||||
`users/${userId}/helm/repositories`
|
||||
);
|
||||
const { GlobalRepository, UserRepositories } = response.data;
|
||||
|
||||
// Extract URLs from user repositories
|
||||
const userHelmReposUrls = UserRepositories.map((repo) => repo.URL);
|
||||
|
||||
// Combine global and user repositories, remove duplicates and empty values
|
||||
const uniqueHelmRepos = [
|
||||
...new Set([GlobalRepository, ...userHelmReposUrls]),
|
||||
]
|
||||
.map((url) => url.toLowerCase())
|
||||
.filter((url) => url);
|
||||
|
||||
return uniqueHelmRepos;
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err, 'Failed to fetch Helm repositories');
|
||||
}
|
||||
}
|
||||
|
||||
async function getChartsFromRepo(repo: string): Promise<Chart[]> {
|
||||
try {
|
||||
// Construct the URL with required repo parameter
|
||||
const response = await axios.get<HelmChartsResponse>('templates/helm', {
|
||||
params: { repo },
|
||||
});
|
||||
|
||||
return compact(
|
||||
Object.values(response.data.entries).map((versions) =>
|
||||
versions[0] ? { ...versions[0], repo } : null
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
// Ignore errors from chart repositories as some may error but others may not
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function getCharts(userId: number): Promise<Chart[]> {
|
||||
try {
|
||||
// First, get all the helm repositories
|
||||
const repos = await getHelmRepositories(userId);
|
||||
|
||||
// Then fetch charts from each repository in parallel
|
||||
const chartsPromises = repos.map((repo) => getChartsFromRepo(repo));
|
||||
const chartsArrays = await Promise.all(chartsPromises);
|
||||
|
||||
// Flatten the arrays of charts into a single array
|
||||
return chartsArrays.flat();
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err, 'Failed to fetch Helm charts');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* React hook to fetch helm charts from all accessible repositories
|
||||
* @param userId User ID
|
||||
*/
|
||||
export function useHelmChartList(userId: number) {
|
||||
return useQuery([userId, 'helm-charts'], () => getCharts(userId), {
|
||||
enabled: !!userId,
|
||||
...withGlobalError('Unable to retrieve Helm charts'),
|
||||
});
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { withGlobalError } from '@/react-tools/react-query';
|
||||
|
||||
import { Chart } from '../../types';
|
||||
|
||||
async function getHelmChartValues(chart: string, repo: string) {
|
||||
try {
|
||||
const response = await axios.get<string>(`/templates/helm/values`, {
|
||||
params: {
|
||||
repo,
|
||||
chart,
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err as Error, 'Unable to get Helm chart values');
|
||||
}
|
||||
}
|
||||
|
||||
export function useHelmChartValues(chart: Chart) {
|
||||
return useQuery({
|
||||
queryKey: ['helm-chart-values', chart.repo, chart.name],
|
||||
queryFn: () => getHelmChartValues(chart.name, chart.repo),
|
||||
enabled: !!chart.name,
|
||||
select: (data) => ({
|
||||
values: data,
|
||||
}),
|
||||
...withGlobalError('Unable to get Helm chart values'),
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue