Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimistically add and remove members from admins room #56895

Merged
Show file tree
Hide file tree
Changes from 4 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
131 changes: 81 additions & 50 deletions src/libs/actions/Policy/Member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import type {OnyxData} from '@src/types/onyx/Request';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import {createPolicyExpenseChats} from './Policy';

type AnnounceRoomMembersOnyxData = {
type RoomMembersOnyxData = {
onyxOptimisticData: OnyxUpdate[];
onyxSuccessData: OnyxUpdate[];
onyxFailureData: OnyxUpdate[];
Expand Down Expand Up @@ -133,43 +133,47 @@ function getPolicy(policyID: string | undefined): OnyxEntry<Policy> {
/**
* Build optimistic data for adding members to the announcement room
*/
function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[]): AnnounceRoomMembersOnyxData {
const announceReport = ReportUtils.getRoom(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID);
const announceReportMetadata = ReportUtils.getReportMetadata(announceReport?.reportID);
const announceRoomMembers: AnnounceRoomMembersOnyxData = {
function buildRoomMembersOnyxData(
roomType: typeof CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE | typeof CONST.REPORT.CHAT_TYPE.POLICY_ADMINS,
policyID: string,
accountIDs: number[],
): RoomMembersOnyxData {
const report = ReportUtils.getRoom(roomType, policyID);
const reportMetadata = ReportUtils.getReportMetadata(report?.reportID);
const roomMembers: RoomMembersOnyxData = {
onyxOptimisticData: [],
onyxFailureData: [],
onyxSuccessData: [],
};

if (!announceReport) {
return announceRoomMembers;
if (!report || accountIDs.length === 0) {
return roomMembers;
}

const participantAccountIDs = [...Object.keys(announceReport.participants ?? {}).map(Number), ...accountIDs];
const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, announceReportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
const participantAccountIDs = [...Object.keys(report.participants ?? {}).map(Number), ...accountIDs];
const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, reportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);

announceRoomMembers.onyxOptimisticData.push(
roomMembers.onyxOptimisticData.push(
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport?.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT}${report?.reportID}`,
value: {
participants: ReportUtils.buildParticipantsFromAccountIDs(participantAccountIDs),
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport?.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report?.reportID}`,
value: {
pendingChatMembers,
},
},
);

announceRoomMembers.onyxFailureData.push(
roomMembers.onyxFailureData.push(
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport?.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT}${report?.reportID}`,
value: {
participants: accountIDs.reduce((acc, curr) => {
Object.assign(acc, {[curr]: null});
Expand All @@ -179,20 +183,20 @@ function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[]
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport?.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report?.reportID}`,
value: {
pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null,
pendingChatMembers: reportMetadata?.pendingChatMembers ?? null,
},
},
);
announceRoomMembers.onyxSuccessData.push({
roomMembers.onyxSuccessData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport?.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report?.reportID}`,
value: {
pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null,
pendingChatMembers: reportMetadata?.pendingChatMembers ?? null,
},
});
return announceRoomMembers;
return roomMembers;
}
/**
* Updates the import spreadsheet data according to the result of the import
Expand Down Expand Up @@ -231,30 +235,35 @@ function updateImportSpreadsheetData(membersLength: number): OnyxData {
/**
* Build optimistic data for removing users from the announcement room
*/
function removeOptimisticAnnounceRoomMembers(policyID: string | undefined, policyName: string, accountIDs: number[]): AnnounceRoomMembersOnyxData {
const announceRoomMembers: AnnounceRoomMembersOnyxData = {
function removeOptimisticRoomMembers(
roomType: typeof CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE | typeof CONST.REPORT.CHAT_TYPE.POLICY_ADMINS,
policyID: string | undefined,
policyName: string,
accountIDs: number[],
): RoomMembersOnyxData {
const roomMembers: RoomMembersOnyxData = {
onyxOptimisticData: [],
onyxFailureData: [],
onyxSuccessData: [],
};

if (!policyID) {
return announceRoomMembers;
return roomMembers;
}

const announceReport = ReportUtils.getRoom(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID);
const announceReportMetadata = ReportUtils.getReportMetadata(announceReport?.reportID);
const report = ReportUtils.getRoom(roomType, policyID);
const reportMetadata = ReportUtils.getReportMetadata(report?.reportID);

if (!announceReport) {
return announceRoomMembers;
if (!report) {
return roomMembers;
}

const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, announceReportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, reportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);

announceRoomMembers.onyxOptimisticData.push(
roomMembers.onyxOptimisticData.push(
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`,
value: {
...(accountIDs.includes(sessionAccountID)
? {
Expand All @@ -267,43 +276,43 @@ function removeOptimisticAnnounceRoomMembers(policyID: string | undefined, polic
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report.reportID}`,
value: {
pendingChatMembers,
},
},
);
announceRoomMembers.onyxFailureData.push(
roomMembers.onyxFailureData.push(
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`,
value: {
...(accountIDs.includes(sessionAccountID)
? {
statusNum: announceReport.statusNum,
stateNum: announceReport.stateNum,
oldPolicyName: announceReport.oldPolicyName,
statusNum: report.statusNum,
stateNum: report.stateNum,
oldPolicyName: report.oldPolicyName,
}
: {}),
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report.reportID}`,
value: {
pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null,
pendingChatMembers: reportMetadata?.pendingChatMembers ?? null,
},
},
);
announceRoomMembers.onyxSuccessData.push({
roomMembers.onyxSuccessData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport.reportID}`,
key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report.reportID}`,
value: {
pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null,
pendingChatMembers: reportMetadata?.pendingChatMembers ?? null,
},
});

return announceRoomMembers;
return roomMembers;
}

/**
Expand All @@ -326,7 +335,16 @@ function removeMembers(accountIDs: number[], policyID: string) {
ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy?.name ?? '', CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY),
);

const announceRoomMembers = removeOptimisticAnnounceRoomMembers(policy?.id, policy?.name ?? '', accountIDs);
const announceRoomMembers = removeOptimisticRoomMembers(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policy?.id, policy?.name ?? '', accountIDs);
const adminRoomMembers = removeOptimisticRoomMembers(
CONST.REPORT.CHAT_TYPE.POLICY_ADMINS,
policy?.id,
policy?.name ?? '',
accountIDs.filter((accountID) => {
const login = allPersonalDetails?.[accountID]?.login;
return login && policy?.employeeList?.[login]?.role !== CONST.POLICY.ROLE.USER;
}),
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are AUDITORs members of the #admins room too? Asking because I don't see them mentioned here https://github.com/Expensify/App?tab=readme-ov-file#workspace-admin-room

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BE adds auditor as the admins member, so I guess yes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should compare with role === ADMIN || role === AUDITOR to account for further changes in case another role is added

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. Updated.


const optimisticMembersState: OnyxCollectionInputValue<PolicyEmployee> = {};
const successMembersState: OnyxCollectionInputValue<PolicyEmployee> = {};
Expand Down Expand Up @@ -390,7 +408,7 @@ function removeMembers(accountIDs: number[], policyID: string) {
},
},
];
optimisticData.push(...announceRoomMembers.onyxOptimisticData);
optimisticData.push(...announceRoomMembers.onyxOptimisticData, ...adminRoomMembers.onyxOptimisticData);

const successData: OnyxUpdate[] = [
{
Expand All @@ -399,7 +417,7 @@ function removeMembers(accountIDs: number[], policyID: string) {
value: {employeeList: successMembersState},
},
];
successData.push(...announceRoomMembers.onyxSuccessData);
successData.push(...announceRoomMembers.onyxSuccessData, ...adminRoomMembers.onyxSuccessData);

const failureData: OnyxUpdate[] = [
{
Expand All @@ -408,7 +426,7 @@ function removeMembers(accountIDs: number[], policyID: string) {
value: {employeeList: failureMembersState, approver: policy?.approver, rules: policy?.rules},
},
];
failureData.push(...announceRoomMembers.onyxFailureData);
failureData.push(...announceRoomMembers.onyxFailureData, ...adminRoomMembers.onyxFailureData);

const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);

Expand Down Expand Up @@ -675,7 +693,8 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount
const {newAccountIDs, newLogins} = PersonalDetailsUtils.getNewAccountIDsAndLogins(logins, accountIDs);
const newPersonalDetailsOnyxData = PersonalDetailsUtils.getPersonalDetailsOnyxDataForOptimisticUsers(newLogins, newAccountIDs);

const announceRoomMembers = buildAnnounceRoomMembersOnyxData(policyID, accountIDs);
const announceRoomMembers = buildRoomMembersOnyxData(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID, accountIDs);
const adminRoomMembers = buildRoomMembersOnyxData(CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, policyID, role !== CONST.POLICY.ROLE.USER ? accountIDs : []);
const optimisticAnnounceChat = ReportUtils.buildOptimisticAnnounceChat(policyID, [...policyMemberAccountIDs, ...accountIDs]);
const announceRoomChat = optimisticAnnounceChat.announceChatData;

Expand Down Expand Up @@ -709,7 +728,13 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount
},
},
];
optimisticData.push(...newPersonalDetailsOnyxData.optimisticData, ...membersChats.onyxOptimisticData, ...announceRoomChat.onyxOptimisticData, ...announceRoomMembers.onyxOptimisticData);
optimisticData.push(
...newPersonalDetailsOnyxData.optimisticData,
...membersChats.onyxOptimisticData,
...announceRoomChat.onyxOptimisticData,
...announceRoomMembers.onyxOptimisticData,
...adminRoomMembers.onyxOptimisticData,
);

const successData: OnyxUpdate[] = [
{
Expand All @@ -720,7 +745,13 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount
},
},
];
successData.push(...newPersonalDetailsOnyxData.finallyData, ...membersChats.onyxSuccessData, ...announceRoomChat.onyxSuccessData, ...announceRoomMembers.onyxSuccessData);
successData.push(
...newPersonalDetailsOnyxData.finallyData,
...membersChats.onyxSuccessData,
...announceRoomChat.onyxSuccessData,
...announceRoomMembers.onyxSuccessData,
...adminRoomMembers.onyxSuccessData,
);

const failureData: OnyxUpdate[] = [
{
Expand All @@ -734,7 +765,7 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount
},
},
];
failureData.push(...membersChats.onyxFailureData, ...announceRoomChat.onyxFailureData, ...announceRoomMembers.onyxFailureData);
failureData.push(...membersChats.onyxFailureData, ...announceRoomChat.onyxFailureData, ...announceRoomMembers.onyxFailureData, ...adminRoomMembers.onyxFailureData);

const params: AddMembersToWorkspaceParams = {
employees: JSON.stringify(logins.map((login) => ({email: login, role}))),
Expand Down
Loading
Loading