aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts')
-rw-r--r--server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts56
1 files changed, 55 insertions, 1 deletions
diff --git a/server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts b/server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts
index eec78f438f4..bc109a8e030 100644
--- a/server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts
+++ b/server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts
@@ -19,19 +19,24 @@
*/
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { addGlobalSuccessMessage } from 'design-system';
+import { isEqual, keyBy, partition, pick, unionBy } from 'lodash';
import { getActivity } from '../../api/ce';
import {
createGitLabConfiguration,
deleteGitLabConfiguration,
fetchGitLabConfigurations,
+ fetchGitlabRolesMapping,
syncNowGitLabProvisioning,
updateGitLabConfiguration,
+ updateGitlabRolesMapping,
} from '../../api/gitlab-provisioning';
import { translate } from '../../helpers/l10n';
import { mapReactQueryResult } from '../../helpers/react-query';
-import { AlmSyncStatus, ProvisioningType } from '../../types/provisioning';
+import { AlmSyncStatus, GitLabMapping, ProvisioningType } from '../../types/provisioning';
import { TaskStatuses, TaskTypes } from '../../types/tasks';
+const MAPPING_STALE_TIME = 60_000;
+
export function useGitLabConfigurationsQuery() {
return useQuery({
queryKey: ['identity_provider', 'gitlab_config', 'list'],
@@ -189,3 +194,52 @@ export function useSyncWithGitLabNow() {
canSyncNow: autoProvisioningEnabled && !syncStatus?.nextSync && !mutation.isPending,
};
}
+
+// Order is reversed to put custom roles at the end (their index is -1)
+const defaultRoleOrder = ['owner', 'maintainer', 'developer', 'reporter', 'guest'];
+
+export function useGitlabRolesMappingQuery() {
+ return useQuery({
+ queryKey: ['identity_provider', 'gitlab_mapping'],
+ queryFn: fetchGitlabRolesMapping,
+ staleTime: MAPPING_STALE_TIME,
+ select: (data) =>
+ [...data].sort((a, b) => {
+ if (defaultRoleOrder.includes(a.id) || defaultRoleOrder.includes(b.id)) {
+ return defaultRoleOrder.indexOf(b.id) - defaultRoleOrder.indexOf(a.id);
+ }
+ return a.gitlabRole.localeCompare(b.gitlabRole);
+ }),
+ });
+}
+
+export function useGitlabRolesMappingMutation() {
+ const client = useQueryClient();
+ const queryKey = ['identity_provider', 'gitlab_mapping'];
+ return useMutation({
+ mutationFn: async (mapping: GitLabMapping[]) => {
+ const state = keyBy(client.getQueryData<GitLabMapping[]>(queryKey), (m) => m.id);
+
+ const [maybeChangedRoles] = partition(mapping, (m) => state[m.id]);
+ const changedRoles = maybeChangedRoles.filter((item) => !isEqual(item, state[item.id]));
+
+ return {
+ addedOrChanged: await Promise.all([
+ ...changedRoles.map((data) =>
+ updateGitlabRolesMapping(data.id, pick(data, 'permissions')),
+ ),
+ ]),
+ };
+ },
+ onSuccess: ({ addedOrChanged }) => {
+ const state = client.getQueryData<GitLabMapping[]>(queryKey);
+ if (state) {
+ const newData = unionBy(addedOrChanged, state, (el) => el.id);
+ client.setQueryData(queryKey, newData);
+ }
+ addGlobalSuccessMessage(
+ translate('settings.authentication.gitlab.configuration.roles_mapping.save_success'),
+ );
+ },
+ });
+}