diff --git a/.changeset/popular-months-bow.md b/.changeset/popular-months-bow.md new file mode 100644 index 0000000000..05511e08ee --- /dev/null +++ b/.changeset/popular-months-bow.md @@ -0,0 +1,5 @@ +--- +"@tokens-studio/figma-plugin": patch +--- + +Improved recovery dialog button labels to be more explicit. The "Use remote" action (which discards local changes) is now the primary action with danger styling, while "Recover changes" (which keeps local changes) is the secondary cancel action. This makes it clearer which action is destructive. diff --git a/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/__tests__/pullTokensFactory.test.ts b/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/__tests__/pullTokensFactory.test.ts index 1bdfa480ec..db36957ecb 100644 --- a/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/__tests__/pullTokensFactory.test.ts +++ b/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/__tests__/pullTokensFactory.test.ts @@ -308,7 +308,7 @@ describe('pullTokensFactory', () => { ], } as unknown as StartupMessage; - mockConfirm.mockResolvedValueOnce(true); + mockConfirm.mockResolvedValueOnce(false); const fn = pullTokensFactory( mockStore, @@ -330,6 +330,61 @@ describe('pullTokensFactory', () => { expect(state.tokenState.remoteData).toEqual({ metadata: null, themes: [], tokens: {} }); }); + it('should show recovery dialog with correct button labels and danger variant', async () => { + const mockStore = createMockStore({ + uiState: { + storageType: mockStorageType, + }, + }); + + const mockParams = { + localTokenData: { + checkForChanges: true, + values: { + global: [ + { + type: TokenTypes.COLOR, + name: 'colors.red', + value: '#ff0000', + $extensions: { + 'studio.tokens': { + id: 'mock-uuid', + }, + }, + }, + ], + }, + }, + localApiProviders: [ + { ...mockStorageType, secret: 'secret' }, + ], + } as unknown as StartupMessage; + + mockConfirm.mockResolvedValueOnce(false); + + const fn = pullTokensFactory( + mockStore, + mockStore.dispatch, + {}, + mockParams, + mockUseConfirm, + mockUseRemoteTokens, + ); + + mockFetchBranches.mockResolvedValueOnce(['main']); + + await fn(); + + // Verify the confirm dialog was called with correct parameters + expect(mockConfirm).toHaveBeenCalledWith({ + text: 'Recover local changes?', + description: 'You have local changes unsaved to the remote storage.', + confirmAction: 'Use remote', + cancelAction: 'Recover changes', + variant: 'danger', + }); + }); + it('should go to start tab if the localTokenData is missing somehow', async () => { const mockStore = createMockStore({ uiState: { diff --git a/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/pullTokensFactory.ts b/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/pullTokensFactory.ts index a0f165078f..001109562a 100644 --- a/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/pullTokensFactory.ts +++ b/packages/tokens-studio-for-figma/src/app/components/AppContainer/startupProcessSteps/pullTokensFactory.ts @@ -28,11 +28,15 @@ export function pullTokensFactory( const activeTheme = typeof params.activeTheme === 'string' ? { [INTERNAL_THEMES_NO_GROUP]: params.activeTheme } : params.activeTheme; const askUserIfRecoverLocalChanges = async () => { - const shouldRecoverLocalChanges = await useConfirmResult.confirm({ + const shouldUseRemote = await useConfirmResult.confirm({ text: 'Recover local changes?', description: 'You have local changes unsaved to the remote storage.', + confirmAction: 'Use remote', + cancelAction: 'Recover changes', + variant: 'danger', }); - return shouldRecoverLocalChanges; + // Return the opposite: if user confirms "Use remote", we should NOT recover local changes + return !shouldUseRemote; }; const getApiCredentials = async (shouldPull: boolean, isRemoteStorage: boolean) => {