Skip to content

Commit

Permalink
Merge pull request Expensify#33665 from ishpaul777/new-feat/actionabl…
Browse files Browse the repository at this point in the history
…e-whispers

New Feature: Create the UI for Actionable Mention Whispers
  • Loading branch information
jasperhuangg authored Jan 13, 2024
2 parents 744e35c + 5d42ef7 commit 753ce92
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ const CONST = {
TASKCOMPLETED: 'TASKCOMPLETED',
TASKEDITED: 'TASKEDITED',
TASKREOPENED: 'TASKREOPENED',
ACTIONABLEMENTIONWHISPER: 'ACTIONABLEMENTIONWHISPER',
POLICYCHANGELOG: {
ADD_APPROVER_RULE: 'POLICYCHANGELOG_ADD_APPROVER_RULE',
ADD_BUDGET: 'POLICYCHANGELOG_ADD_BUDGET',
Expand Down Expand Up @@ -600,6 +601,10 @@ const CONST = {
},
THREAD_DISABLED: ['CREATED'],
},
ACTIONABLE_MENTION_WHISPER_RESOLUTION: {
INVITE: 'invited',
NOTHING: 'nothing',
},
ARCHIVE_REASON: {
DEFAULT: 'default',
ACCOUNT_CLOSED: 'accountClosed',
Expand Down
42 changes: 42 additions & 0 deletions src/components/ReportActionItem/ActionableItemButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import {View} from 'react-native';
import Button from '@components/Button';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import type {TranslationPaths} from '@src/languages/types';

type ActionableItem = {
isPrimary?: boolean;
key: string;
onPress: () => void;
text: TranslationPaths;
};

type ActionableItemButtonsProps = {
items: ActionableItem[];
};

function ActionableItemButtons(props: ActionableItemButtonsProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();

return (
<View style={[styles.flexRow, styles.gap4]}>
{props.items?.map((item) => (
<Button
key={item.key}
style={[styles.mt2]}
onPress={item.onPress}
text={translate(item.text)}
small
success={item.isPrimary}
/>
))}
</View>
);
}

ActionableItemButtons.displayName = 'ActionableItemButtton';

export default ActionableItemButtons;
export type {ActionableItem};
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1966,6 +1966,10 @@ export default {
levelTwoResult: 'Message hidden from channel, plus anonymous warning and message is reported for review.',
levelThreeResult: 'Message removed from channel plus anonymous warning and message is reported for review.',
},
actionableMentionWhisperOptions: {
invite: 'Invite them',
nothing: 'Do nothing',
},
teachersUnitePage: {
teachersUnite: 'Teachers Unite',
joinExpensifyOrg: 'Join Expensify.org in eliminating injustice around the world and help teachers split their expenses for classrooms in need!',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,10 @@ export default {
copy: 'Copiar',
copied: '¡Copiado!',
},
actionableMentionWhisperOptions: {
invite: 'Invitar',
nothing: 'No hacer nada',
},
moderation: {
flagDescription: 'Todos los mensajes marcados se enviarán a un moderador para su revisión.',
chooseAReason: 'Elige abajo un motivo para reportarlo:',
Expand Down
57 changes: 57 additions & 0 deletions src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ function addActions(reportID: string, text = '', file?: File) {
reportComment?: string;
file?: File;
timezone?: string;
shouldAllowActionableMentionWhispers?: boolean;
clientCreatedTime?: string;
};

Expand All @@ -350,6 +351,7 @@ function addActions(reportID: string, text = '', file?: File) {
commentReportActionID: file && reportCommentAction ? reportCommentAction.reportActionID : null,
reportComment: reportCommentText,
file,
shouldAllowActionableMentionWhispers: true,
clientCreatedTime: file ? attachmentAction?.created : reportCommentAction?.created,
};

Expand Down Expand Up @@ -2585,6 +2587,60 @@ function clearNewRoomFormError() {
});
}

function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEntry<ReportAction>, resolution: ValueOf<typeof CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION>) {
const message = reportAction?.message?.[0];
if (!message) {
return;
}

const updatedMessage: Message = {
...message,
resolution,
};

const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportId}`,
value: {
[reportAction.reportActionID]: {
message: [updatedMessage],
originalMessage: {
resolution,
},
},
},
},
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportId}`,
value: {
[reportAction.reportActionID]: {
message: [message],
originalMessage: {
resolution: null,
},
},
},
},
];

type ResolveActionableMentionWhisperParams = {
reportActionID: string;
resolution: ValueOf<typeof CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION>;
};

const parameters: ResolveActionableMentionWhisperParams = {
reportActionID: reportAction.reportActionID,
resolution,
};

API.write('ResolveActionableMentionWhisper', parameters, {optimisticData, failureData});
}

export {
searchInServer,
addComment,
Expand Down Expand Up @@ -2649,4 +2705,5 @@ export {
getDraftPrivateNote,
updateLastVisitTime,
clearNewRoomFormError,
resolveActionableMentionWhisper,
};
31 changes: 31 additions & 0 deletions src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import PressableWithSecondaryInteraction from '@components/PressableWithSecondar
import EmojiReactionsPropTypes from '@components/Reactions/EmojiReactionsPropTypes';
import ReportActionItemEmojiReactions from '@components/Reactions/ReportActionItemEmojiReactions';
import RenderHTML from '@components/RenderHTML';
import ActionableItemButtons from '@components/ReportActionItem/ActionableItemButtons';
import ChronosOOOListActions from '@components/ReportActionItem/ChronosOOOListActions';
import MoneyReportView from '@components/ReportActionItem/MoneyReportView';
import MoneyRequestAction from '@components/ReportActionItem/MoneyRequestAction';
Expand Down Expand Up @@ -305,6 +306,25 @@ function ReportActionItem(props) {
[props.report, props.action, toggleContextMenuFromActiveReportAction],
);

const actionableItemButtons = useMemo(() => {
if (!(props.action.actionName === CONST.REPORT.ACTIONS.TYPE.ACTIONABLEMENTIONWHISPER && !lodashGet(props.action, 'originalMessage.resolution', null))) {
return [];
}
return [
{
text: 'actionableMentionWhisperOptions.invite',
key: `${props.action.reportActionID}-actionableMentionWhisper-${CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION.INVITE}`,
onPress: () => Report.resolveActionableMentionWhisper(props.report.reportID, props.action, CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION.INVITE),
isPrimary: true,
},
{
text: 'actionableMentionWhisperOptions.nothing',
key: `${props.action.reportActionID}-actionableMentionWhisper-${CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION.NOTHING}`,
onPress: () => Report.resolveActionableMentionWhisper(props.report.reportID, props.action, CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION.NOTHING),
},
];
}, [props.action, props.report]);

/**
* Get the content of ReportActionItem
* @param {Boolean} hovered whether the ReportActionItem is hovered
Expand Down Expand Up @@ -467,6 +487,17 @@ function ReportActionItem(props) {
</Text>
</Button>
)}
{/**
These are the actionable buttons that appear at the bottom of a Concierge message
for example: Invite a user mentioned but not a member of the room
https://github.com/Expensify/App/issues/32741
*/}
{actionableItemButtons.length > 0 && (
<ActionableItemButtons
action={props.action}
items={actionableItemButtons}
/>
)}
</View>
) : (
<ReportActionItemMessageEdit
Expand Down
14 changes: 14 additions & 0 deletions src/types/onyx/OriginalMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type OriginalMessageActionName =
| 'TASKCOMPLETED'
| 'TASKEDITED'
| 'TASKREOPENED'
| 'ACTIONABLEMENTIONWHISPER'
| ValueOf<typeof CONST.REPORT.ACTIONS.TYPE.POLICYCHANGELOG>;
type OriginalMessageApproved = {
actionName: typeof CONST.REPORT.ACTIONS.TYPE.APPROVED;
Expand Down Expand Up @@ -109,6 +110,18 @@ type OriginalMessageAddComment = {
};
};

type OriginalMessageActionableMentionWhisper = {
actionName: typeof CONST.REPORT.ACTIONS.TYPE.ACTIONABLEMENTIONWHISPER;
originalMessage: {
inviteeAccountIDs: number[];
inviteeEmails: string;
lastModified: string;
reportID: number;
resolution?: ValueOf<typeof CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION> | null;
whisperedTo?: number[];
};
};

type OriginalMessageSubmitted = {
actionName: typeof CONST.REPORT.ACTIONS.TYPE.SUBMITTED;
originalMessage: unknown;
Expand Down Expand Up @@ -239,6 +252,7 @@ type OriginalMessage =
| OriginalMessageApproved
| OriginalMessageIOU
| OriginalMessageAddComment
| OriginalMessageActionableMentionWhisper
| OriginalMessageSubmitted
| OriginalMessageClosed
| OriginalMessageCreated
Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/ReportAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ type Message = {

/** ID of a task report */
taskReportID?: string;

/** resolution for actionable mention whisper */
resolution?: ValueOf<typeof CONST.REPORT.ACTIONABLE_MENTION_WHISPER_RESOLUTION> | null;
};

type ImageMetadata = {
Expand Down

0 comments on commit 753ce92

Please sign in to comment.