mirror of
https://github.com/portainer/portainer.git
synced 2025-08-08 23:35:31 +02:00
refactor(namespace): migrate namespace access view to react [r8s-141] (#87)
This commit is contained in:
parent
8ed7cd80cb
commit
e9fc6d5598
62 changed files with 1018 additions and 610 deletions
|
@ -2,10 +2,9 @@ import { http, HttpResponse } from 'msw';
|
|||
import { render } from '@testing-library/react';
|
||||
|
||||
import {
|
||||
EnvironmentGroup,
|
||||
EnvironmentGroupId,
|
||||
} from '@/react/portainer/environments/environment-groups/types';
|
||||
import { Environment } from '@/react/portainer/environments/types';
|
||||
Environment,
|
||||
} from '@/react/portainer/environments/types';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { Tag } from '@/portainer/tags/types';
|
||||
import { createMockEnvironment } from '@/react-tools/test-mocks';
|
||||
|
@ -13,6 +12,7 @@ import { server } from '@/setup-tests/server';
|
|||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
import { EnvironmentGroup } from '@/react/portainer/environments/environment-groups/types';
|
||||
|
||||
import { EnvironmentItem } from './EnvironmentItem';
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ import {
|
|||
EnvironmentStatus,
|
||||
PlatformType,
|
||||
EdgeTypes,
|
||||
EnvironmentGroupId,
|
||||
} from '@/react/portainer/environments/types';
|
||||
import { EnvironmentGroupId } from '@/react/portainer/environments/environment-groups/types';
|
||||
import {
|
||||
refetchIfAnyOffline,
|
||||
useEnvironmentList,
|
||||
|
|
|
@ -56,6 +56,7 @@ export function AccessDatatable({
|
|||
isLoading={!dataset}
|
||||
columns={columns}
|
||||
settingsManager={tableState}
|
||||
getRowId={(row) => `${row.Type}-${row.Id}`}
|
||||
extendTableOptions={mergeOptions(
|
||||
withMeta({
|
||||
table: 'access-table',
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
|
||||
import { EnvironmentGroupId } from '../types';
|
||||
|
||||
import { buildUrl } from './queries/build-url';
|
||||
import { EnvironmentGroup, EnvironmentGroupId } from './types';
|
||||
import { EnvironmentGroup } from './types';
|
||||
|
||||
export async function getGroup(id: EnvironmentGroupId) {
|
||||
try {
|
||||
const { data: group } = await axios.get<EnvironmentGroup>(buildUrl(id));
|
||||
return group;
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, '');
|
||||
throw parseAxiosError(e, 'Unable to retrieve group');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +19,6 @@ export async function getGroups() {
|
|||
const { data: groups } = await axios.get<EnvironmentGroup[]>(buildUrl());
|
||||
return groups;
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, '');
|
||||
throw parseAxiosError(e, 'Unable to retrieve groups');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { error as notifyError } from '@/portainer/services/notifications';
|
||||
import { withGlobalError } from '@/react-tools/react-query';
|
||||
|
||||
import { EnvironmentGroup, EnvironmentGroupId } from './types';
|
||||
import { EnvironmentGroupId } from '../types';
|
||||
|
||||
import { EnvironmentGroup } from './types';
|
||||
import { getGroup, getGroups } from './environment-groups.service';
|
||||
import { queryKeys } from './queries/query-keys';
|
||||
|
||||
|
@ -17,16 +19,22 @@ export function useGroups<T = EnvironmentGroup[]>({
|
|||
}
|
||||
|
||||
export function useGroup<T = EnvironmentGroup>(
|
||||
groupId: EnvironmentGroupId,
|
||||
select?: (group: EnvironmentGroup) => T
|
||||
groupId?: EnvironmentGroupId,
|
||||
select?: (group: EnvironmentGroup | null) => T
|
||||
) {
|
||||
const { data } = useQuery(queryKeys.group(groupId), () => getGroup(groupId), {
|
||||
staleTime: 50,
|
||||
select,
|
||||
onError(error) {
|
||||
notifyError('Failed loading group', error as Error);
|
||||
return useQuery(
|
||||
queryKeys.group(groupId),
|
||||
() => {
|
||||
if (groupId === undefined) {
|
||||
return null;
|
||||
}
|
||||
return getGroup(groupId);
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
{
|
||||
staleTime: 50,
|
||||
select,
|
||||
enabled: groupId !== undefined,
|
||||
...withGlobalError('Failed loading group'),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { EnvironmentGroupId } from '../types';
|
||||
import { EnvironmentGroupId } from '../../types';
|
||||
|
||||
export function buildUrl(id?: EnvironmentGroupId, action?: string) {
|
||||
let url = '/endpoint_groups';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { EnvironmentGroupId } from '../types';
|
||||
import { EnvironmentGroupId } from '../../types';
|
||||
|
||||
export const queryKeys = {
|
||||
base: () => ['environment-groups'] as const,
|
||||
group: (id: EnvironmentGroupId) => [...queryKeys.base(), id] as const,
|
||||
group: (id?: EnvironmentGroupId) => [...queryKeys.base(), id] as const,
|
||||
};
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { TagId } from '@/portainer/tags/types';
|
||||
|
||||
export type EnvironmentGroupId = number;
|
||||
import {
|
||||
TeamAccessPolicies,
|
||||
UserAccessPolicies,
|
||||
EnvironmentGroupId,
|
||||
} from '../types';
|
||||
|
||||
export interface EnvironmentGroup {
|
||||
// Environment(Endpoint) group Identifier
|
||||
|
@ -11,4 +15,6 @@ export interface EnvironmentGroup {
|
|||
Description: string;
|
||||
// List of tags associated to this environment(endpoint) group
|
||||
TagIds: TagId[];
|
||||
UserAccessPolicies?: UserAccessPolicies;
|
||||
TeamAccessPolicies?: TeamAccessPolicies;
|
||||
}
|
||||
|
|
|
@ -3,15 +3,14 @@ import axios, {
|
|||
json2formData,
|
||||
arrayToJson,
|
||||
} from '@/portainer/services/axios';
|
||||
import { type EnvironmentGroupId } from '@/react/portainer/environments/environment-groups/types';
|
||||
import { type TagId } from '@/portainer/tags/types';
|
||||
import { EdgeAsyncIntervalsValues } from '@/react/edge/components/EdgeAsyncIntervalsForm';
|
||||
|
||||
import {
|
||||
type EnvironmentGroupId,
|
||||
type Environment,
|
||||
ContainerEngine,
|
||||
EnvironmentCreationTypes,
|
||||
} from '../types';
|
||||
} from '@/react/portainer/environments/types';
|
||||
import { type TagId } from '@/portainer/tags/types';
|
||||
import { EdgeAsyncIntervalsValues } from '@/react/edge/components/EdgeAsyncIntervalsForm';
|
||||
|
||||
import { buildUrl } from './utils';
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { type EnvironmentGroupId } from '@/react/portainer/environments/environment-groups/types';
|
||||
import {
|
||||
Environment,
|
||||
EnvironmentId,
|
||||
EnvironmentType,
|
||||
EnvironmentSecuritySettings,
|
||||
EnvironmentStatus,
|
||||
EnvironmentGroupId,
|
||||
} from '@/react/portainer/environments/types';
|
||||
import { type TagId } from '@/portainer/tags/types';
|
||||
import { UserId } from '@/portainer/users/types';
|
||||
import { TeamId } from '@/react/portainer/users/teams/types';
|
||||
|
@ -9,13 +16,6 @@ import {
|
|||
} from '@/react/edge/edge-stacks/types';
|
||||
|
||||
import { getPublicSettings } from '../../settings/settings.service';
|
||||
import type {
|
||||
Environment,
|
||||
EnvironmentId,
|
||||
EnvironmentType,
|
||||
EnvironmentSecuritySettings,
|
||||
EnvironmentStatus,
|
||||
} from '../types';
|
||||
|
||||
import { buildUrl } from './utils';
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@ import {
|
|||
KubernetesSettings,
|
||||
DeploymentOptions,
|
||||
EndpointChangeWindow,
|
||||
EnvironmentGroupId,
|
||||
} from '@/react/portainer/environments/types';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { TagId } from '@/portainer/tags/types';
|
||||
|
||||
import { EnvironmentGroupId } from '../environment-groups/types';
|
||||
import { buildUrl } from '../environment.service/utils';
|
||||
|
||||
import { environmentQueryKeys } from './query-keys';
|
||||
|
|
|
@ -12,9 +12,8 @@ import { queryKeys as edgeGroupQueryKeys } from '@/react/edge/edge-groups/querie
|
|||
import { queryKeys as groupQueryKeys } from '@/react/portainer/environments/environment-groups/queries/query-keys';
|
||||
import { tagKeys } from '@/portainer/tags/queries';
|
||||
|
||||
import { EnvironmentId } from '../types';
|
||||
import { EnvironmentId, EnvironmentGroupId } from '../types';
|
||||
import { buildUrl } from '../environment.service/utils';
|
||||
import { EnvironmentGroupId } from '../environment-groups/types';
|
||||
|
||||
import { environmentQueryKeys } from './query-keys';
|
||||
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
import { TagId } from '@/portainer/tags/types';
|
||||
import { EnvironmentGroupId } from '@/react/portainer/environments/environment-groups/types';
|
||||
import { DockerSnapshot } from '@/react/docker/snapshots/types';
|
||||
|
||||
export type EnvironmentGroupId = number;
|
||||
|
||||
type RoleId = number;
|
||||
interface AccessPolicy {
|
||||
RoleId: RoleId;
|
||||
}
|
||||
|
||||
export type UserAccessPolicies = Record<number, AccessPolicy>; // map[UserID]AccessPolicy
|
||||
export type TeamAccessPolicies = Record<number, AccessPolicy>;
|
||||
|
||||
export type EnvironmentId = number;
|
||||
|
||||
/**
|
||||
|
@ -158,6 +167,8 @@ export type Environment = {
|
|||
* A message that describes the status. Should be included for Status Provisioning or Error.
|
||||
*/
|
||||
StatusMessage?: EnvironmentStatusMessage;
|
||||
UserAccessPolicies?: UserAccessPolicies;
|
||||
TeamAccessPolicies?: TeamAccessPolicies;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useField } from 'formik';
|
||||
|
||||
import { useGroups } from '@/react/portainer/environments/environment-groups/queries';
|
||||
import { EnvironmentGroupId } from '@/react/portainer/environments/environment-groups/types';
|
||||
import { EnvironmentGroupId } from '@/react/portainer/environments/types';
|
||||
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
import { Select } from '@@/form-components/Input';
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { TeamId } from '@/react/portainer/users/teams/types';
|
||||
import { UserId } from '@/portainer/users/types';
|
||||
|
||||
import { TLSConfiguration } from '../../settings/types';
|
||||
import {
|
||||
TeamAccessPolicies,
|
||||
UserAccessPolicies,
|
||||
} from '../../environments/types';
|
||||
|
||||
export type Catalog = {
|
||||
repositories: string[];
|
||||
|
@ -19,14 +20,6 @@ export enum RegistryTypes {
|
|||
GITHUB,
|
||||
}
|
||||
|
||||
export type RoleId = number;
|
||||
interface AccessPolicy {
|
||||
RoleId: RoleId;
|
||||
}
|
||||
|
||||
type UserAccessPolicies = Record<UserId, AccessPolicy>; // map[UserID]AccessPolicy
|
||||
type TeamAccessPolicies = Record<TeamId, AccessPolicy>;
|
||||
|
||||
export interface RegistryAccess {
|
||||
UserAccessPolicies: UserAccessPolicies;
|
||||
TeamAccessPolicies: TeamAccessPolicies;
|
||||
|
|
|
@ -122,6 +122,7 @@ export function CreateTeamForm({ users, teams }: Props) {
|
|||
isLoading={isSubmitting || addTeamMutation.isLoading}
|
||||
loadingText="Creating team..."
|
||||
icon={Plus}
|
||||
className="!ml-0"
|
||||
>
|
||||
Create team
|
||||
</LoadingButton>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue