Repository navigation
[Payment due @linhvovan29546] Create company agents #103817
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
Changes from all commits
1c1378f
04bc2f9
aef8001
57b0b89
ecad0f3
f8e5ab7
757af65
2c460a5
468b669
f076477
1dc4f7b
adc4142
41228ff
a06455f
a4df129
81c9619
13d80dd
5e37f69
cf1216e
ce2b810
d21c357
eff60be
0823caf
5f364fc
2147496
51b9673
4cb63cb
51205aa
35c6e6f
7477ca6
8894017
bd073da
bb85352
43ba2f5
50f46cb
f02a68a
37eae1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; | ||
|
|
||
| import type CONST from '@src/CONST'; | ||
|
|
||
| import type {ValueOf} from 'type-fest'; | ||
|
|
||
| type CreateCompanyAgentParams = { | ||
| prompt: string; | ||
| policyID: string; | ||
| role: ValueOf<typeof CONST.POLICY.ROLE>; | ||
| firstName?: string; | ||
| customExpensifyAvatarID?: string; | ||
| file?: File | CustomRNImageManipulatorResult; | ||
| optimisticAccountID: number; | ||
| optimisticReportID: string; | ||
| createdReportActionID: string; | ||
| }; | ||
|
|
||
| export default CreateCompanyAgentParams; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ import type PolicyEmployee from '@src/types/onyx/PolicyEmployee'; | |
| import type {AnyOnyxUpdate} from '@src/types/onyx/Request'; | ||
|
|
||
| import type {OnyxCollection, OnyxCollectionInputValue, OnyxUpdate} from 'react-native-onyx'; | ||
| import type {ValueOf} from 'type-fest'; | ||
|
|
||
| import Onyx from 'react-native-onyx'; | ||
|
|
||
|
|
@@ -40,15 +41,14 @@ function openProfilePage() { | |
| read(READ_COMMANDS.OPEN_PROFILE_PAGE, null); | ||
| } | ||
|
|
||
| function createAgent( | ||
| firstName: string | undefined, | ||
| function prepareNewAgentOnyxData( | ||
| currentUserAccountID: number, | ||
| currentUserLogin: string | undefined, | ||
| prompt: string, | ||
| ownerAccountID: number, | ||
| ownerLogin: string | undefined, | ||
| policy?: Policy, | ||
| firstName?: string, | ||
| customExpensifyAvatarID?: string, | ||
| file?: File | CustomRNImageManipulatorResult, | ||
| optimisticAvatarURI?: string, | ||
| policyID?: string, | ||
| ) { | ||
| const optimisticAccountID = Number(generateReportID()); | ||
|
|
||
|
|
@@ -59,7 +59,7 @@ function createAgent( | |
| avatarURI = optimisticAvatarURI; | ||
| } | ||
|
|
||
| // Optimistic row for Settings > Agents until CREATE_AGENT responds. Omit `login` (server-assigned). | ||
| // Optimistic row for Settings > Agents until BE responds. Omit `login` (server-assigned). | ||
| const optimisticPersonalDetail = { | ||
| accountID: optimisticAccountID, | ||
| displayName: firstName, | ||
|
|
@@ -71,24 +71,29 @@ function createAgent( | |
| // Generate the DM report ID client-side so it can be written to Onyx and opened immediately. | ||
| const optimisticReportID = generateReportID(); | ||
| const optimisticChatReport = buildOptimisticChatReport({ | ||
| participantList: [ownerAccountID, optimisticAccountID], | ||
| ownerAccountID, | ||
| participantList: [currentUserAccountID, optimisticAccountID], | ||
| ownerAccountID: currentUserAccountID, | ||
| optimisticReportID, | ||
| currentUserAccountID: ownerAccountID, | ||
| currentUserAccountID, | ||
| }); | ||
|
|
||
| // Reuse the client-generated CREATED action ID when CreateAgent creates the DM. | ||
| const createdReportActionID = rand64(); | ||
| const optimisticCreatedAction = buildOptimisticCreatedReportAction({ | ||
| emailCreatingAction: ownerLogin ?? CONST.REPORT.OWNER_EMAIL_FAKE, | ||
| currentUserAccountID: ownerAccountID, | ||
| emailCreatingAction: currentUserLogin ?? CONST.REPORT.OWNER_EMAIL_FAKE, | ||
| currentUserAccountID, | ||
| optimisticReportActionID: createdReportActionID, | ||
| }); | ||
|
|
||
| const optimisticData: AnyOnyxUpdate[] = [ | ||
| { | ||
| onyxMethod: Onyx.METHOD.MERGE, | ||
| key: `${ONYXKEYS.COLLECTION.AGENT}${optimisticAccountID}`, | ||
| value: {prompt, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, | ||
| value: { | ||
| prompt, | ||
| ownerAccountID: policy?.policyAccountID, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The optimistic data for company agents looks incomplete, so the offline state doesn't match what the server returns. I reproduced two problems on web: 1. Role and Owner columns are empty offline
Once back online, the role and owner both fill in correctly. 2. The agent is missing entirely in a workspace created offline
Once back online, For reference, the server response for // agent
value: {
prompt,
ownerAccountID: policy?.policyAccountID,
ownerType: policy ? CONST.AGENTS.OWNER_TYPE.WORKSPACE : CONST.AGENTS.OWNER_TYPE.PERSON,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
},
// policy: employeeList entry with `role` + `pendingAction: ADD`The The PR's offline steps are "Same as Tests", and step 4 ("Verify the agent is added to the workspace with the chosen role") can't pass offline as it stands.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The agent email is not predictable 100% thus the missing employee entry and with that entry missing I had to put |
||
| pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, | ||
| }, | ||
| }, | ||
| { | ||
| onyxMethod: Onyx.METHOD.SET, | ||
|
|
@@ -128,8 +133,6 @@ function createAgent( | |
| onyxMethod: Onyx.METHOD.MERGE, | ||
| key: `${ONYXKEYS.COLLECTION.AGENT}${optimisticAccountID}`, | ||
| value: { | ||
| prompt, | ||
| pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, | ||
| errors: getMicroSecondOnyxErrorWithTranslationKey('agentsPage.error.genericAdd'), | ||
| }, | ||
| }, | ||
|
|
@@ -150,11 +153,63 @@ function createAgent( | |
| }, | ||
| ]; | ||
|
|
||
| return {optimisticData, successData, failureData, optimisticAccountID, avatarURI, optimisticReportID, createdReportActionID, optimisticPersonalDetailPromise}; | ||
| } | ||
|
|
||
| function createAgent( | ||
| firstName: string | undefined, | ||
| prompt: string, | ||
| currentUserAccountID: number, | ||
| currentUserLogin: string | undefined, | ||
| customExpensifyAvatarID?: string, | ||
| file?: File | CustomRNImageManipulatorResult, | ||
| optimisticAvatarURI?: string, | ||
| ) { | ||
| const {optimisticData, successData, failureData, optimisticAccountID, avatarURI, optimisticReportID, createdReportActionID, optimisticPersonalDetailPromise} = prepareNewAgentOnyxData( | ||
| currentUserAccountID, | ||
| currentUserLogin, | ||
| prompt, | ||
| undefined, | ||
| firstName, | ||
| customExpensifyAvatarID, | ||
| optimisticAvatarURI, | ||
| ); | ||
|
|
||
| write( | ||
| // Flag this as the user's personal agent; the backend makes personal agents a full co-pilot of the creator. | ||
| // optimisticReportID is the owner<->agent DM's optimistic reportID; CreateAgent creates the DM under this exact ID. | ||
| WRITE_COMMANDS.CREATE_AGENT, | ||
| {firstName, prompt, customExpensifyAvatarID, file, policyID, optimisticAccountID: String(optimisticAccountID), isPersonalAgent: true, optimisticReportID, createdReportActionID}, | ||
| {firstName, prompt, customExpensifyAvatarID, file, optimisticAccountID: String(optimisticAccountID), isPersonalAgent: true, optimisticReportID, createdReportActionID}, | ||
| {optimisticData, successData, failureData}, | ||
| ); | ||
|
|
||
| return {optimisticAccountID, avatarURI, optimisticReportID, optimisticPersonalDetailPromise}; | ||
| } | ||
|
|
||
| function createCompanyAgent( | ||
| currentUserAccountID: number, | ||
| currentUserLogin: string | undefined, | ||
| prompt: string, | ||
| policy: Policy, | ||
| role: ValueOf<typeof CONST.POLICY.ROLE>, | ||
| firstName?: string, | ||
| customExpensifyAvatarID?: string, | ||
| file?: File | CustomRNImageManipulatorResult, | ||
| optimisticAvatarURI?: string, | ||
| ) { | ||
| const {optimisticData, successData, failureData, optimisticAccountID, avatarURI, optimisticReportID, createdReportActionID, optimisticPersonalDetailPromise} = prepareNewAgentOnyxData( | ||
| currentUserAccountID, | ||
| currentUserLogin, | ||
| prompt, | ||
| policy, | ||
| firstName, | ||
| customExpensifyAvatarID, | ||
| optimisticAvatarURI, | ||
| ); | ||
|
|
||
| write( | ||
| WRITE_COMMANDS.CREATE_COMPANY_AGENT, | ||
| {prompt, policyID: policy.id, role, firstName, customExpensifyAvatarID, file, optimisticAccountID, optimisticReportID, createdReportActionID}, | ||
| {optimisticData, successData, failureData}, | ||
| ); | ||
|
|
||
|
|
@@ -433,6 +488,7 @@ export { | |
| openAgentsPage, | ||
| openProfilePage, | ||
| createAgent, | ||
| createCompanyAgent, | ||
| setNewAgentTemplate, | ||
| clearNewAgentTemplate, | ||
| clearAgentError, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.