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

Polish admins-only policy room feature #21950

Merged
merged 39 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b8198c8
add writeCapability to create new room
rezkiy37 Jun 27, 2023
823d28a
update admin room welcome message
rezkiy37 Jun 27, 2023
43a46cc
filter out admin-only rooms for members
rezkiy37 Jun 27, 2023
8135994
Revert "update admin room welcome message"
rezkiy37 Jun 27, 2023
a937311
update admin room welcome message
rezkiy37 Jun 27, 2023
42e21d7
fix reports visibility
rezkiy37 Jun 27, 2023
3cacb87
remove extra space for offline indicator
rezkiy37 Jun 27, 2023
e7e9cae
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jun 28, 2023
fc6d024
omit padding bottom of ReportActionItemCreated
rezkiy37 Jun 28, 2023
b298dea
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jun 30, 2023
e40d85c
Apply destructuring assignment of values of validate method
rezkiy37 Jun 30, 2023
e16e167
Add JSDoc
rezkiy37 Jun 30, 2023
35807e8
Add dummy translation
rezkiy37 Jun 30, 2023
e526c7e
Add real translations
rezkiy37 Jul 1, 2023
78e9c5b
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 2, 2023
5ad14aa
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 3, 2023
5e0e492
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 4, 2023
ae5b9dd
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 6, 2023
e8d2625
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 7, 2023
2865c7f
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 14, 2023
36f9d56
restrict some actions
rezkiy37 Jul 14, 2023
f4c89d9
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 17, 2023
3c91515
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 18, 2023
c6279a9
Revert "restrict some actions"
rezkiy37 Jul 18, 2023
9654e73
Revert "remove extra space for offline indicator"
rezkiy37 Jul 18, 2023
8b7fe70
Revert "fix reports visibility"
rezkiy37 Jul 18, 2023
fbbf0b7
Revert "filter out admin-only rooms for members"
rezkiy37 Jul 18, 2023
c1f8509
one-line of isAdminsOnlyPostingRoom
rezkiy37 Jul 18, 2023
3b23219
revert redundant changes
rezkiy37 Jul 18, 2023
9e8e423
show write capability picker for admins only
rezkiy37 Jul 18, 2023
3b3f3c9
move down write capability picker
rezkiy37 Jul 18, 2023
e69102f
Revert "omit padding bottom of ReportActionItemCreated"
rezkiy37 Jul 18, 2023
50a6315
remove bottom spacing of messages list when no composer
rezkiy37 Jul 18, 2023
d1a792c
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 19, 2023
8a224fc
omit unmounted inputs of form
rezkiy37 Jul 19, 2023
ccc00ba
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 19, 2023
76ba533
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 24, 2023
38659cb
add a comment
rezkiy37 Jul 24, 2023
b886d07
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jul 24, 2023
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
2 changes: 2 additions & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ export default {
beginningOfChatHistoryDomainRoomPartTwo: ' to chat with colleagues, share tips, and ask questions.',
beginningOfChatHistoryAdminRoomPartOne: ({workspaceName}) => `Collaboration among ${workspaceName} admins starts here! 🎉\nUse `,
beginningOfChatHistoryAdminRoomPartTwo: ' to chat about topics such as workspace configurations and more.',
beginningOfChatHistoryAdminOnlyPostingRoomPartOne: 'Use ',
beginningOfChatHistoryAdminOnlyPostingRoomPartTwo: ({workspaceName}) => ` to hear about important announcements related to ${workspaceName}`,
beginningOfChatHistoryAnnounceRoomPartOne: ({workspaceName}) => `Collaboration between all ${workspaceName} members starts here! 🎉\nUse `,
beginningOfChatHistoryAnnounceRoomPartTwo: ({workspaceName}) => ` to chat about anything ${workspaceName} related.`,
beginningOfChatHistoryUserRoomPartOne: 'Collaboration starts here! 🎉\nUse this space to chat about anything ',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ export default {
beginningOfChatHistoryDomainRoomPartTwo: ' para chatear con compañeros, compartir consejos o hacer una pregunta.',
beginningOfChatHistoryAdminRoomPartOne: ({workspaceName}) => `Este es el lugar para que los administradores de ${workspaceName} colaboren! 🎉\nUsa `,
beginningOfChatHistoryAdminRoomPartTwo: ' para chatear sobre temas como la configuración del espacio de trabajo y mas.',
beginningOfChatHistoryAdminOnlyPostingRoomPartOne: 'Utiliza ',
beginningOfChatHistoryAdminOnlyPostingRoomPartTwo: ({workspaceName}) => ` para enterarte de anuncios importantes relacionados con ${workspaceName}`,
beginningOfChatHistoryAnnounceRoomPartOne: ({workspaceName}) => `Este es el lugar para que todos los miembros de ${workspaceName} colaboren! 🎉\nUsa `,
beginningOfChatHistoryAnnounceRoomPartTwo: ({workspaceName}) => ` para chatear sobre cualquier cosa relacionada con ${workspaceName}.`,
beginningOfChatHistoryUserRoomPartOne: 'Este es el lugar para colaborar! 🎉\nUsa este espacio para chatear sobre cualquier cosa relacionada con ',
Expand Down
6 changes: 5 additions & 1 deletion src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ function getOptions(
includeThreads = false,
includeTasks = false,
includeMoneyRequests = false,
isShareDestination = false,
},
) {
if (!isPersonalDetailsReady(personalDetails)) {
Expand All @@ -650,7 +651,9 @@ function getOptions(
const searchValue = parsedPhoneNumber.possible ? parsedPhoneNumber.number.e164 : searchInputValue.toLowerCase();

// Filter out all the reports that shouldn't be displayed
const filteredReports = _.filter(reports, (report) => ReportUtils.shouldReportBeInOptionList(report, Navigation.getTopmostReportId(), false, iouReports, betas, policies));
const filteredReports = _.filter(reports, (report) =>
ReportUtils.shouldReportBeInOptionList(report, Navigation.getTopmostReportId(), false, iouReports, betas, policies, isShareDestination),
);
amyevans marked this conversation as resolved.
Show resolved Hide resolved

// Sorting the reports works like this:
// - Order everything by the last message timestamp (descending)
Expand Down Expand Up @@ -981,6 +984,7 @@ function getShareDestinationOptions(reports, personalDetails, betas = [], search
includePersonalDetails: true,
excludeLogins,
includeOwnedWorkspaceChats,
isShareDestination: true,
});
}

Expand Down
40 changes: 36 additions & 4 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,19 @@ function sortReportsByLastRead(reports) {
* - It's not pending deletion
*
* @param {Object} reportAction
* @param {String} reportID
* @returns {Boolean}
*/
function canEditReportAction(reportAction) {
function canEditReportAction(reportAction, reportID) {
return (
reportAction.actorAccountID === currentUserAccountID &&
reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT &&
!isReportMessageAttachment(lodashGet(reportAction, ['message', 0], {})) &&
!ReportActionsUtils.isDeletedAction(reportAction) &&
!ReportActionsUtils.isCreatedTaskReportAction(reportAction) &&
reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE
reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE &&
// eslint-disable-next-line no-use-before-define
isAllowedToComment(getReport(reportID))
amyevans marked this conversation as resolved.
Show resolved Hide resolved
);
}

Expand Down Expand Up @@ -246,7 +249,9 @@ function canDeleteReportAction(reportAction, reportID) {
reportAction.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ||
ReportActionsUtils.isCreatedTaskReportAction(reportAction) ||
(ReportActionsUtils.isMoneyRequestAction(reportAction) && isSettled(reportAction.originalMessage.IOUReportID)) ||
reportAction.actorAccountID === CONST.ACCOUNT_ID.CONCIERGE
reportAction.actorAccountID === CONST.ACCOUNT_ID.CONCIERGE ||
// eslint-disable-next-line no-use-before-define
!isAllowedToComment(getReport(reportID))
amyevans marked this conversation as resolved.
Show resolved Hide resolved
) {
return false;
}
Expand All @@ -268,6 +273,18 @@ function isAdminRoom(report) {
return getChatType(report) === CONST.REPORT.CHAT_TYPE.POLICY_ADMINS;
}

/**
* Whether the provided report is an Admin-only posting room
* @param {Object} report
* @param {String} report.writeCapability
* @returns {Boolean}
*/
function isAdminsOnlyPostingRoom(report) {
const writeCapability = lodashGet(report, 'writeCapability', CONST.REPORT.WRITE_CAPABILITIES.ALL);

return writeCapability === CONST.REPORT.WRITE_CAPABILITIES.ADMINS;
amyevans marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Whether the provided report is a Announce room
* @param {Object} report
Expand Down Expand Up @@ -646,6 +663,9 @@ function getRoomWelcomeMessage(report) {
} else if (isAdminRoom(report)) {
welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartOne', {workspaceName});
welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartTwo');
} else if (isAdminsOnlyPostingRoom(report)) {
welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminOnlyPostingRoomPartOne');
welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminOnlyPostingRoomPartTwo', {workspaceName});
} else if (isAnnounceRoom(report)) {
welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartOne', {workspaceName});
welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartTwo', {workspaceName});
Expand Down Expand Up @@ -1677,6 +1697,7 @@ function buildOptimisticTaskReportAction(taskReportID, actionName, message = '')
* @param {Boolean} isOwnPolicyExpenseChat
* @param {String} oldPolicyName
* @param {String} visibility
* @param {String} writeCapability
* @param {String} notificationPreference
* @param {String} parentReportActionID
* @param {String} parentReportID
Expand All @@ -1691,6 +1712,7 @@ function buildOptimisticChatReport(
isOwnPolicyExpenseChat = false,
oldPolicyName = '',
visibility = undefined,
writeCapability = CONST.REPORT.WRITE_CAPABILITIES.ALL,
notificationPreference = CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS,
parentReportActionID = '',
parentReportID = '',
Expand Down Expand Up @@ -1721,6 +1743,7 @@ function buildOptimisticChatReport(
statusNum: 0,
visibility,
welcomeMessage: '',
writeCapability,
};
}

Expand Down Expand Up @@ -2075,9 +2098,10 @@ function canAccessReport(report, policies, betas) {
* @param {Object} iouReports
* @param {String[]} betas
* @param {Object} policies
* @param {Boolean} isShareDestination
* @returns {boolean}
*/
function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, iouReports, betas, policies) {
function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, iouReports, betas, policies, isShareDestination = false) {
const isInDefaultMode = !isInGSDMode;

// Exclude reports that have no data because there wouldn't be anything to show in the option item.
Expand Down Expand Up @@ -2129,6 +2153,14 @@ function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, iouRep
return false;
}

// Exclude reports that are admin-only posting rooms, when the user tries to share something to the room,
// because, the user isn't an admin for a linked workspace.
if (isShareDestination && report.writeCapability === CONST.REPORT.WRITE_CAPABILITIES.ADMINS) {
const linkedWorkspace = _.find(policies, (policy) => policy && policy.id === report.policyID);

return lodashGet(linkedWorkspace, 'role', '') === CONST.POLICY.ROLE.ADMIN;
}

// Hide only chat threads that haven't been commented on (other threads are actionable)
if (isChatThread(report) && !report.lastMessageText) {
return false;
Expand Down
5 changes: 4 additions & 1 deletion src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -1263,8 +1263,9 @@ function navigateToConciergeChat() {
* @param {String} reportName
* @param {String} visibility
* @param {Array<Number>} policyMembersAccountIDs
* @param {String} writeCapability
*/
function addPolicyReport(policyID, reportName, visibility, policyMembersAccountIDs) {
function addPolicyReport(policyID, reportName, visibility, policyMembersAccountIDs, writeCapability) {
// The participants include the current user (admin), and for restricted rooms, the policy members. Participants must not be empty.
const members = visibility === CONST.REPORT.VISIBILITY.RESTRICTED ? policyMembersAccountIDs : [];
const participants = _.unique([currentUserAccountID, ...members]);
Expand All @@ -1277,6 +1278,7 @@ function addPolicyReport(policyID, reportName, visibility, policyMembersAccountI
false,
'',
visibility,
writeCapability,

// The room might contain all policy members so notifying always should be opt-in only.
CONST.REPORT.NOTIFICATION_PREFERENCE.DAILY,
Expand Down Expand Up @@ -1343,6 +1345,7 @@ function addPolicyReport(policyID, reportName, visibility, policyMembersAccountI
visibility,
reportID: policyReport.reportID,
createdReportActionID: createdReportAction.reportActionID,
writeCapability,
},
{optimisticData, successData, failureData},
);
Expand Down
9 changes: 6 additions & 3 deletions src/pages/home/report/ContextMenu/ContextMenuActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ export default [
successTextTranslateKey: '',
successIcon: null,
shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID) =>
type === CONTEXT_MENU_TYPES.REPORT_ACTION && reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT && !ReportUtils.isThreadFirstChat(reportAction, reportID),
type === CONTEXT_MENU_TYPES.REPORT_ACTION &&
reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT &&
!ReportUtils.isThreadFirstChat(reportAction, reportID) &&
ReportUtils.isAllowedToComment(ReportUtils.getReport(reportID)),
amyevans marked this conversation as resolved.
Show resolved Hide resolved
onPress: (closePopover, {reportAction, reportID}) => {
if (closePopover) {
hideContextMenu(false, () => {
Expand Down Expand Up @@ -267,8 +270,8 @@ export default [
isAnonymousAction: false,
textTranslateKey: 'reportActionContextMenu.editComment',
icon: Expensicons.Pencil,
shouldShow: (type, reportAction, isArchivedRoom, betas, menuTarget, isChronosReport) =>
type === CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canEditReportAction(reportAction) && !isArchivedRoom && !isChronosReport,
shouldShow: (type, reportAction, isArchivedRoom, betas, menuTarget, isChronosReport, reportID) =>
type === CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canEditReportAction(reportAction, reportID) && !isArchivedRoom && !isChronosReport,
onPress: (closePopover, {reportID, reportAction, draftMessage}) => {
const editAction = () => Report.saveReportActionDraft(reportID, reportAction.reportActionID, _.isEmpty(draftMessage) ? getActionText(reportAction) : '');

Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/report/ReportActionCompose.js
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ class ReportActionCompose extends React.Component {

const parentReportActionID = lodashGet(this.props.report, 'parentReportActionID', '');
const parentReportAction = lodashGet(this.props.parentReportActions, [parentReportActionID], {});
const lastReportAction = _.find([...this.props.reportActions, parentReportAction], (action) => ReportUtils.canEditReportAction(action));
const lastReportAction = _.find([...this.props.reportActions, parentReportAction], (action) => ReportUtils.canEditReportAction(action, this.props.reportID));

if (lastReportAction !== -1 && lastReportAction) {
Report.saveReportActionDraft(this.props.reportID, lastReportAction.reportActionID, _.last(lastReportAction.message).html);
Expand Down
7 changes: 6 additions & 1 deletion src/pages/home/report/ReportActionItemCreated.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ function ReportActionItemCreated(props) {

const icons = ReportUtils.getIcons(props.report, props.personalDetails);

const errors = lodashGet(props.report, 'errorFields.addWorkspaceRoom') || lodashGet(props.report, 'errorFields.createChat');
const isArchivedRoom = ReportUtils.isArchivedRoom(props.report);
const hideComposer = ReportUtils.shouldHideComposer(props.report, errors);
const shouldOmitBottomSpace = props.report.lastMessageText === '' && (isArchivedRoom || hideComposer);

return (
<OfflineWithFeedback
pendingAction={lodashGet(props.report, 'pendingFields.addWorkspaceRoom') || lodashGet(props.report, 'pendingFields.createChat')}
Expand All @@ -69,7 +74,7 @@ function ReportActionItemCreated(props) {
/>
<View
accessibilityLabel={props.translate('accessibilityHints.chatWelcomeMessage')}
style={[styles.p5, StyleUtils.getReportWelcomeTopMarginStyle(props.isSmallScreenWidth)]}
style={[styles.p5, shouldOmitBottomSpace && styles.pb0, StyleUtils.getReportWelcomeTopMarginStyle(props.isSmallScreenWidth)]}
amyevans marked this conversation as resolved.
Show resolved Hide resolved
>
<PressableWithoutFeedback
onPress={() => ReportUtils.navigateToDetailsPage(props.report)}
Expand Down
4 changes: 1 addition & 3 deletions src/pages/home/report/ReportFooter.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ function ReportFooter(props) {
/>
)}
{isArchivedRoom && <ArchivedReportFooter report={props.report} />}
{!props.isSmallScreenWidth && (
<View style={styles.offlineIndicatorRow}>{hideComposer && <OfflineIndicator containerStyles={[styles.chatItemComposeSecondaryRow]} />}</View>
)}
{!props.isSmallScreenWidth && <OfflineIndicator containerStyles={[styles.chatItemComposeSecondaryRow]} />}
amyevans marked this conversation as resolved.
Show resolved Hide resolved
</View>
)}
{!hideComposer && (props.shouldShowComposeInput || !props.isSmallScreenWidth) && (
Expand Down
21 changes: 19 additions & 2 deletions src/pages/workspace/WorkspaceNewRoomPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function WorkspaceNewRoomPage(props) {
*/
const submit = (values) => {
const policyMembers = _.map(_.keys(props.allPolicyMembers[`${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${values.policyID}`]), (accountID) => Number(accountID));
Report.addPolicyReport(values.policyID, values.roomName, values.visibility, policyMembers);
Report.addPolicyReport(values.policyID, values.roomName, values.visibility, policyMembers, values.writeCapability);
};

/**
Expand Down Expand Up @@ -116,6 +116,15 @@ function WorkspaceNewRoomPage(props) {
[props.policies],
);

const writeCapabilityOptions = useMemo(
() =>
_.map(CONST.REPORT.WRITE_CAPABILITIES, (value) => ({
value,
label: translate(`writeCapabilityPage.writeCapability.${value}`),
})),
[translate],
);

const visibilityOptions = useMemo(
() =>
_.map(
Expand Down Expand Up @@ -163,7 +172,15 @@ function WorkspaceNewRoomPage(props) {
shouldDelayFocus={shouldDelayFocus}
/>
</View>
<View style={styles.mb5}>
<View style={styles.mb2}>
<Picker
inputID="writeCapability"
label={translate('writeCapabilityPage.label')}
items={writeCapabilityOptions}
defaultValue={CONST.REPORT.WRITE_CAPABILITIES.ALL}
/>
amyevans marked this conversation as resolved.
Show resolved Hide resolved
</View>
<View style={styles.mb2}>
<Picker
inputID="policyID"
label={translate('workspace.common.workspace')}
Expand Down
4 changes: 0 additions & 4 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -811,10 +811,6 @@ const styles = {
paddingBottom: 5,
},

offlineIndicatorRow: {
height: 25,
},

// Actions
actionAvatar: {
borderRadius: 20,
Expand Down
Loading