Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 0 additions & 91 deletions web-server/pages/api/integrations/selected.ts

This file was deleted.

118 changes: 101 additions & 17 deletions web-server/pages/api/resources/orgs/[org_id]/teams/v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
} from 'ramda';
import * as yup from 'yup';

import { getSelectedReposForOrg } from '@/api/integrations/selected';
import { syncReposForOrg } from '@/api/internal/[org_id]/sync_repos';
import {
getOnBoardingState,
Expand All @@ -22,8 +21,12 @@ import {
} from '@/constants/integrations';
import { getTeamV2Mock } from '@/mocks/teams';
import { BaseTeam } from '@/types/api/teams';
import { OnboardingStep, ReqRepoWithProvider } from '@/types/resources';
import { db, getFirstRow } from '@/utils/db';
import {
OnboardingStep,
RepoWithMultipleWorkflows,
ReqRepoWithProvider
} from '@/types/resources';
import { db, dbRaw, getFirstRow } from '@/utils/db';
import groupBy from '@/utils/objectArray';

const repoSchema = yup.object().shape({
Expand Down Expand Up @@ -84,17 +87,16 @@ endpoint.handle.GET(getSchema, async (req, res) => {
.orderBy('name', 'asc');

const teams = await getQuery;
const reposWithWorkflows = await getSelectedReposForOrg(
const teamReposMap = await getTeamReposMap(
org_id,
providers?.length
? (providers as Integration[])
: [Integration.GITHUB, Integration.GITLAB]
).then((res) => res.flat());
);

res.send({
teams: teams,
teamReposMap: ramdaGroupBy(prop('team_id'), reposWithWorkflows),
reposWithWorkflows
teamReposMap
});
});

Expand Down Expand Up @@ -134,7 +136,7 @@ endpoint.handle.POST(postSchema, async (req, res) => {

const providers = Array.from(new Set(orgReposList.map((r) => r.provider)));
await updateReposWorkflows(org_id, orgReposList);
const reposWithWorkflows = await getSelectedReposForOrg(
const teamReposMap = await getTeamReposMap(
org_id,
providers as Integration[]
);
Expand All @@ -143,7 +145,7 @@ endpoint.handle.POST(postSchema, async (req, res) => {

res.send({
team,
teamReposMap: ramdaGroupBy(prop('team_id'), reposWithWorkflows)
teamReposMap
});
});

Expand Down Expand Up @@ -177,14 +179,14 @@ endpoint.handle.PATCH(patchSchema, async (req, res) => {

const providers = Array.from(new Set(orgReposList.map((r) => r.provider)));

const reposWithWorkflows = await getSelectedReposForOrg(
const teamReposMap = await getTeamReposMap(
org_id,
providers as Integration[]
);
syncReposForOrg();
res.send({
team,
teamReposMap: ramdaGroupBy(prop('team_id'), reposWithWorkflows)
teamReposMap
});
});

Expand All @@ -193,12 +195,49 @@ endpoint.handle.DELETE(deleteSchema, async (req, res) => {
return res.send(getTeamV2Mock);
}

const data = await db('Team')
.update('is_deleted', true)
.where('id', req.payload.id)
.orderBy('name', 'asc')
.returning('*')
.then(getFirstRow);
const data = await dbRaw.transaction(async (trx) => {
const deletedTeamRow = await trx('Team')
.update({
is_deleted: true,
updated_at: new Date()
})
.where('id', req.payload.id)
.orderBy('name', 'asc')
.returning('*')
.then(getFirstRow);

// 1. Mark inactive and Get Repo Ids of this deleted team. Ex: [ '123', '456', '789' ]
const deletedTeamRepoIds: string[] = await trx('TeamRepos')
.update({
is_active: false,
updated_at: new Date()
})
.where('team_id', req.payload.id)
.andWhere('is_active', true)
.returning('org_repo_id')
.then((result) => result.map((row) => row.org_repo_id));

// 2. Get Repo Ids which are still used across other teams. Ex: [ '456', '789' ]
const activeRepoIds: string[] = await trx('TeamRepos')
.where('is_active', true)
.whereIn('org_repo_id', deletedTeamRepoIds)
.distinct('org_repo_id')
.then((result) => result.map((row) => row.org_repo_id));

// 3. Repo Ids which are nowhere used. Ex: [ '123' ]
const orgRepoIdsToBeInactivate = deletedTeamRepoIds.filter(
(id) => !activeRepoIds.includes(id)
);

await trx('OrgRepo')
.update({
is_active: false,
updated_at: new Date()
})
.whereIn('id', orgRepoIdsToBeInactivate);

return deletedTeamRow;
});

res.send(data);
});
Expand Down Expand Up @@ -302,3 +341,48 @@ const updateReposWorkflows = async (
}
}
};

const getTeamReposMap = async (org_id: ID, providers: Integration[]) => {
const baseQuery = db(Table.OrgRepo)
.where('org_id', org_id)
.andWhere('OrgRepo.is_active', true)
.whereIn('OrgRepo.provider', providers);

const teamJoin = baseQuery
.leftJoin({ tr: Table.TeamRepos }, 'OrgRepo.id', 'tr.org_repo_id')
.andWhere('tr.is_active', true);

const workflowJoin = teamJoin.leftJoin(
{ rw: Table.RepoWorkflow },
function () {
this.on('OrgRepo.id', 'rw.org_repo_id').andOn(
'rw.is_active',
'tr.is_active'
);
}
);

const dbRepos: RepoWithMultipleWorkflows[] = await workflowJoin
.select('OrgRepo.*')
.select(
dbRaw.raw(
"COALESCE(json_agg(rw.*) FILTER (WHERE rw.id IS NOT NULL), '[]') as repo_workflows"
)
)
.select('tr.deployment_type', 'tr.team_id')
.groupBy('OrgRepo.id', 'tr.deployment_type', 'tr.team_id');

const repoWithWorkflows = dbRepos.map((repo) => {
const updatedWorkflows = repo.repo_workflows.map((workflow) => ({
name: workflow.name,
value: workflow.provider_workflow_id
}));

return {
...repo,
repo_workflows: updatedWorkflows
};
});

return ramdaGroupBy(prop('team_id'), repoWithWorkflows);
};
16 changes: 1 addition & 15 deletions web-server/src/slices/repos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import { Integration } from '@/constants/integrations';
import { RootState } from '@/store/index';
import { LoadedOrg } from '@/types/github';
import { StateFetchConfig } from '@/types/redux';
import {
BaseRepo,
RepoUniqueDetails,
RepoWithMultipleWorkflows
} from '@/types/resources';
import { BaseRepo, RepoUniqueDetails } from '@/types/resources';
import { addFetchCasesToReducer } from '@/utils/redux';

type RepoSelectionMap = Record<BaseRepo['parent'], RepoUniqueDetails[]>;
Expand Down Expand Up @@ -155,13 +151,3 @@ export const fetchReposForOrgFromProvider = createAsyncThunk(
);
}
);

export const fetchSelectedRepos = createAsyncThunk(
'repos/fetchSelectedRepos',
async (params: { orgId: ID; provider: Integration }) => {
return await handleApi<RepoWithMultipleWorkflows[]>(
`/integrations/selected`,
{ params: { org_id: params.orgId, provider: params.provider } }
);
}
);
Loading