112 lines
3.4 KiB
TypeScript
112 lines
3.4 KiB
TypeScript
import { useQueryClient } from '@tanstack/react-query';
|
|
import _ from 'lodash';
|
|
|
|
import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
|
|
import { useEnvironment } from '@/react/portainer/environments/queries';
|
|
import { isAgentEnvironment } from '@/react/portainer/environments/utils';
|
|
import { useTasks } from '@/react/docker/proxy/queries/tasks/useTasks';
|
|
import { queryKeys as tasksQueryKeys } from '@/react/docker/proxy/queries/tasks/query-keys';
|
|
import { TaskViewModel } from '@/docker/models/task';
|
|
import { useServices } from '@/react/docker/services/queries/useServices';
|
|
import { queryKeys as servicesQueryKeys } from '@/react/docker/services/queries/query-keys';
|
|
import { ServiceViewModel } from '@/docker/models/service';
|
|
import { useContainers } from '@/react/docker/containers/queries/useContainers';
|
|
import { queryKeys as containersQueryKeys } from '@/react/docker/containers/queries/query-keys';
|
|
import { ContainerListViewModel } from '@/react/docker/containers/types';
|
|
import { SWARM_STACK_NAME_LABEL } from '@/react/constants';
|
|
|
|
import { associateContainerToTask } from '../../tasks/utils';
|
|
import { associateServiceTasks } from '../../services/utils';
|
|
|
|
export function useSwarmStackResources(
|
|
stackName: string,
|
|
{ enabled }: { enabled?: boolean } = {}
|
|
) {
|
|
const queryClient = useQueryClient();
|
|
const environmentId = useEnvironmentId();
|
|
const isAgentQuery = useEnvironment(environmentId, (env) =>
|
|
isAgentEnvironment(env.Type)
|
|
);
|
|
const stackFilter = {
|
|
label: [`${SWARM_STACK_NAME_LABEL}=${stackName}`],
|
|
};
|
|
|
|
const isAgent = isAgentQuery.data || false;
|
|
const servicesQuery = useServices(
|
|
{ environmentId, filters: stackFilter },
|
|
{
|
|
enabled,
|
|
select: (services) => services.map((s) => new ServiceViewModel(s)),
|
|
}
|
|
);
|
|
const tasksQuery = useTasks(
|
|
{
|
|
environmentId,
|
|
filters: stackFilter,
|
|
},
|
|
{ enabled, select: (tasks) => tasks.map((t) => new TaskViewModel(t)) }
|
|
);
|
|
const containersQuery = useContainers(environmentId, {
|
|
enabled: enabled && isAgent,
|
|
});
|
|
|
|
const containerQueryIsLoading = isAgent && containersQuery.isLoading;
|
|
|
|
if (!servicesQuery.data || !tasksQuery.data || containerQueryIsLoading) {
|
|
return {
|
|
data: undefined,
|
|
isLoading: true,
|
|
};
|
|
}
|
|
|
|
const containers =
|
|
isAgent && containersQuery.data ? containersQuery.data : [];
|
|
|
|
const data = assignSwarmStackResources({
|
|
services: servicesQuery.data,
|
|
tasks: tasksQuery.data,
|
|
isAgent,
|
|
containers,
|
|
});
|
|
|
|
return {
|
|
data,
|
|
isLoading: false,
|
|
refetch: () =>
|
|
Promise.all(
|
|
_.compact([
|
|
queryClient.invalidateQueries(servicesQueryKeys.list(environmentId)),
|
|
queryClient.invalidateQueries(tasksQueryKeys.list(environmentId)),
|
|
isAgent &&
|
|
queryClient.invalidateQueries(
|
|
containersQueryKeys.list(environmentId)
|
|
),
|
|
])
|
|
),
|
|
};
|
|
}
|
|
|
|
function assignSwarmStackResources({
|
|
services,
|
|
tasks,
|
|
isAgent,
|
|
containers,
|
|
}: {
|
|
services: ServiceViewModel[];
|
|
tasks: TaskViewModel[];
|
|
isAgent: boolean;
|
|
containers: ContainerListViewModel[];
|
|
}) {
|
|
const associatedTasks = isAgent
|
|
? tasks.map((task) => associateContainerToTask(task, containers))
|
|
: tasks;
|
|
|
|
return services.map((service) => {
|
|
const serviceTasks = associateServiceTasks(service, associatedTasks);
|
|
return {
|
|
...service,
|
|
Tasks: serviceTasks,
|
|
};
|
|
});
|
|
}
|