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
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,8 @@
"ukkonen",
"unapprove",
"unapproves",
"unarchived",
"unarchiving",
"unassigning",
"unassignment",
"unbaselined",
Expand Down
1 change: 1 addition & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4530,6 +4530,7 @@ const CONST = {
THREE_DOT_MENU_ACTION: {
LEAVE: 'leave',
TRANSFER_OWNERSHIP: 'transferOwnership',
UNARCHIVE: 'unarchive',
},
POLICY_FEATURE: {
OVERVIEW: 'overview',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {clearCopyPolicySettings} from '@libs/actions/Policy/CopyPolicySettings';
import {callFunctionIfActionIsAllowed} from '@libs/actions/Session';
import Navigation from '@libs/Navigation/Navigation';
import {canUnarchivePolicy} from '@libs/PolicyUtils';
import shouldRenderTransferOwnerButton from '@libs/shouldRenderTransferOwnerButton';

import UnarchiveWorkspaceFlow from '@pages/workspace/archiveWorkspace/UnarchiveWorkspaceFlow';

import {setNameValuePair} from '@userActions/User';

import CONST from '@src/CONST';
Expand Down Expand Up @@ -59,7 +62,7 @@ function WorkspaceRowThreeDotsMenu({item, onDeleteWorkspace, onArchiveWorkspace,
const isFocused = useIsFocused();
const {translate} = useLocalize();
const {isBetaEnabled} = usePermissions();
const icons = useMemoizedLazyExpensifyIcons(['Box', 'Building', 'Exit', 'Plus', 'Copy', 'Star', 'Trashcan', 'Transfer']);
const icons = useMemoizedLazyExpensifyIcons(['ArrowCircleClockwise', 'Box', 'Building', 'Exit', 'Plus', 'Copy', 'Star', 'Trashcan', 'Transfer']);
const canArchivePolicies = isBetaEnabled(CONST.BETAS.ARCHIVE_POLICIES);
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID);
Expand Down Expand Up @@ -170,6 +173,15 @@ function WorkspaceRowThreeDotsMenu({item, onDeleteWorkspace, onArchiveWorkspace,
}
}

if (canUnarchivePolicy(item.isArchived, item.ownerAccountID, currentUserPersonalDetails.accountID, canArchivePolicies)) {
menuItems.push({
icon: icons.ArrowCircleClockwise,
text: translate('workspace.common.unarchive'),
onSelected: callFunctionIfActionIsAllowed(() => setActiveAction(CONST.POLICY.THREE_DOT_MENU_ACTION.UNARCHIVE)),
shouldCallAfterModalHide: true,
});
}

// Transferring ownership applies to both active and archived workspaces, so it lives outside the split above.
if (isAdmin && !isOwner && canRenderTransferOwnerButton) {
menuItems.push({
Expand Down Expand Up @@ -200,6 +212,12 @@ function WorkspaceRowThreeDotsMenu({item, onDeleteWorkspace, onArchiveWorkspace,
onDismiss={() => setActiveAction(undefined)}
/>
)}
{activeAction === CONST.POLICY.THREE_DOT_MENU_ACTION.UNARCHIVE && (
<UnarchiveWorkspaceFlow
policyID={item.policyID}
onDismiss={() => setActiveAction(undefined)}
/>
)}
{activeAction === CONST.POLICY.THREE_DOT_MENU_ACTION.TRANSFER_OWNERSHIP && (
<TransferOwnershipFlow
policyID={item.policyID}
Expand Down
3 changes: 3 additions & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4788,6 +4788,9 @@ ${amount} für ${merchant} – ${date}`,
'Möchten Sie diesen Workspace wirklich archivieren? Dadurch werden allen Benutzern die Kreditkarten entzogen und alle nicht eingereichten Kartenausgaben endgültig gelöscht.',
archiveWithExpensifyCardsConfirmation:
'Möchten Sie diesen Workspace wirklich archivieren? Dadurch werden alle Expensify Card-Limits auf 0 $ gesetzt und neue Kaufversuche automatisch abgelehnt.',
unarchive: 'Wiederherstellen',
unarchiveWorkspace: 'Workspace wiederherstellen',
unarchiveConfirmation: 'Möchtest du diesen Workspace wirklich aus dem Archiv wiederherstellen?',
deleteWorkspaceTitle: (workspaceName: string) => `${workspaceName} löschen?`,
deleteConfirmation: 'Möchten Sie diesen Workspace wirklich löschen?',
deleteWithCardsConfirmation: 'Möchtest du diesen Workspace wirklich löschen? Dadurch werden alle Kartenfeeds und zugewiesenen Karten entfernt.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/el.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4856,6 +4856,9 @@ ${amount} για ${merchant} - ${date}`,
'Είστε βέβαιοι ότι θέλετε να αρχειοθετήσετε αυτόν τον χώρο εργασίας; Θα καταργηθεί η ανάθεση όλων των πιστωτικών καρτών από τους χρήστες και θα διαγραφούν οριστικά όσες δαπάνες καρτών δεν έχουν υποβληθεί.',
archiveWithExpensifyCardsConfirmation:
'Είστε βέβαιοι ότι θέλετε να αρχειοθετήσετε αυτόν τον χώρο εργασίας; Όλα τα όρια των Expensify Card θα οριστούν σε $0 και κάθε νέα απόπειρα αγοράς θα απορρίπτεται αυτόματα.',
unarchive: 'Αναίρεση αρχειοθέτησης',
unarchiveWorkspace: 'Αναίρεση αρχειοθέτησης χώρου εργασίας',
unarchiveConfirmation: 'Είστε βέβαιοι ότι θέλετε να αναιρέσετε την αρχειοθέτηση αυτού του χώρου εργασίας;',
deleteWorkspaceTitle: (workspaceName: string) => `Διαγραφή του ${workspaceName};`,
deleteConfirmation: 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτόν τον χώρο εργασίας;',
deleteWithCardsConfirmation: 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτόν τον χώρο εργασίας; Θα αφαιρεθούν όλες οι ροές καρτών και οι ανατεθειμένες κάρτες.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4962,6 +4962,9 @@ const translations = {
'Are you sure you want to archive this workspace? This will unassign all credit cards from users and permanently delete any unsubmitted card expenses.',
archiveWithExpensifyCardsConfirmation:
'Are you sure you want to archive this workspace? This will set all Expensify Card limits to $0 and automatically decline any new purchase attempts.',
unarchive: 'Unarchive',
unarchiveWorkspace: 'Unarchive workspace',
unarchiveConfirmation: 'Are you sure you want to unarchive this workspace?',
deleteWorkspaceTitle: (workspaceName: string) => `Delete ${workspaceName}?`,
deleteConfirmation: 'Are you sure you want to delete this workspace?',
deleteWithCardsConfirmation: 'Are you sure you want to delete this workspace? This will remove all card feeds and assigned cards.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4712,6 +4712,9 @@ ${amount} para ${merchant} - ${date}`,
'¿Estás seguro de que quieres archivar este espacio de trabajo? Se desasignarán todas las tarjetas de crédito de los usuarios y se eliminarán permanentemente los gastos de tarjeta no enviados.',
archiveWithExpensifyCardsConfirmation:
'¿Estás seguro de que quieres archivar este espacio de trabajo? Se establecerán todos los límites de las Tarjetas Expensify a $0 y se rechazarán automáticamente los nuevos intentos de compra.',
unarchive: 'Desarchivar',
unarchiveWorkspace: 'Desarchivar espacio de trabajo',
unarchiveConfirmation: '¿Estás seguro de que quieres desarchivar este espacio de trabajo?',
deleteWorkspaceTitle: (workspaceName: string) => `¿Eliminar ${workspaceName}?`,
deleteConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo?',
deleteWithCardsConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo? Se eliminarán todos los datos de las tarjetas y las tarjetas asignadas.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4795,6 +4795,9 @@ ${amount} pour ${merchant} - ${date}`,
'Voulez-vous vraiment archiver cet espace de travail ? Cela désassignera toutes les cartes de crédit des utilisateurs et supprimera définitivement toutes les dépenses de carte non soumises.',
archiveWithExpensifyCardsConfirmation:
'Voulez-vous vraiment archiver cet espace de travail ? Cela fixera toutes les limites des Expensify Card à 0 $ et refusera automatiquement toute nouvelle tentative d’achat.',
unarchive: 'Désarchiver',
unarchiveWorkspace: 'Désarchiver l’espace de travail',
unarchiveConfirmation: 'Voulez-vous vraiment désarchiver cet espace de travail ?',
deleteWorkspaceTitle: (workspaceName: string) => `Supprimer ${workspaceName} ?`,
deleteConfirmation: 'Voulez-vous vraiment supprimer cet espace de travail ?',
deleteWithCardsConfirmation: 'Voulez-vous vraiment supprimer cet espace de travail ? Cela supprimera tous les flux de cartes et les cartes assignées.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4758,6 +4758,9 @@ ${amount} per ${merchant} - ${date}`,
'Sei sicuro di voler archiviare questo spazio di lavoro? Questa azione annullerà l’assegnazione di tutte le carte di credito agli utenti ed eliminerà definitivamente le spese con carta non inviate.',
archiveWithExpensifyCardsConfirmation:
'Sei sicuro di voler archiviare questo spazio di lavoro? Questa azione imposterà tutti i limiti delle Expensify Card a 0 $ e rifiuterà automaticamente qualsiasi nuovo tentativo di acquisto.',
unarchive: 'Ripristina dall’archivio',
unarchiveWorkspace: 'Ripristina spazio di lavoro dall’archivio',
unarchiveConfirmation: 'Sei sicuro di voler ripristinare questo spazio di lavoro dall’archivio?',
deleteWorkspaceTitle: (workspaceName: string) => `Eliminare ${workspaceName}?`,
deleteConfirmation: 'Sei sicuro di voler eliminare questo spazio di lavoro?',
deleteWithCardsConfirmation: 'Sei sicuro di voler eliminare questo spazio di lavoro? Questa azione rimuoverà tutti i feed delle carte e le carte assegnate.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4723,6 +4723,9 @@ ${integrationName === CONST.ONBOARDING_ACCOUNTING_MAPPING.other ? 'あなたの'
'このワークスペースをアーカイブしてもよろしいですか? すべてのクレジットカードのユーザーへの割り当てが解除され、未申請のカード経費は完全に削除されます。',
archiveWithExpensifyCardsConfirmation:
'このワークスペースをアーカイブしてもよろしいですか? すべての Expensify カードの利用限度額が $0 に設定され、新しい購入はすべて自動的に拒否されます。',
unarchive: 'アーカイブ解除',
unarchiveWorkspace: 'ワークスペースのアーカイブを解除',
unarchiveConfirmation: 'このワークスペースのアーカイブを解除してもよろしいですか?',
deleteWorkspaceTitle: (workspaceName: string) => `${workspaceName} を削除しますか?`,
deleteConfirmation: 'このワークスペースを削除してもよろしいですか?',
deleteWithCardsConfirmation: 'このワークスペースを削除してもよろしいですか? すべてのカードフィードと割り当て済みカードが削除されます。',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4759,6 +4759,9 @@ ${amount} voor ${merchant} - ${date}`,
'Weet je zeker dat je deze werkruimte wilt archiveren? Hiermee worden alle creditcards van gebruikers losgekoppeld en worden alle niet-ingediende kaartuitgaven permanent verwijderd.',
archiveWithExpensifyCardsConfirmation:
'Weet je zeker dat je deze werkruimte wilt archiveren? Hiermee worden alle Expensify Card-limieten op $0 gezet en worden nieuwe aankooppogingen automatisch geweigerd.',
unarchive: 'Dearchiveren',
unarchiveWorkspace: 'Werkruimte dearchiveren',
unarchiveConfirmation: 'Weet je zeker dat je deze werkruimte wilt dearchiveren?',
deleteWorkspaceTitle: (workspaceName: string) => `${workspaceName} verwijderen?`,
deleteConfirmation: 'Weet je zeker dat je deze werkruimte wilt verwijderen?',
deleteWithCardsConfirmation: 'Weet je zeker dat je deze werkruimte wilt verwijderen? Hiermee worden alle kaartfeeds en toegewezen kaarten verwijderd.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4788,6 +4788,9 @@ ${amount} dla ${merchant} - ${date}`,
'Czy na pewno chcesz zarchiwizować tę przestrzeń roboczą? Spowoduje to anulowanie przypisania wszystkich kart kredytowych użytkownikom i trwałe usunięcie nieprzesłanych wydatków z kart.',
archiveWithExpensifyCardsConfirmation:
'Czy na pewno chcesz zarchiwizować tę przestrzeń roboczą? Spowoduje to ustawienie wszystkich limitów Expensify Card na $0 i automatyczne odrzucanie nowych prób zakupu.',
unarchive: 'Przywróć z archiwum',
unarchiveWorkspace: 'Przywróć przestrzeń roboczą z archiwum',
unarchiveConfirmation: 'Czy na pewno chcesz przywrócić tę przestrzeń roboczą z archiwum?',
deleteWorkspaceTitle: (workspaceName: string) => `Usunąć ${workspaceName}?`,
deleteConfirmation: 'Czy na pewno chcesz usunąć tę przestrzeń roboczą?',
deleteWithCardsConfirmation: 'Na pewno chcesz usunąć tę przestrzeń roboczą? Spowoduje to usunięcie wszystkich źródeł kart i przypisanych kart.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4751,6 +4751,9 @@ ${amount} para ${merchant} - ${date}`,
'Tem certeza de que deseja arquivar este workspace? Isso removerá a atribuição de todos os cartões de crédito dos usuários e excluirá permanentemente as despesas de cartão não enviadas.',
archiveWithExpensifyCardsConfirmation:
'Tem certeza de que deseja arquivar este workspace? Isso definirá todos os limites do Expensify Card como $0 e recusará automaticamente novas tentativas de compra.',
unarchive: 'Desarquivar',
unarchiveWorkspace: 'Desarquivar espaço de trabalho',
unarchiveConfirmation: 'Tem certeza de que deseja desarquivar este espaço de trabalho?',
deleteWorkspaceTitle: (workspaceName: string) => `Excluir ${workspaceName}?`,
deleteConfirmation: 'Tem certeza de que deseja excluir este workspace?',
deleteWithCardsConfirmation: 'Tem certeza de que deseja excluir este workspace? Isso removerá todos os feeds de cartão e cartões atribuídos.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4613,6 +4613,9 @@ ${amount},商户:${merchant} - 日期:${date}`,
archiveConfirmation: '确定要归档此工作区吗?',
archiveWithThirdPartyCardsConfirmation: '确定要归档此工作区吗?这将取消所有用户的信用卡分配,并永久删除所有未提交的卡片报销。',
archiveWithExpensifyCardsConfirmation: '确定要归档此工作区吗?这将把所有 Expensify 卡的限额设为 $0,并自动拒绝任何新的消费尝试。',
unarchive: '取消归档',
unarchiveWorkspace: '取消归档工作区',
unarchiveConfirmation: '确定要取消归档此工作区吗?',
deleteWorkspaceTitle: (workspaceName: string) => `删除 ${workspaceName}?`,
deleteConfirmation: '确定要删除此工作区吗?',
deleteWithCardsConfirmation: '确定要删除此工作区吗?这将移除所有卡片数据源和已分配的卡片。',
Expand Down
5 changes: 5 additions & 0 deletions src/libs/API/parameters/UnarchivePolicyParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type UnarchivePolicyParams = {
policyID: string;
};

export default UnarchivePolicyParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ export type {default as ChronosRemoveOOOEventParams} from './ChronosRemoveOOOEve
export type {default as TransferWalletBalanceParams} from './TransferWalletBalanceParams';
export type {default as DeleteWorkspaceParams} from './DeleteWorkspaceParams';
export type {default as ArchivePolicyParams} from './ArchivePolicyParams';
export type {default as UnarchivePolicyParams} from './UnarchivePolicyParams';
export type {default as ShareBankAccountAndSetPayerParams} from './ShareBankAccountAndSetPayerParams';
export type {default as CreateWorkspaceParams} from './CreateWorkspaceParams';
export type {default as UpdateWorkspaceGeneralSettingsParams} from './UpdateWorkspaceGeneralSettingsParams';
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ const WRITE_COMMANDS = {
RESOLVE_ACTIONABLE_REPORT_MENTION_WHISPER: 'ResolveActionableReportMentionWhisper',
DELETE_WORKSPACE: 'DeleteWorkspace',
ARCHIVE_POLICY: 'ArchivePolicy',
UNARCHIVE_POLICY: 'UnarchivePolicy',
DELETE_MEMBERS_FROM_WORKSPACE: 'DeleteMembersFromWorkspace',
ADD_MEMBERS_TO_WORKSPACE: 'AddMembersToWorkspace',
UPDATE_WORKSPACE_AVATAR: 'UpdateWorkspaceAvatar',
Expand Down Expand Up @@ -901,6 +902,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.TRANSFER_WALLET_BALANCE]: Parameters.TransferWalletBalanceParams;
[WRITE_COMMANDS.DELETE_WORKSPACE]: Parameters.DeleteWorkspaceParams;
[WRITE_COMMANDS.ARCHIVE_POLICY]: Parameters.ArchivePolicyParams;
[WRITE_COMMANDS.UNARCHIVE_POLICY]: Parameters.UnarchivePolicyParams;
[WRITE_COMMANDS.DELETE_MEMBERS_FROM_WORKSPACE]: Parameters.DeleteMembersFromWorkspaceParams;
[WRITE_COMMANDS.ADD_MEMBERS_TO_WORKSPACE]: Parameters.AddMembersToWorkspaceParams;
[WRITE_COMMANDS.UPDATE_WORKSPACE_AVATAR]: Parameters.UpdateWorkspaceAvatarParams;
Expand Down
9 changes: 9 additions & 0 deletions src/libs/PolicyUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ function isArchivedPolicy(policy: OnyxInputOrEntry<Policy>): boolean {
return !!policy?.archivedDate;
}

/**
* Whether the current user can unarchive the workspace: only the owner of an archived workspace can, and only
* while the archive policies beta is enabled. Takes primitives so it works with both a Policy and a workspace row.
*/
function canUnarchivePolicy(isArchived: boolean, ownerAccountID: number | undefined, currentUserAccountID: number, isArchivePoliciesBetaEnabled: boolean): boolean {
return isArchivePoliciesBetaEnabled && isArchived && ownerAccountID === currentUserAccountID;
}

/**
* Whether the policy is archived or is optimistically pending deletion. Deleting a workspace
* archives it on the backend, but the optimistic data only sets pendingAction, so report state
Expand Down Expand Up @@ -2831,6 +2839,7 @@ export {
isPolicyFieldListEmpty,
isArchivedOrPendingDeletePolicy,
isArchivedPolicy,
canUnarchivePolicy,
getUberConnectionErrorDirectlyFromPolicy,
isPolicyOwner,
isPolicyMember,
Expand Down
Loading
Loading