diff --git a/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js index 092bdb0a669..0692a4769b9 100644 --- a/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js @@ -176,13 +176,20 @@ describe('Verify Accessibility Support in different sections in Settings and Pro cy.get('#changeInterfaceLanguageLabel').should('be.visible').and('have.text', 'Change interface language'); // # When space key is pressed on dropdown, it should expand and should collapse when esc key is pressed - cy.get('@inputEl').typeWithForce(' '); - cy.findByRole('listbox').should('have.class', 'react-select__menu-list').as('listBox'); + // Menu is portaled to document.body (outside the aria-modal dialog), so query by class + // and assert role=listbox rather than findByRole (inaccessible outside the modal). + cy.get('@inputEl').focus().typeWithForce(' '); + cy.get('.react-select__menu-list'). + should('be.visible'). + and('have.attr', 'role', 'listbox'). + and('have.class', 'react-select__menu-list'). + as('listBox'); cy.get('@inputEl').typeWithForce('{esc}'); cy.get('@listBox').should('not.exist'); // # Press down arrow twice and check aria label - cy.get('@inputEl').typeWithForce(' '); + cy.get('@inputEl').focus().typeWithForce(' '); + cy.get('.react-select__menu-list').should('be.visible'); cy.get('@inputEl').typeWithForce('{downarrow}{downarrow}'); cy.get('#displayLanguage').within(($el) => { cy.wrap($el).findByRole('log').should('have.attr', 'aria-live', 'assertive').as('ariaEl'); @@ -276,7 +283,7 @@ describe('Verify Accessibility Support in different sections in Settings and Pro // * Check Tab behavior in MFA section cy.get('#mfaEdit').click(); cy.get('#passwordEdit').focus().tab({shift: true}).tab().tab(); - cy.get('.setting-list button.btn').should('have.class', 'a11y--active a11y--focused').tab(); + cy.get('.setting-list').findByRole('button', {name: /Add|Remove/i}).should('have.class', 'a11y--active a11y--focused').tab(); cy.get('#cancelSetting').should('have.class', 'a11y--active a11y--focused'); // * Check Tab behavior in Sign-In Method if its available @@ -284,7 +291,7 @@ describe('Verify Accessibility Support in different sections in Settings and Pro if (el.find('#signinEdit').length) { cy.get('#signinEdit').click(); cy.get('#mfaEdit').focus().tab({shift: true}).tab().tab(); - cy.get('.setting-list a.btn').should('have.class', 'a11y--active a11y--focused').tab(); + cy.get('.setting-list').findByRole('link').should('have.class', 'a11y--active a11y--focused').tab(); cy.get('#cancelSetting').should('have.class', 'a11y--active a11y--focused'); } }); diff --git a/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.ts b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.ts index 30562d1c6e3..a6fcb71c833 100644 --- a/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.ts @@ -145,7 +145,7 @@ describe('Collapsed Reply Threads', () => { cy.uiGetPostThreadFooter(postForAvatar.id).find('.Avatars').find('button').first().click(); // * Profile popover should be visible and close on ESC - cy.get('div.user-profile-popover').first().should('be.visible').find('button.btn-primary.btn-sm').type('{esc}'); + cy.get('div.user-profile-popover').first().should('be.visible').find('.user-popover__bottom-row-container button').type('{esc}'); // # Visit global threads cy.uiClickSidebarItem('threads'); @@ -153,8 +153,8 @@ describe('Collapsed Reply Threads', () => { // * Find the first avatar and click it cy.get('div.ThreadItem').find('.activity').find('.Avatars').find('button').first().click(); - // * Profile popover should be visible and close on ESC - cy.get('div.user-profile-popover').first().should('be.visible').find('button.btn-primary.btn-sm'); + // * Profile popover should be visible + cy.get('div.user-profile-popover').first().should('be.visible').find('.user-popover__bottom-row-container button'); }); it('MM-T4143 Emoji reaction - type +:+1:', () => { diff --git a/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts index 9e81ff19cce..aa5da966413 100644 --- a/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts @@ -55,7 +55,7 @@ describe('Custom emojis', () => { cy.uiOpenCustomEmoji(); // # Click on add custom emoji - cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible').click(); + cy.findByRole('link', {name: 'Add Custom Emoji'}).should('be.visible').click(); // # Type emoji name cy.get('#name').type(customEmojiWithColons); @@ -122,5 +122,5 @@ function saveCustomEmoji(teamName: string) { // * Should return to list of custom emojis cy.url().should('include', `${teamName}/emoji`); - cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible'); + cy.findByRole('link', {name: 'Add Custom Emoji'}).should('be.visible'); } diff --git a/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts index 5a777268906..d85e450e30c 100644 --- a/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts @@ -105,7 +105,7 @@ describe('Custom emojis', () => { cy.uiOpenCustomEmoji(); // # Click on add custom emoji - cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible').click(); + cy.findByRole('link', {name: 'Add Custom Emoji'}).should('be.visible').click(); // # Type emoji name cy.get('#name').should('be.visible').type(customEmojiWithColons); @@ -180,5 +180,5 @@ function saveCustomEmoji(teamName: string) { // * Should return to list of custom emojis cy.url().should('include', `${teamName}/emoji`); - cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible'); + cy.findByRole('link', {name: 'Add Custom Emoji'}).should('be.visible'); } diff --git a/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts index 5b63917bc26..b97c12df8db 100644 --- a/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts @@ -136,7 +136,7 @@ describe('Guest Account - Guest User Invitation Flow', () => { // * Update email outside whitelisted domain and verify error message cy.get('#resetEmailModal').should('be.visible').within(() => { cy.get('input[type="email"]').type(email); - cy.get('button.btn-primary.confirm').click(); + cy.get('button.GenericModal__button.confirm').click(); cy.get('.error').should('be.visible').and('have.text', 'The email you provided does not belong to an accepted domain for guest accounts. Please contact your administrator or sign up with a different email.'); cy.get('.close').click(); }); diff --git a/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts index 56122570081..72fabcca7d7 100644 --- a/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts @@ -87,7 +87,7 @@ describe('Guest Account - Verify Manage Guest Users', () => { const email = `temp-${getRandomId()}@mattermost.com`; cy.get('#resetEmailModal').should('be.visible').within(() => { cy.get('input[type="email"]').type(email); - cy.get('button.btn-primary.confirm').click(); + cy.get('button.GenericModal__button.confirm').click(); }); // * Verify if Guest's email was updated diff --git a/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js index 676d387d48b..6b469906ea1 100644 --- a/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js @@ -62,7 +62,7 @@ describe('Archived channels', () => { cy.visit(`/admin_console/user_management/channels/${testChannel.id}`); // * Verify the Unarchive Channel button is visible - cy.get('button.btn-secondary', {timeout: TIMEOUTS.TWO_SEC}).should('have.text', 'Unarchive Channel').should('be.visible').should('be.enabled'); + cy.findByRole('button', {name: 'Unarchive Channel', timeout: TIMEOUTS.TWO_SEC}).should('be.visible').should('be.enabled'); // * Verify that only one widget is visible cy.get('div.AdminPanel').should('be.visible').and('have.length', 1); @@ -73,10 +73,10 @@ describe('Archived channels', () => { cy.visit(`/admin_console/user_management/channels/${testChannel.id}`); // # Click Unarchive Channel button - cy.get('button.btn-secondary', {timeout: TIMEOUTS.TWO_SEC}).findAllByText('Unarchive Channel').click(); + cy.findByRole('button', {name: 'Unarchive Channel', timeout: TIMEOUTS.TWO_SEC}).click(); // * Verify the Archive Channel button is visible - cy.get('button.btn-secondary.btn-danger', {timeout: TIMEOUTS.TWO_SEC}).findAllByText('Archive Channel').should('be.visible'); + cy.findByRole('button', {name: 'Archive Channel', timeout: TIMEOUTS.TWO_SEC}).should('be.visible'); // * Verify that the other widget appears cy.get('div.AdminPanel').should('be.visible').should('have.length', 5); diff --git a/e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js index e73d5e317c3..f21bc2a060c 100644 --- a/e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js @@ -155,7 +155,7 @@ describe('Slash commands page', () => { cy.get('#url').clear().type('http://mattermost.com'); // # Click on Cancel - cy.get('a').contains('Cancel').click(); + cy.findByRole('link', {name: 'Cancel'}).click(); // # Click on edit again cy.get('a[href*="/edit"]').click(); diff --git a/e2e-tests/cypress/tests/integration/channels/interactive_dialog/file_upload_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_dialog/file_upload_spec.js index ae2704f647f..d9fe2af9a4a 100644 --- a/e2e-tests/cypress/tests/integration/channels/interactive_dialog/file_upload_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/interactive_dialog/file_upload_spec.js @@ -76,7 +76,7 @@ describe('Interactive Dialog - File Upload', () => { cy.get('label').should('be.visible').and('contain', singleElement.display_name); // * Verify "Choose File" button for allow_multiple=false - cy.get('button.btn-tertiary').should('be.visible').and('have.text', 'Choose File'); + cy.findByRole('button', {name: 'Choose File'}).should('be.visible'); // * Verify placeholder / help text is visible before any upload cy.get('.help-text').should('be.visible'); @@ -87,7 +87,7 @@ describe('Interactive Dialog - File Upload', () => { cy.get('label').should('be.visible').and('contain', multipleElement.display_name); // * Verify "Choose Files" button for allow_multiple=true - cy.get('button.btn-tertiary').should('be.visible').and('have.text', 'Choose Files'); + cy.findByRole('button', {name: 'Choose Files'}).should('be.visible'); // * Verify placeholder / help text is visible before any upload cy.get('.help-text').should('be.visible'); diff --git a/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js index 6f386a80a25..035a8c2b5d9 100644 --- a/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js @@ -191,8 +191,8 @@ describe('Forward Message', () => { // * Assert channel select is not existent cy.get('.forward-post__select').should('not.exist'); - // * Assert if button is enabled - cy.get('.btn-tertiary').should('not.be.disabled'); + // * Assert if cancel button is enabled + cy.findByRole('button', {name: 'Cancel'}).should('not.be.disabled'); // * Assert Notification is shown cy.findByTestId('notification_forward_post').should('be.visible').should('contain.text', `This message is from a private conversation and can only be shared with ${dmChannel.display_name}`); @@ -206,8 +206,8 @@ describe('Forward Message', () => { } if (cancel) { - // * Assert if button is active - cy.get('.btn-tertiary').should('not.be.disabled').type('{esc}', {force: true}); + // * Assert if cancel button is active, then dismiss with escape + cy.findByRole('button', {name: 'Cancel'}).should('not.be.disabled').type('{esc}', {force: true}); } else { // * Assert if button is active cy.get('.GenericModal__button.confirm').should('not.be.disabled').type('{enter}', {force: true}); diff --git a/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js index 5fa8cb785fb..fae10016ed0 100644 --- a/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js @@ -188,8 +188,8 @@ describe('Forward Message', () => { cy.findByTestId('notification_forward_post').should('be.visible').should('contain.text', `This message is from a private channel and can only be shared with ~${privateChannel.display_name}`); if (cancel) { - // * Assert if button is active - cy.get('.btn-tertiary').should('not.be.disabled').click(); + // * Assert if cancel button is active + cy.findByRole('button', {name: 'Cancel'}).should('not.be.disabled').click(); } else { // * Assert if button is active cy.get('.GenericModal__button.confirm').should('not.be.disabled').click(); diff --git a/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js index c075ca6347e..9b4f442bed8 100644 --- a/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js @@ -62,7 +62,7 @@ describe('Channel', () => { cy.get('.url-input-error').should('not.exist'); // * 'Create Channel' button should be enabled - cy.findByText('Create channel').should('not.have.class', 'disabled'); + cy.findByRole('button', {name: 'Create channel'}).should('not.be.disabled'); // # Click on Cancel button to move out of New Channel Modal cy.findByText('Cancel').click(); @@ -92,7 +92,7 @@ function verifyExistingChannelError(newChannelName, makePrivate = false) { cy.get('.url-input-error').contains('A channel with that URL already exists'); // * 'Create Channel' button should be disabled - cy.findByText('Create channel').should('have.class', 'disabled'); + cy.findByRole('button', {name: 'Create channel'}).should('be.disabled'); } /** diff --git a/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_spec.js index fff50a3a33a..673137e1577 100644 --- a/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_spec.js @@ -70,7 +70,7 @@ describe('System Console > User Management > Users', () => { // # Type new password and submit. cy.get('input[type=password]').type('new' + testUser.password); - cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); + cy.get('button.GenericModal__button.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); // # Log out. cy.apiLogout(); @@ -96,7 +96,7 @@ describe('System Console > User Management > Users', () => { cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password); // # Click the 'Cancel' button. - cy.get('.modal-footer > .btn-tertiary').should('contain', 'Cancel').click().wait(TIMEOUTS.HALF_SEC); + cy.get('.modal-footer').findByRole('button', {name: 'Cancel'}).click().wait(TIMEOUTS.HALF_SEC); // # Log out. cy.apiLogout(); @@ -113,7 +113,7 @@ describe('System Console > User Management > Users', () => { cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password); // # Click the 'Reset' button. - cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); + cy.get('button.GenericModal__button.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); // * Verify the appropriate error is returned (current password error shows in modal header area). cy.get('.genericModalError .error').should('be.visible'). @@ -128,7 +128,7 @@ describe('System Console > User Management > Users', () => { cy.get('input[type=password]').eq(1).type('new'); // # Click the 'Reset' button. - cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); + cy.get('button.GenericModal__button.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); // * Verify the appropriate error is returned (new password error shows under the input). cy.get('.Input___error').should('be.visible').and('contain', 'characters long'); @@ -138,7 +138,7 @@ describe('System Console > User Management > Users', () => { searchUserAndOpenResetPassword(otherAdmin.username, otherAdmin.email); // # Click the 'Reset' button. - cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); + cy.get('button.GenericModal__button.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); // * Verify the appropriate error is returned (current password missing). cy.get('.genericModalError .error').should('be.visible'). @@ -148,7 +148,7 @@ describe('System Console > User Management > Users', () => { cy.get('input[type=password]').eq(0).type(otherAdmin.password); // # Click the 'Reset' button. - cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); + cy.get('button.GenericModal__button.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); // * Verify the appropriate error is returned (new password error shows under the input). cy.get('.Input___error').should('be.visible').and('contain', 'characters long'); @@ -162,7 +162,7 @@ describe('System Console > User Management > Users', () => { cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password); // # Click the 'Reset' button. - cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); + cy.get('button.GenericModal__button.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); // # Log out. cy.apiLogout(); diff --git a/e2e-tests/cypress/tests/integration/channels/system_console/user_management_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management_spec.js index 5dbecfefac5..8dc6bd2ca94 100644 --- a/e2e-tests/cypress/tests/integration/channels/system_console/user_management_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/system_console/user_management_spec.js @@ -194,7 +194,7 @@ describe('User Management', () => { // # Set new password. cy.get('input[type=password]').type('new' + testUser.password); - cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); + cy.get('button.GenericModal__button.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC); // * Verify Update email option is visible. cy.get('#systemUsersTable-cell-0_actionsColumn').click().wait(TIMEOUTS.HALF_SEC); @@ -269,7 +269,7 @@ describe('User Management', () => { } // # Click the "Update" button. - cy.get('button.btn-primary.confirm').click(); + cy.get('button.GenericModal__button.confirm').click(); // * Check for the error messages, if any. if (errorMsg.length > 0) { diff --git a/e2e-tests/playwright/lib/src/ui/components/channels/delete_post_confirmation_dialog.ts b/e2e-tests/playwright/lib/src/ui/components/channels/delete_post_confirmation_dialog.ts index 5f32a3f3178..a5a603c8681 100644 --- a/e2e-tests/playwright/lib/src/ui/components/channels/delete_post_confirmation_dialog.ts +++ b/e2e-tests/playwright/lib/src/ui/components/channels/delete_post_confirmation_dialog.ts @@ -13,7 +13,7 @@ export default class DeletePostConfirmationDialog { constructor(container: Locator) { this.container = container; - this.cancelButton = container.locator('button.btn.btn-tertiary'); + this.cancelButton = container.getByRole('button', {name: 'Cancel'}); this.confirmButton = container.locator('button#deletePostModalButton'); } diff --git a/e2e-tests/playwright/lib/src/ui/components/channels/marketplace_modal.ts b/e2e-tests/playwright/lib/src/ui/components/channels/marketplace_modal.ts index 85b90cc51bc..d58b4b175c2 100644 --- a/e2e-tests/playwright/lib/src/ui/components/channels/marketplace_modal.ts +++ b/e2e-tests/playwright/lib/src/ui/components/channels/marketplace_modal.ts @@ -56,7 +56,7 @@ export default class MarketplaceModal { } await installButton.click(); - await expect(this.pluginRow(pluginId).getByRole('button', {name: 'Configure'})).toBeVisible({ + await expect(this.pluginRow(pluginId).getByRole('link', {name: 'Configure'})).toBeVisible({ timeout: duration.one_min, }); @@ -67,6 +67,6 @@ export default class MarketplaceModal { * Clicks "Configure" for the given plugin, which navigates to its System Console settings page. */ async clickConfigure(pluginId: string) { - await this.pluginRow(pluginId).getByRole('button', {name: 'Configure'}).click(); + await this.pluginRow(pluginId).getByRole('link', {name: 'Configure'}).click(); } } diff --git a/e2e-tests/playwright/lib/src/ui/components/channels/restore_post_confirmation_dialog.ts b/e2e-tests/playwright/lib/src/ui/components/channels/restore_post_confirmation_dialog.ts index 9e1ad0ad71d..f5f88728833 100644 --- a/e2e-tests/playwright/lib/src/ui/components/channels/restore_post_confirmation_dialog.ts +++ b/e2e-tests/playwright/lib/src/ui/components/channels/restore_post_confirmation_dialog.ts @@ -13,8 +13,8 @@ export default class RestorePostConfirmationDialog { constructor(container: Locator) { this.container = container; - this.cancelButton = container.locator('button.btn.btn-tertiary'); - this.confirmButton = container.locator('button.GenericModal__button.btn.btn-primary.confirm'); + this.cancelButton = container.getByRole('button', {name: 'Cancel'}); + this.confirmButton = container.locator('button.GenericModal__button.confirm'); } async toBeVisible() { diff --git a/e2e-tests/playwright/specs/accessibility/channels/settings_dialog/notifications.spec.ts b/e2e-tests/playwright/specs/accessibility/channels/settings_dialog/notifications.spec.ts index 4c420d9baf2..e80e1b17003 100644 --- a/e2e-tests/playwright/specs/accessibility/channels/settings_dialog/notifications.spec.ts +++ b/e2e-tests/playwright/specs/accessibility/channels/settings_dialog/notifications.spec.ts @@ -104,9 +104,10 @@ test( - heading "Notifications" [level=3] - link "Learn more about notifications": - /url: https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=${user.id}&sid=${clientConfig.DiagnosticId}&edition=enterprise&server_version=${clientConfig.Version} - - img - heading "Desktop and mobile notifications Permission required" [level=4]: + - text: "" - img + - text: "" - button "Desktop and mobile notifications Permission required Edit" - text: Mentions, direct messages, and group messages - heading "Desktop notification sounds" [level=4] @@ -114,6 +115,7 @@ test( - text: "\\"Bing\\" for messages" - heading "Email notifications" [level=4] - button "Email notifications Edit" + - text: "On" - heading "Auto-follow threads on channel-wide mentions" [level=4] - button "Auto-follow threads on channel-wide mentions Edit" - text: "On" @@ -122,6 +124,7 @@ test( - text: "\\"@${user.username}\\", \\"@channel\\", \\"@all\\", \\"@here\\"" - heading "Keywords that get highlighted (without notifications)" [level=4] - button "Keywords that get highlighted (without notifications) Edit" + - text: None - heading "Troubleshooting notifications" [level=4] - text: Not receiving notifications? Start by sending a test notification to all your devices to check if they’re working as expected. If issues persist, explore ways to solve them with troubleshooting steps. - button "Send a test notification" diff --git a/webapp/AGENTS.md b/webapp/AGENTS.md index f3fdbcaa4a8..c65edc4c49a 100644 --- a/webapp/AGENTS.md +++ b/webapp/AGENTS.md @@ -12,6 +12,7 @@ Follow `webapp/STYLE_GUIDE.md` for canonical style, accessibility, and testing s - **New UI**: prefer `@mattermost/compass-ui` when a published (on npm) component exists. Import via subpaths: `import {Button} from '@mattermost/compass-ui/components/button';` Do not use the root barrel. Do not recreate Compass primitives. +- **Button**: use Compass UI for text-based button UI. Do not use `@mattermost/shared` `Button` (removed); `buttonClassNames` from `@mattermost/shared/components/button` remains for menu triggers and similar class-only cases. Sizes: `x-small` / `small` / `medium` / `large`. Use `destructive` (boolean) and `appearance="inverted"` for those styles. For link-styled CTAs, use `asChild` with a single `` or router `Link` child instead of nesting a button. - **Do not mass-migrate** existing UI components to Compass. Only switch when building new UI or when the task is an intentional migration of the code you are already changing. - **`@mattermost/compass-proto`**: prototyping package not published to npm (shells, call composites, hardcoded menu recipes, proto `WithTooltip`). Not for Mattermost webapp product code — do not add the dependency or import from it unless explicitly adopting that package. Prefer existing webapp / shared / MUI stacks for those surfaces. - **Exceptions (keep current stacks)**: icons → `@mattermost/compass-icons`; emoji → `Emoji` (`@mattermost/shared`); modals → existing shared / `GenericModal`; menus → existing MUI menus. Do not switch Modal/Menu to compass-ui yet. diff --git a/webapp/CLAUDE.OPTIONAL.md b/webapp/CLAUDE.OPTIONAL.md index c4cbeca2b01..bbfbfd742ee 100644 --- a/webapp/CLAUDE.OPTIONAL.md +++ b/webapp/CLAUDE.OPTIONAL.md @@ -67,7 +67,7 @@ import Client4 from '../platform/client/src/client4.ts'; - **React Router 5.3**: Client-side routing - **React Intl**: Internationalization - **Floating UI**: Tooltips and popovers (prefer `WithTooltip` from `@mattermost/shared/components/tooltip`) -- **@mattermost/compass-ui**: Published Compass UI components (prefer `Button` from `@mattermost/compass-ui/components/button` over hand-rolled or shared Button) +- **@mattermost/compass-ui**: Published Compass UI components (prefer `Button` from `@mattermost/compass-ui/components/button` over hand-rolled or shared Button; shared `Button` is removed, `buttonClassNames` remains for class-only cases) - **@mattermost/shared**: Shared components and utilities (`WithTooltip`, `Emoji`, etc.) — use where `webapp/AGENTS.md` specifies them - **@mattermost/compass-icons**: Icon library (prefer over font-awesome) - **Monaco Editor**: Code editor integration diff --git a/webapp/STYLE_GUIDE.md b/webapp/STYLE_GUIDE.md index efe3e276c34..254ff6d5649 100644 --- a/webapp/STYLE_GUIDE.md +++ b/webapp/STYLE_GUIDE.md @@ -102,7 +102,7 @@ The following guidelines should be applied to both new and existing code. Howeve - **React Bootstrap**: Avoid using React Bootstrap directly. - **Modals**: Use `GenericModal` from `@mattermost/components` instead of React Bootstrap's `Modal`. - - **Buttons**: Use `Button` from `@mattermost/compass-ui/components/button` instead of React Bootstrap's `Button` or raw Bootstrap like ` @@ -160,22 +190,52 @@ exports[`components/GetLinkModal should have called onHide when close button is class="modal-footer" > @@ -257,22 +317,52 @@ exports[`components/GetLinkModal should match snapshot when all props is set 1`] class="modal-footer" > @@ -349,22 +439,52 @@ exports[`components/GetLinkModal should match snapshot when helpText is not set class="modal-footer" > diff --git a/webapp/channels/src/components/__snapshots__/list_modal.test.tsx.snap b/webapp/channels/src/components/__snapshots__/list_modal.test.tsx.snap index 15bed1551ec..0163a068a9b 100644 --- a/webapp/channels/src/components/__snapshots__/list_modal.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/list_modal.test.tsx.snap @@ -175,9 +175,14 @@ exports[`components/ListModal should match snapshot with title bar button 1`] = diff --git a/webapp/channels/src/components/__snapshots__/save_button.test.tsx.snap b/webapp/channels/src/components/__snapshots__/save_button.test.tsx.snap index 42afb762be5..61006aafbec 100644 --- a/webapp/channels/src/components/__snapshots__/save_button.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/save_button.test.tsx.snap @@ -3,12 +3,14 @@ exports[`components/SaveButton should match snapshot, extraClasses 1`] = `
@@ -18,12 +20,14 @@ exports[`components/SaveButton should match snapshot, extraClasses 1`] = ` exports[`components/SaveButton should match snapshot, on defaultMessage 1`] = `
@@ -33,12 +37,14 @@ exports[`components/SaveButton should match snapshot, on defaultMessage 1`] = ` exports[`components/SaveButton should match snapshot, on defaultMessage 2`] = `
@@ -48,21 +54,26 @@ exports[`components/SaveButton should match snapshot, on defaultMessage 2`] = ` exports[`components/SaveButton should match snapshot, on savingMessage 1`] = `
@@ -72,21 +83,26 @@ exports[`components/SaveButton should match snapshot, on savingMessage 1`] = ` exports[`components/SaveButton should match snapshot, on savingMessage 2`] = `
diff --git a/webapp/channels/src/components/__snapshots__/setting_item_max.test.tsx.snap b/webapp/channels/src/components/__snapshots__/setting_item_max.test.tsx.snap index d8ca91faef2..b0e51d6c14c 100644 --- a/webapp/channels/src/components/__snapshots__/setting_item_max.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/setting_item_max.test.tsx.snap @@ -3,7 +3,7 @@ exports[`components/SettingItemMax should match snapshot 1`] = `
@@ -57,7 +68,7 @@ exports[`components/SettingItemMax should match snapshot 1`] = ` exports[`components/SettingItemMax should match snapshot, on clientError 1`] = `
@@ -111,7 +133,7 @@ exports[`components/SettingItemMax should match snapshot, on clientError 1`] = ` exports[`components/SettingItemMax should match snapshot, on serverError 1`] = `

- - + + + @@ -215,23 +248,34 @@ exports[`components/SettingItemMax should match snapshot, with new saveTextButto
- - + + +
@@ -269,13 +313,22 @@ exports[`components/SettingItemMax should match snapshot, without submit 1`] = `
- + +
diff --git a/webapp/channels/src/components/__snapshots__/setting_picture.test.tsx.snap b/webapp/channels/src/components/__snapshots__/setting_picture.test.tsx.snap index 8d3751ae01a..251ad92582c 100644 --- a/webapp/channels/src/components/__snapshots__/setting_picture.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/setting_picture.test.tsx.snap @@ -39,7 +39,9 @@ exports[`components/SettingItemMin should match snapshot with active Save button class="setting-list-item" >
- +
- - + +
@@ -107,7 +124,9 @@ exports[`components/SettingItemMin should match snapshot with removeSrc state ac class="setting-list-item" >
- +
- - + +
@@ -185,7 +219,9 @@ exports[`components/SettingItemMin should match snapshot, on loading picture 1`] class="setting-list-item" >
- +
- - + +
@@ -283,7 +335,9 @@ exports[`components/SettingItemMin should match snapshot, profile picture on fil class="setting-list-item" >
- +
- - + +
@@ -362,7 +431,9 @@ exports[`components/SettingItemMin should match snapshot, profile picture on sou class="setting-list-item" >
- +
- - + +
@@ -448,7 +534,9 @@ exports[`components/SettingItemMin should match snapshot, team icon on file 1`] class="setting-list-item" >
- +
- - + +
@@ -551,7 +654,9 @@ exports[`components/SettingItemMin should match snapshot, team icon on source 1` class="setting-list-item" >
- +
- - + +
@@ -654,7 +774,9 @@ exports[`components/SettingItemMin should match snapshot, user icon on source 1` class="setting-list-item" >
- +
- - + +
diff --git a/webapp/channels/src/components/__snapshots__/spinner_button.test.tsx.snap b/webapp/channels/src/components/__snapshots__/spinner_button.test.tsx.snap index dc40f38b5ed..7cb0c51b1a4 100644 --- a/webapp/channels/src/components/__snapshots__/spinner_button.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/spinner_button.test.tsx.snap @@ -3,14 +3,19 @@ exports[`components/SpinnerButton should match snapshot with children 1`] = `
`; @@ -18,9 +23,14 @@ exports[`components/SpinnerButton should match snapshot with children 1`] = ` exports[`components/SpinnerButton should match snapshot with required props 1`] = `
`; @@ -28,18 +38,24 @@ exports[`components/SpinnerButton should match snapshot with required props 1`] exports[`components/SpinnerButton should match snapshot with spinning 1`] = `
diff --git a/webapp/channels/src/components/actions_menu/actions_menu_empty_popover.tsx b/webapp/channels/src/components/actions_menu/actions_menu_empty_popover.tsx index b3213793206..4f7d034462c 100644 --- a/webapp/channels/src/components/actions_menu/actions_menu_empty_popover.tsx +++ b/webapp/channels/src/components/actions_menu/actions_menu_empty_popover.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import {Permissions} from 'mattermost-redux/constants'; @@ -57,7 +57,7 @@ export default function ActionsMenuEmptyPopover({
@@ -85,9 +90,14 @@ exports[`components/activity_log_modal/ActivityLog should match snapshot with mo class="activity-log__action" > diff --git a/webapp/channels/src/components/activity_log_modal/components/activity_log.tsx b/webapp/channels/src/components/activity_log_modal/components/activity_log.tsx index bde15f9390f..2d08103d2bd 100644 --- a/webapp/channels/src/components/activity_log_modal/components/activity_log.tsx +++ b/webapp/channels/src/components/activity_log_modal/components/activity_log.tsx @@ -5,7 +5,7 @@ import React, {type JSX} from 'react'; import type {MessageDescriptor} from 'react-intl'; import {FormattedDate, FormattedMessage, FormattedTime, defineMessages} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {Session} from '@mattermost/types/sessions'; import {General} from 'mattermost-redux/constants'; diff --git a/webapp/channels/src/components/add_groups_to_channel_modal/__snapshots__/add_groups_to_channel_modal.test.tsx.snap b/webapp/channels/src/components/add_groups_to_channel_modal/__snapshots__/add_groups_to_channel_modal.test.tsx.snap index 59e4424b2ec..bbc15205888 100644 --- a/webapp/channels/src/components/add_groups_to_channel_modal/__snapshots__/add_groups_to_channel_modal.test.tsx.snap +++ b/webapp/channels/src/components/add_groups_to_channel_modal/__snapshots__/add_groups_to_channel_modal.test.tsx.snap @@ -123,12 +123,14 @@ exports[`components/AddGroupsToChannelModal should match snapshot 1`] = ` diff --git a/webapp/channels/src/components/add_groups_to_team_modal/__snapshots__/add_groups_to_team_modal.test.tsx.snap b/webapp/channels/src/components/add_groups_to_team_modal/__snapshots__/add_groups_to_team_modal.test.tsx.snap index aa32d624df3..3054c9a63f4 100644 --- a/webapp/channels/src/components/add_groups_to_team_modal/__snapshots__/add_groups_to_team_modal.test.tsx.snap +++ b/webapp/channels/src/components/add_groups_to_team_modal/__snapshots__/add_groups_to_team_modal.test.tsx.snap @@ -123,12 +123,14 @@ exports[`components/AddGroupsToTeamModal should match snapshot 1`] = ` diff --git a/webapp/channels/src/components/add_user_to_channel_modal/__snapshots__/add_user_to_channel_modal.test.tsx.snap b/webapp/channels/src/components/add_user_to_channel_modal/__snapshots__/add_user_to_channel_modal.test.tsx.snap index 1f8835a0c86..74f5a479654 100644 --- a/webapp/channels/src/components/add_user_to_channel_modal/__snapshots__/add_user_to_channel_modal.test.tsx.snap +++ b/webapp/channels/src/components/add_user_to_channel_modal/__snapshots__/add_user_to_channel_modal.test.tsx.snap @@ -72,18 +72,26 @@ exports[`components/AddUserToChannelModal should match snapshot 1`] = ` class="modal-footer" > diff --git a/webapp/channels/src/components/add_user_to_channel_modal/add_user_to_channel_modal.tsx b/webapp/channels/src/components/add_user_to_channel_modal/add_user_to_channel_modal.tsx index d0acc0dc67d..e098888a102 100644 --- a/webapp/channels/src/components/add_user_to_channel_modal/add_user_to_channel_modal.tsx +++ b/webapp/channels/src/components/add_user_to_channel_modal/add_user_to_channel_modal.tsx @@ -6,7 +6,7 @@ import type {ChangeEvent, FormEvent} from 'react'; import {Modal} from 'react-bootstrap'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {Channel, ChannelMembership} from '@mattermost/types/channels'; import type {UserProfile} from '@mattermost/types/users'; import type {RelationOneToOne} from '@mattermost/types/utilities'; diff --git a/webapp/channels/src/components/add_user_to_group_multiselect/__snapshots__/add_user_to_group_multiselect.test.tsx.snap b/webapp/channels/src/components/add_user_to_group_multiselect/__snapshots__/add_user_to_group_multiselect.test.tsx.snap index 5db533d13c3..38c2c58cb44 100644 --- a/webapp/channels/src/components/add_user_to_group_multiselect/__snapshots__/add_user_to_group_multiselect.test.tsx.snap +++ b/webapp/channels/src/components/add_user_to_group_multiselect/__snapshots__/add_user_to_group_multiselect.test.tsx.snap @@ -81,13 +81,15 @@ exports[`component/add_user_to_group_multiselect should match snapshot with diff class="multi-select__footer modal-footer" > @@ -176,13 +178,15 @@ exports[`component/add_user_to_group_multiselect should match snapshot with prof class="multi-select__footer modal-footer" > @@ -271,13 +275,15 @@ exports[`component/add_user_to_group_multiselect should match snapshot without a class="multi-select__footer modal-footer" > diff --git a/webapp/channels/src/components/add_users_to_group_modal/__snapshots__/add_users_to_group_modal.test.tsx.snap b/webapp/channels/src/components/add_users_to_group_modal/__snapshots__/add_users_to_group_modal.test.tsx.snap index 16bf0617f19..dbce0590e9c 100644 --- a/webapp/channels/src/components/add_users_to_group_modal/__snapshots__/add_users_to_group_modal.test.tsx.snap +++ b/webapp/channels/src/components/add_users_to_group_modal/__snapshots__/add_users_to_group_modal.test.tsx.snap @@ -158,18 +158,25 @@ exports[`component/add_users_to_group_modal should match snapshot 1`] = ` class="multi-select__footer modal-footer" > diff --git a/webapp/channels/src/components/add_users_to_team_modal/__snapshots__/add_users_to_team_modal.test.tsx.snap b/webapp/channels/src/components/add_users_to_team_modal/__snapshots__/add_users_to_team_modal.test.tsx.snap index 5d7b0d61cd1..9e77ee7bbed 100644 --- a/webapp/channels/src/components/add_users_to_team_modal/__snapshots__/add_users_to_team_modal.test.tsx.snap +++ b/webapp/channels/src/components/add_users_to_team_modal/__snapshots__/add_users_to_team_modal.test.tsx.snap @@ -123,12 +123,14 @@ exports[`components/admin_console/add_users_to_team_modal/AddUsersToTeamModal sh diff --git a/webapp/channels/src/components/admin_console/__snapshots__/cluster_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/__snapshots__/cluster_settings.test.tsx.snap index 30c25c4d98d..f9460314e53 100644 --- a/webapp/channels/src/components/admin_console/__snapshots__/cluster_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/__snapshots__/cluster_settings.test.tsx.snap @@ -469,13 +469,15 @@ exports[`components/ClusterSettings should match snapshot, compression disabled class="admin-console-save" > @@ -957,13 +959,15 @@ exports[`components/ClusterSettings should match snapshot, compression enabled 1 class="admin-console-save" > @@ -1445,13 +1449,15 @@ exports[`components/ClusterSettings should match snapshot, encryption disabled 1 class="admin-console-save" > @@ -1933,13 +1939,15 @@ exports[`components/ClusterSettings should match snapshot, encryption enabled 1` class="admin-console-save" > diff --git a/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap index 8bc20b3ca91..280c7459a2a 100644 --- a/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap @@ -378,10 +378,14 @@ exports[`components/DatabaseSettings should match snapshot 1`] = ` >
diff --git a/webapp/channels/src/components/admin_console/__snapshots__/elasticsearch_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/__snapshots__/elasticsearch_settings.test.tsx.snap index 633488a8aa4..4305dfb124e 100644 --- a/webapp/channels/src/components/admin_console/__snapshots__/elasticsearch_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/__snapshots__/elasticsearch_settings.test.tsx.snap @@ -508,11 +508,15 @@ exports[`components/ElasticSearchSettings should match snapshot, disabled 1`] = >
@@ -1527,10 +1545,14 @@ exports[`components/ElasticSearchSettings should match snapshot, enabled 1`] = ` >
@@ -2542,10 +2578,14 @@ exports[`components/ElasticSearchSettings should match snapshot, sniff enabled 1 >
diff --git a/webapp/channels/src/components/admin_console/__snapshots__/message_export_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/__snapshots__/message_export_settings.test.tsx.snap index 8d4e9ea30f7..25e31d6c3ad 100644 --- a/webapp/channels/src/components/admin_console/__snapshots__/message_export_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/__snapshots__/message_export_settings.test.tsx.snap @@ -202,11 +202,15 @@ exports[`components/MessageExportSettings should match snapshot, disabled, actia >
@@ -722,11 +728,15 @@ exports[`components/MessageExportSettings should match snapshot, disabled, globa >
@@ -992,10 +1004,14 @@ exports[`components/MessageExportSettings should match snapshot, enabled, actian >
@@ -1502,10 +1520,14 @@ exports[`components/MessageExportSettings should match snapshot, enabled, global >
@@ -2136,10 +2160,14 @@ exports[`components/MessageExportSettings should match snapshot, enabled, global >
diff --git a/webapp/channels/src/components/admin_console/__snapshots__/push_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/__snapshots__/push_settings.test.tsx.snap index ea10aacfd33..44f7f69a14d 100644 --- a/webapp/channels/src/components/admin_console/__snapshots__/push_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/__snapshots__/push_settings.test.tsx.snap @@ -257,13 +257,15 @@ exports[`components/PushSettings should match snapshot, licensed 1`] = ` class="admin-console-save" > @@ -414,13 +416,15 @@ exports[`components/PushSettings should match snapshot, unlicensed 1`] = ` class="admin-console-save" > diff --git a/webapp/channels/src/components/admin_console/access_control/__snapshots__/policies.test.tsx.snap b/webapp/channels/src/components/admin_console/access_control/__snapshots__/policies.test.tsx.snap index f1efd32d466..e19981b9442 100644 --- a/webapp/channels/src/components/admin_console/access_control/__snapshots__/policies.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/access_control/__snapshots__/policies.test.tsx.snap @@ -19,12 +19,37 @@ exports[`components/admin_console/access_control/PolicyList should match snapsho

@@ -127,12 +152,37 @@ exports[`components/admin_console/access_control/PolicyList should match snapsho

@@ -357,12 +407,37 @@ exports[`components/admin_console/access_control/PolicyList should match snapsho

diff --git a/webapp/channels/src/components/admin_console/access_control/editors/shared.test.tsx b/webapp/channels/src/components/admin_console/access_control/editors/shared.test.tsx index 9014aff5c36..80359636906 100644 --- a/webapp/channels/src/components/admin_console/access_control/editors/shared.test.tsx +++ b/webapp/channels/src/components/admin_console/access_control/editors/shared.test.tsx @@ -45,11 +45,11 @@ describe('TestButton', () => { const button = screen.getByRole('button', {name: /test access rule/i}); expect(button).toBeInTheDocument(); - expect(button).toHaveClass('btn', 'btn-sm', 'btn-tertiary'); + expect(button.className).toEqual(expect.stringContaining('_button--emphasis-tertiary')); + expect(button.className).toEqual(expect.stringContaining('_button--size-small')); - // Check for icon - const icon = button.querySelector('i.icon.icon-lock-outline'); - expect(icon).toBeInTheDocument(); + // Leading icon is provided via compass-ui Icon glyph slot + expect(button.querySelector('svg')).toBeInTheDocument(); }); test('should render the supplied label override instead of the default copy', () => { @@ -67,7 +67,7 @@ describe('TestButton', () => { expect(screen.queryByRole('button', {name: /test access rule/i})).not.toBeInTheDocument(); const button = screen.getByRole('button', {name: /simulate rules/i}); expect(button).toBeInTheDocument(); - expect(button.querySelector('i.icon.icon-lock-outline')).toBeInTheDocument(); + expect(button.querySelector('svg')).toBeInTheDocument(); }); test('should be enabled and clickable when disabled is false', () => { diff --git a/webapp/channels/src/components/admin_console/access_control/editors/shared.tsx b/webapp/channels/src/components/admin_console/access_control/editors/shared.tsx index ec153ddec76..45d112f57b2 100644 --- a/webapp/channels/src/components/admin_console/access_control/editors/shared.tsx +++ b/webapp/channels/src/components/admin_console/access_control/editors/shared.tsx @@ -5,7 +5,9 @@ import React, {type JSX} from 'react'; import {defineMessage, FormattedMessage} from 'react-intl'; import type {MessageDescriptor} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {LockOutlineIcon, PlusIcon} from '@mattermost/compass-icons/components'; +import {Button} from '@mattermost/compass-ui/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import {WithTooltip} from '@mattermost/shared/components/tooltip'; import type {AccessControlTestResult} from '@mattermost/types/access_control'; import type {UserPropertyField} from '@mattermost/types/properties_user'; @@ -505,11 +507,11 @@ export function TestButton({onClick, disabled, disabledTooltip, label}: TestButt const button = (
{teamAbacEnabled && ( diff --git a/webapp/channels/src/components/admin_console/access_control/modals/job_details/searchable_sync_job_channel_list.tsx b/webapp/channels/src/components/admin_console/access_control/modals/job_details/searchable_sync_job_channel_list.tsx index 276f8fb49f4..75caf8a8a1f 100644 --- a/webapp/channels/src/components/admin_console/access_control/modals/job_details/searchable_sync_job_channel_list.tsx +++ b/webapp/channels/src/components/admin_console/access_control/modals/job_details/searchable_sync_job_channel_list.tsx @@ -4,7 +4,7 @@ import React, {useState, useRef, useEffect, type JSX} from 'react'; import {FormattedMessage, defineMessages, injectIntl, type WrappedComponentProps} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {Channel} from '@mattermost/types/channels'; import type {Team} from '@mattermost/types/teams'; import type {IDMappedObjects} from '@mattermost/types/utilities'; @@ -214,7 +214,7 @@ const SearchableSyncJobChannelList = (props: Props) => { nextButton = (
)} @@ -503,7 +503,7 @@ export default function PolicyList(props: Props): JSX.Element { defaultMessage='Delete Policy' /> } - confirmButtonVariant='destructive' + destructive={true} compassDesign={true} > <> diff --git a/webapp/channels/src/components/admin_console/access_control/policy_details/__snapshots__/policy_details.test.tsx.snap b/webapp/channels/src/components/admin_console/access_control/policy_details/__snapshots__/policy_details.test.tsx.snap index b97017e6a04..fbdc57a0d3f 100644 --- a/webapp/channels/src/components/admin_console/access_control/policy_details/__snapshots__/policy_details.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/access_control/policy_details/__snapshots__/policy_details.test.tsx.snap @@ -75,9 +75,14 @@ exports[`components/admin_console/access_control/policy_details/PolicyDetails sh


@@ -382,9 +423,14 @@ exports[`components/admin_console/access_control/policy_details/PolicyDetails sh

- Cancel + + Cancel +
@@ -493,9 +545,14 @@ exports[`components/admin_console/access_control/policy_details/PolicyDetails sh


@@ -775,21 +868,27 @@ exports[`components/admin_console/access_control/policy_details/PolicyDetails sh class="admin-console-save" > - Cancel + + Cancel + diff --git a/webapp/channels/src/components/admin_console/access_control/policy_details/channel_list/__snapshots__/channel_list.test.tsx.snap b/webapp/channels/src/components/admin_console/access_control/policy_details/channel_list/__snapshots__/channel_list.test.tsx.snap index de5702dc627..9d58c3cc74c 100644 --- a/webapp/channels/src/components/admin_console/access_control/policy_details/channel_list/__snapshots__/channel_list.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/access_control/policy_details/channel_list/__snapshots__/channel_list.test.tsx.snap @@ -39,13 +39,40 @@ exports[`components/admin_console/access_control/channel_list should match snaps class="Filter" >
@@ -318,13 +349,40 @@ exports[`components/admin_console/access_control/channel_list should match snaps class="Filter" >
@@ -597,13 +659,40 @@ exports[`components/admin_console/access_control/channel_list should match snaps class="Filter" >
@@ -876,13 +969,40 @@ exports[`components/admin_console/access_control/channel_list should match snaps class="Filter" >
diff --git a/webapp/channels/src/components/admin_console/access_control/policy_details/policy_details.tsx b/webapp/channels/src/components/admin_console/access_control/policy_details/policy_details.tsx index f85ab4d8b83..67113e6ca86 100644 --- a/webapp/channels/src/components/admin_console/access_control/policy_details/policy_details.tsx +++ b/webapp/channels/src/components/admin_console/access_control/policy_details/policy_details.tsx @@ -5,9 +5,9 @@ import cloneDeep from 'lodash/cloneDeep'; import React, {useState, useEffect, useMemo, type JSX} from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; +import {Button} from '@mattermost/compass-ui/components/button'; import {SectionNotice} from '@mattermost/compass-ui/components/section-notice'; import {GenericModal} from '@mattermost/components'; -import {buttonClassNames} from '@mattermost/shared/components/button'; import type {AccessControlPolicy, AccessControlPolicyActiveUpdate, AccessControlPolicyRule} from '@mattermost/types/access_control'; import {getMembershipRule, buildRulesWithMembership, getAutoAddFromRules} from '@mattermost/types/access_control'; import type {ChannelSearchOpts, ChannelWithTeamData} from '@mattermost/types/channels'; @@ -872,7 +872,7 @@ function PolicyDetails({ defaultMessage='Delete Policy' /> } - confirmButtonVariant='destructive' + destructive={true} compassDesign={true} > <> @@ -905,15 +905,17 @@ function PolicyDetails({ /> } /> - - - + + + + {serverError && ( diff --git a/webapp/channels/src/components/admin_console/admin_settings/__snapshots__/admin_setting.test.tsx.snap b/webapp/channels/src/components/admin_console/admin_settings/__snapshots__/admin_setting.test.tsx.snap index e0337db3539..e307547131c 100644 --- a/webapp/channels/src/components/admin_console/admin_settings/__snapshots__/admin_setting.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/admin_settings/__snapshots__/admin_setting.test.tsx.snap @@ -20,13 +20,15 @@ exports[`AdminSettings should match snapshot 1`] = ` class="admin-console-save" > diff --git a/webapp/channels/src/components/admin_console/admin_user_card/admin_user_card.scss b/webapp/channels/src/components/admin_console/admin_user_card/admin_user_card.scss index 702edeb15e1..999d7075444 100644 --- a/webapp/channels/src/components/admin_console/admin_user_card/admin_user_card.scss +++ b/webapp/channels/src/components/admin_console/admin_user_card/admin_user_card.scss @@ -83,9 +83,11 @@ input.AdminUserCard__picture-input[type='file'] { .AdminUserCard__footer { display: flex; flex-direction: row; + align-items: center; padding: 20px; border-top: solid 1px rgba(0, 0, 0, 0.2); background-color: #fff; + gap: 8px; } .AdminUserCard__user-info { diff --git a/webapp/channels/src/components/admin_console/audits/audits.tsx b/webapp/channels/src/components/admin_console/audits/audits.tsx index b8f70380c1a..9504fdeabb1 100644 --- a/webapp/channels/src/components/admin_console/audits/audits.tsx +++ b/webapp/channels/src/components/admin_console/audits/audits.tsx @@ -5,7 +5,7 @@ import React, {useEffect, useState, memo, useCallback} from 'react'; import type {CSSProperties} from 'react'; import {FormattedMessage, defineMessages} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {Audit} from '@mattermost/types/audits'; import type {ActionResult} from 'mattermost-redux/types/actions'; diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx index a07e7c6e76c..dcf58f3ecc5 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {buttonClassNames} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import {useOpenCloudZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm'; import ExternalLink from 'components/external_link'; @@ -28,16 +28,23 @@ const CancelSubscription = () => { defaultMessage='At this time, deleting a workspace can only be done with the help of a customer support representative.' /> - - - + + + + ); diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx index 70eab1e0bb1..a6113fce254 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button, buttonClassNames} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; import CloudTrialSvg from 'components/common/svg_images_components/cloud_trial_svg'; @@ -140,17 +140,21 @@ const ContactSalesCard = (props: Props) => { {description} {(isFreeTrial || subscriptionPlan === CloudProducts.ENTERPRISE || isCloudLegacyPlan) && - - - - + + + + } {(!isFreeTrial && subscriptionPlan !== CloudProducts.ENTERPRISE && subscriptionPlan !== CloudProducts.LEGACY) && ); @@ -115,17 +121,17 @@ export const FreeTrial = ({daysLeftOnTrial}: FreeTrialProps) => { /> } - + ); }; @@ -337,16 +343,18 @@ export const InvoiceInfo = ({invoice, product, fullCharges, partialCharges, hasM
- +
- }/>} > - - - + + + + ); @@ -41,15 +46,18 @@ const noCompanyInfoSection = ( defaultMessage='There is currently no company information on file.' /> - - - + + + + ); diff --git a/webapp/channels/src/components/admin_console/billing/company_info_edit.tsx b/webapp/channels/src/components/admin_console/billing/company_info_edit.tsx index e604772cd3e..f5472052f21 100644 --- a/webapp/channels/src/components/admin_console/billing/company_info_edit.tsx +++ b/webapp/channels/src/components/admin_console/billing/company_info_edit.tsx @@ -7,7 +7,7 @@ import {defineMessage, FormattedMessage} from 'react-intl'; import {useDispatch, useSelector} from 'react-redux'; import {useHistory} from 'react-router-dom'; -import {buttonClassNames} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import {getCloudCustomer, updateCloudCustomer, updateCloudCustomerAddress} from 'mattermost-redux/actions/cloud'; @@ -285,15 +285,17 @@ const CompanyInfoEdit: React.FC = () => { /> )} /> - - - + + + + ); diff --git a/webapp/channels/src/components/admin_console/billing/plan_details/plan_details.tsx b/webapp/channels/src/components/admin_console/billing/plan_details/plan_details.tsx index 31c6bc32a21..73526994209 100644 --- a/webapp/channels/src/components/admin_console/billing/plan_details/plan_details.tsx +++ b/webapp/channels/src/components/admin_console/billing/plan_details/plan_details.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import useOpenPricingModal from 'components/common/hooks/useOpenPricingModal'; import Tag from 'components/widgets/tag/tag'; diff --git a/webapp/channels/src/components/admin_console/blockable_button/blockable_button.tsx b/webapp/channels/src/components/admin_console/blockable_button/blockable_button.tsx deleted file mode 100644 index 229cc0a3f5d..00000000000 --- a/webapp/channels/src/components/admin_console/blockable_button/blockable_button.tsx +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React, {useCallback} from 'react'; -import type {MouseEvent} from 'react'; - -type Props = { - id?: string; - activeClassName?: string; - - // Bool whether navigation is blocked - blocked: boolean; - - actions: { - - // Function for deferring navigation while blocked - deferNavigation: (func: () => void) => void; - }; - children?: React.ReactNode; - className?: string; - onClick?: (e: React.MouseEvent) => void; - onCancelConfirmed: () => void; -}; - -const BlockableButton = ({blocked, actions, onClick, onCancelConfirmed, ...restProps}: Props) => { - const handleClick = useCallback((e: MouseEvent) => { - onClick?.(e); - - if (blocked) { - e.preventDefault(); - actions.deferNavigation(() => { - onCancelConfirmed(); - }); - } - }, [actions, blocked, onClick, onCancelConfirmed]); - - return ( - + ), [disabled, intl, handleDisableForAllTeams]); diff --git a/webapp/channels/src/components/admin_console/custom_plugin_settings/__snapshots__/custom_plugin_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/custom_plugin_settings/__snapshots__/custom_plugin_settings.test.tsx.snap index b6f71ffdd2b..7d7d7da4d42 100644 --- a/webapp/channels/src/components/admin_console/custom_plugin_settings/__snapshots__/custom_plugin_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/custom_plugin_settings/__snapshots__/custom_plugin_settings.test.tsx.snap @@ -349,10 +349,14 @@ exports[`components/admin_console/CustomPluginSettings should match snapshot wit class="help-text" >
@@ -488,13 +494,15 @@ exports[`components/admin_console/CustomPluginSettings should match snapshot wit class="admin-console-save" > @@ -856,10 +864,14 @@ exports[`components/admin_console/CustomPluginSettings should match snapshot wit class="help-text" >
diff --git a/webapp/channels/src/components/admin_console/custom_plugin_settings/enable_plugin_button.tsx b/webapp/channels/src/components/admin_console/custom_plugin_settings/enable_plugin_button.tsx index 2a04e2a9556..07684ce1492 100644 --- a/webapp/channels/src/components/admin_console/custom_plugin_settings/enable_plugin_button.tsx +++ b/webapp/channels/src/components/admin_console/custom_plugin_settings/enable_plugin_button.tsx @@ -171,7 +171,7 @@ export function PluginEnableButton({actions, disabled, homepageUrl, id, saveNeed defaultMessage='Are you sure you would like to remove the plugin?' /> } - confirmButtonVariant='destructive' + destructive={true} confirmButtonText={ diff --git a/webapp/channels/src/components/admin_console/data_retention_settings/__snapshots__/data_retention_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/data_retention_settings/__snapshots__/data_retention_settings.test.tsx.snap index 002ecfcf778..48a42496667 100644 --- a/webapp/channels/src/components/admin_console/data_retention_settings/__snapshots__/data_retention_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/data_retention_settings/__snapshots__/data_retention_settings.test.tsx.snap @@ -86,9 +86,14 @@ exports[`components/admin_console/data_retention_settings/data_retention_setting








@@ -426,13 +457,40 @@ exports[`components/admin_console/data_retention_settings/channel_list should ma class="Filter" >
diff --git a/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/__snapshots__/custom_policy_form.test.tsx.snap b/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/__snapshots__/custom_policy_form.test.tsx.snap index cce996a0fcd..5f2947b779e 100644 --- a/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/__snapshots__/custom_policy_form.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/__snapshots__/custom_policy_form.test.tsx.snap @@ -200,9 +200,14 @@ exports[`components/admin_console/data_retention_settings/custom_policy_form sho

@@ -598,21 +639,27 @@ exports[`components/admin_console/data_retention_settings/custom_policy_form sho class="admin-console-save" > - Cancel + + Cancel + @@ -814,9 +861,14 @@ exports[`components/admin_console/data_retention_settings/custom_policy_form sho

@@ -1236,21 +1324,27 @@ exports[`components/admin_console/data_retention_settings/custom_policy_form sho class="admin-console-save" > - Cancel + + Cancel + diff --git a/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/custom_policy_form.tsx b/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/custom_policy_form.tsx index 06e6911c3e9..f5b194242cc 100644 --- a/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/custom_policy_form.tsx +++ b/webapp/channels/src/components/admin_console/data_retention_settings/custom_policy_form/custom_policy_form.tsx @@ -5,7 +5,7 @@ import React, {type JSX} from 'react'; import {defineMessages, FormattedMessage, injectIntl} from 'react-intl'; import type {WrappedComponentProps} from 'react-intl'; -import {buttonClassNames} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {ChannelWithTeamData} from '@mattermost/types/channels'; import type { DataRetentionCustomPolicy, @@ -536,15 +536,17 @@ class CustomPolicyForm extends React.PureComponent { /> )} /> - - - + + + + {serverError && diff --git a/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/__snapshots__/global_policy_form.test.tsx.snap b/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/__snapshots__/global_policy_form.test.tsx.snap index 461d78ee141..beb4b31d9dc 100644 --- a/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/__snapshots__/global_policy_form.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/__snapshots__/global_policy_form.test.tsx.snap @@ -239,21 +239,27 @@ exports[`components/PluginManagement should match snapshot 1`] = ` class="admin-console-save" > - Cancel + + Cancel + diff --git a/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/global_policy_form.tsx b/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/global_policy_form.tsx index e6a7606401b..6cce8b7c540 100644 --- a/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/global_policy_form.tsx +++ b/webapp/channels/src/components/admin_console/data_retention_settings/global_policy_form/global_policy_form.tsx @@ -4,7 +4,7 @@ import React, {type JSX} from 'react'; import {defineMessages, FormattedMessage} from 'react-intl'; -import {buttonClassNames} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {AdminConfig, EnvironmentConfig} from '@mattermost/types/config'; import type {DeepPartial} from '@mattermost/types/utilities'; @@ -273,15 +273,17 @@ export default class GlobalPolicyForm extends React.PureComponent /> )} /> - - - + + + + {this.state.serverError && diff --git a/webapp/channels/src/components/admin_console/file_upload_setting.tsx b/webapp/channels/src/components/admin_console/file_upload_setting.tsx index 5b3fbebf00d..37d865b7971 100644 --- a/webapp/channels/src/components/admin_console/file_upload_setting.tsx +++ b/webapp/channels/src/components/admin_console/file_upload_setting.tsx @@ -4,7 +4,7 @@ import React, {memo, useCallback, useEffect, useRef, useState} from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import * as Utils from 'utils/utils'; diff --git a/webapp/channels/src/components/admin_console/filter/filter.scss b/webapp/channels/src/components/admin_console/filter/filter.scss index c3aac90eb1f..623aaf5b619 100644 --- a/webapp/channels/src/components/admin_console/filter/filter.scss +++ b/webapp/channels/src/components/admin_console/filter/filter.scss @@ -3,29 +3,14 @@ display: inline-block; padding-left: 8px; - .Filter_button { - width: auto; - height: 32px; - padding: 0 10px; - border: 0; - border-radius: 4px; - background: var(--sys-center-channel-bg); - color: var(--sys-button-bg); - font-size: 12px; - - &.Filter__active, - &:focus { - background: rgba(var(--sys-button-bg-rgb), 0.12); - } - - &:hover { - background: rgba(var(--sys-button-bg-rgb), 0.06); - } - } - - .Icon { - margin-right: 2px; - font-size: 14px; + // Held-open state. Compass's :active is momentary, so drive this off + // aria-expanded, which is already the source of truth for the popover. + // The :hover variant is spelled out because Compass's own hover rule has + // the same specificity as the bare one and would otherwise win on order, + // and the tint has to clear the 8% resting tertiary to read as a state. + .Filter_button[aria-expanded='true'], + .Filter_button[aria-expanded='true']:hover { + background-color: rgba(var(--link-color-rgb), 0.24); } .Filter_content { diff --git a/webapp/channels/src/components/admin_console/filter/filter.tsx b/webapp/channels/src/components/admin_console/filter/filter.tsx index 30c6ca4c86c..09bb2b2bf82 100644 --- a/webapp/channels/src/components/admin_console/filter/filter.tsx +++ b/webapp/channels/src/components/admin_console/filter/filter.tsx @@ -5,7 +5,9 @@ import classNames from 'classnames'; import React, {type JSX} from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {FilterVariantIcon} from '@mattermost/compass-icons/components'; +import {Button} from '@mattermost/compass-ui/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import FilterList from './filter_list'; @@ -190,20 +192,22 @@ class Filter extends React.PureComponent { className='Filter' ref={this.filterRef} > - +
{ +
)} diff --git a/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.scss b/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.scss index 6d1195040e1..998212a138c 100644 --- a/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.scss +++ b/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.scss @@ -54,7 +54,7 @@ } } -.btn.btn-sm.ChannelsResourceRow__remove { +.ChannelsResourceRow__remove { height: 32px; flex-shrink: 0; align-self: center; diff --git a/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.tsx b/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.tsx index b855a679a80..2640f23d061 100644 --- a/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.tsx +++ b/webapp/channels/src/components/admin_console/global_attributes/applies_to/channels/channels_resource_row.tsx @@ -6,7 +6,7 @@ import React, {useMemo, useState} from 'react'; import {defineMessages, FormattedMessage, useIntl} from 'react-intl'; import {ChevronDownIcon, ChevronRightIcon} from '@mattermost/compass-icons/components'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import ChannelsResourceSettings from './channels_resource_settings'; import {summarizeChannelResource} from './summary'; @@ -79,8 +79,8 @@ const ChannelsResourceRow = ({value, onChange, onRemove, ordered, disabled}: Pro {errorKind && ( ((props, ref) => { + const {children, ...rest} = props; + return ( + + ); +}); +ExternalSourceMenuTrigger.displayName = 'ExternalSourceMenuTrigger'; + const LINK_MODAL_IDS: Record = { ldap: ModalIdentifiers.ATTRIBUTE_MODAL_LDAP, saml: ModalIdentifiers.ATTRIBUTE_MODAL_SAML, @@ -231,15 +249,11 @@ function AttributeExternalSource({links, fieldType, onLink, disabled = false, di - - - - + ), dataTestId: 'attributeExternalSourceTrigger', }} diff --git a/webapp/channels/src/components/admin_console/global_attributes/attribute_details/attribute_remove_applies_to_warning_modal.tsx b/webapp/channels/src/components/admin_console/global_attributes/attribute_details/attribute_remove_applies_to_warning_modal.tsx index 92f60ac815a..83a1bbc38bf 100644 --- a/webapp/channels/src/components/admin_console/global_attributes/attribute_details/attribute_remove_applies_to_warning_modal.tsx +++ b/webapp/channels/src/components/admin_console/global_attributes/attribute_details/attribute_remove_applies_to_warning_modal.tsx @@ -79,7 +79,7 @@ function ConfirmRemoveAppliesToModal({resourceTypes, onConfirm, onCancel, onExit return ( { const confirm = screen.getByRole('button', {name: 'Delete'}); expect(confirm).toHaveClass('delete'); - expect(confirm).toHaveClass('btn-danger'); }); it('uses the singular surviving-child lead for the diamond fixture', () => { diff --git a/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/delete_modal.tsx b/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/delete_modal.tsx index b5f3d248e3b..211828b2250 100644 --- a/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/delete_modal.tsx +++ b/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/delete_modal.tsx @@ -177,7 +177,7 @@ function AttributeGraphDeleteModal({optionName, options, onConfirm, onExited}: P compassDesign={true} modalHeaderText={formatMessage(messages.safeTitle, {name: model.optionName})} confirmButtonText={formatMessage(messages.deleteValue)} - confirmButtonVariant='destructive' + destructive={true} handleCancel={noop} handleConfirm={onConfirm} onExited={onExited} diff --git a/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/draft_forms.tsx b/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/draft_forms.tsx index ff8a677c261..f9a253cb301 100644 --- a/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/draft_forms.tsx +++ b/webapp/channels/src/components/admin_console/global_attributes/attribute_details/graph/draft_forms.tsx @@ -5,7 +5,7 @@ import React from 'react'; import {defineMessages, FormattedMessage, useIntl} from 'react-intl'; import {PlusIcon} from '@mattermost/compass-icons/components'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import Input from 'components/widgets/inputs/input/input'; @@ -87,7 +87,7 @@ export const AddTopLevelForm = ({

@@ -520,13 +526,15 @@ export default function ClassificationAttribute({disabled = false}: Props): JSX. onClick={handleSave} defaultMessage={} /> - - - + + + + {saveFailed && ( { getHistory().push(ATTRIBUTE_DETAILS_ROUTE); }} data-testid='newAttributeButton' + leadingIcon={}/>} > - - - - +
diff --git a/webapp/channels/src/components/admin_console/group_settings/__snapshots__/group_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/group_settings/__snapshots__/group_settings.test.tsx.snap index 34a16ae2d4c..ca02083032a 100644 --- a/webapp/channels/src/components/admin_console/group_settings/__snapshots__/group_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/group_settings/__snapshots__/group_settings.test.tsx.snap @@ -104,13 +104,39 @@ For more information on Groups, please see class="group-list-link-unlink" >
diff --git a/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_details.test.tsx.snap b/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_details.test.tsx.snap index 085c2e680f1..e8653781894 100644 --- a/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_details.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_details.test.tsx.snap @@ -164,14 +164,18 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou class="MenuWrapper " > @@ -356,24 +360,32 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou 1 - 20 of 20 @@ -384,22 +396,28 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou class="admin-console-save" > - Cancel + + Cancel +
@@ -766,24 +788,32 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou 1 - 20 of 20 @@ -794,22 +824,28 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou class="admin-console-save" > - Cancel + + Cancel +
@@ -1174,24 +1214,32 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou 1 - 20 of 20 @@ -1202,22 +1250,28 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou class="admin-console-save" > - Cancel + + Cancel +
@@ -1580,24 +1638,32 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou 1 - 20 of 20 @@ -1608,22 +1674,28 @@ exports[`components/admin_console/group_settings/group_details/GroupDetails shou class="admin-console-save" > - Cancel + + Cancel +
@@ -113,11 +117,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -144,11 +152,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -175,11 +187,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -210,11 +226,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -285,11 +305,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -360,11 +384,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > diff --git a/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_teams_and_channels_row.test.tsx.snap b/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_teams_and_channels_row.test.tsx.snap index 2a7d0d36b25..5043cb77b8f 100644 --- a/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_teams_and_channels_row.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_teams_and_channels_row.test.tsx.snap @@ -71,11 +71,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -111,11 +115,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -170,11 +178,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -210,11 +222,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -254,11 +270,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > @@ -298,11 +318,15 @@ exports[`components/admin_console/group_settings/group_details/GroupTeamsAndChan class="text-right" > diff --git a/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_users.test.tsx.snap b/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_users.test.tsx.snap index ef9981811a8..b722f08f2ec 100644 --- a/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_users.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/group_settings/group_details/__snapshots__/group_users.test.tsx.snap @@ -855,24 +855,32 @@ exports[`components/admin_console/group_settings/group_details/GroupUsers should 1 - 20 of 20
@@ -1734,23 +1742,31 @@ exports[`components/admin_console/group_settings/group_details/GroupUsers should 1 - 20 of 55 @@ -2612,22 +2628,30 @@ exports[`components/admin_console/group_settings/group_details/GroupUsers should 21 - 40 of 55 @@ -3284,23 +3308,31 @@ exports[`components/admin_console/group_settings/group_details/GroupUsers should 41 - 55 of 55 @@ -4162,24 +4194,32 @@ exports[`components/admin_console/group_settings/group_details/GroupUsers should 1 - 20 of 20 @@ -5079,24 +5119,32 @@ exports[`components/admin_console/group_settings/group_details/GroupUsers should 1 - 20 of 20 @@ -5991,24 +6039,32 @@ exports[`components/admin_console/group_settings/group_details/GroupUsers should 1 - 20 of 20 diff --git a/webapp/channels/src/components/admin_console/group_settings/group_details/group_details.tsx b/webapp/channels/src/components/admin_console/group_settings/group_details/group_details.tsx index b1606632818..fa16559c3aa 100644 --- a/webapp/channels/src/components/admin_console/group_settings/group_details/group_details.tsx +++ b/webapp/channels/src/components/admin_console/group_settings/group_details/group_details.tsx @@ -5,7 +5,7 @@ import React, {type JSX} from 'react'; import type {WrappedComponentProps} from 'react-intl'; import {FormattedMessage, defineMessage, injectIntl} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {ChannelWithTeamData} from '@mattermost/types/channels'; import { SyncableType, diff --git a/webapp/channels/src/components/admin_console/group_settings/group_details/group_teams_and_channels_row.tsx b/webapp/channels/src/components/admin_console/group_settings/group_details/group_teams_and_channels_row.tsx index 4472f640ab3..3882ee4f052 100644 --- a/webapp/channels/src/components/admin_console/group_settings/group_details/group_teams_and_channels_row.tsx +++ b/webapp/channels/src/components/admin_console/group_settings/group_details/group_teams_and_channels_row.tsx @@ -6,7 +6,7 @@ import isNil from 'lodash/isNil'; import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import ConfirmModal from 'components/confirm_modal'; import GlobeIcon from 'components/widgets/icons/globe_icon'; diff --git a/webapp/channels/src/components/admin_console/group_settings/group_details/group_users.tsx b/webapp/channels/src/components/admin_console/group_settings/group_details/group_users.tsx index e02bdd4c3a2..e64c72c945b 100644 --- a/webapp/channels/src/components/admin_console/group_settings/group_details/group_users.tsx +++ b/webapp/channels/src/components/admin_console/group_settings/group_details/group_users.tsx @@ -6,7 +6,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; import {Link} from 'react-router-dom'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import {GroupSource, PluginGroupSourcePrefix} from '@mattermost/types/groups'; import type {UserProfile} from '@mattermost/types/users'; diff --git a/webapp/channels/src/components/admin_console/group_settings/groups_list/__snapshots__/groups_list.test.tsx.snap b/webapp/channels/src/components/admin_console/group_settings/groups_list/__snapshots__/groups_list.test.tsx.snap index 26c6d0f61c1..296df94a0f4 100644 --- a/webapp/channels/src/components/admin_console/group_settings/groups_list/__snapshots__/groups_list.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/group_settings/groups_list/__snapshots__/groups_list.test.tsx.snap @@ -43,13 +43,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -201,22 +227,53 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna @@ -277,13 +334,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -483,24 +566,32 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 1 - 2 of 2 @@ -550,13 +641,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -730,24 +847,32 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 1 - 2 of 2 @@ -797,13 +922,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -977,24 +1128,32 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 1 - 2 of 2 @@ -1044,13 +1203,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -1256,24 +1441,32 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 1 - 3 of 3 @@ -1323,13 +1516,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -1892,23 +2111,31 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 1 - 200 of 401 @@ -1958,13 +2185,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -2527,22 +2780,30 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 201 - 400 of 401 @@ -2592,13 +2853,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -2804,22 +3091,30 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 201 - 400 of 401 @@ -2869,13 +3164,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -2936,13 +3257,39 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna class="group-list-link-unlink" > @@ -3090,24 +3437,32 @@ exports[`components/admin_console/group_settings/GroupsList.tsx should match sna 1 - 2 of 2 diff --git a/webapp/channels/src/components/admin_console/group_settings/groups_list/groups_list.tsx b/webapp/channels/src/components/admin_console/group_settings/groups_list/groups_list.tsx index 4e6cdc0338d..c9156462a2b 100644 --- a/webapp/channels/src/components/admin_console/group_settings/groups_list/groups_list.tsx +++ b/webapp/channels/src/components/admin_console/group_settings/groups_list/groups_list.tsx @@ -5,8 +5,10 @@ import classNames from 'classnames'; import React, {type JSX} from 'react'; import {defineMessage, FormattedMessage} from 'react-intl'; +import {LinkVariantIcon, LinkVariantOffIcon} from '@mattermost/compass-icons/components'; +import {Button} from '@mattermost/compass-ui/components/button'; import {Checkbox} from '@mattermost/compass-ui/components/checkbox'; -import {Button} from '@mattermost/shared/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import type {GroupSearchOpts, MixedUnlinkedGroupRedux} from '@mattermost/types/groups'; import type {ActionResult} from 'mattermost-redux/types/actions'; @@ -164,8 +166,8 @@ export default class GroupsList extends React.PureComponent { emphasis='primary' onClick={() => this.linkSelectedGroups()} disabled={this.props.readOnly} + leadingIcon={}/>} > - { emphasis='primary' onClick={() => this.unlinkSelectedGroups()} disabled={this.props.readOnly} + leadingIcon={}/>} > - { type='button' emphasis='primary' disabled={this.props.readOnly} + leadingIcon={}/>} > - onConfirm?.(filterToDelete!)} > {formatMessage({id: 'admin.ip_filtering.delete_filter', defaultMessage: 'Delete filter'})} diff --git a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_header.tsx b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_header.tsx index 613a374d457..12f20a6bc67 100644 --- a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_header.tsx +++ b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_header.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import IPNotInRangeErrorPanel from './edit_section_ip_not_in_range_panel'; diff --git a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_ip_not_in_range_panel.tsx b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_ip_not_in_range_panel.tsx index 4b29de9d659..8a2274e2b14 100644 --- a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_ip_not_in_range_panel.tsx +++ b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_ip_not_in_range_panel.tsx @@ -5,8 +5,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; import {AlertOutlineIcon} from '@mattermost/compass-icons/components'; -import {Button} from '@mattermost/shared/components/button'; - +import {Button} from '@mattermost/compass-ui/components/button'; type IPNotInRangeErrorPanelProps = { currentUsersIP: string | null; setShowAddModal: (show: boolean) => void; diff --git a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_no_filters_panel.tsx b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_no_filters_panel.tsx index cd311c1fbe8..f7b8fbb4b01 100644 --- a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_no_filters_panel.tsx +++ b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_section_no_filters_panel.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import IPFilteringEarthSvg from 'components/common/svg_images_components/ip_filtering_earth_svg'; diff --git a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_sections.scss b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_sections.scss index b9edd246441..39b55c52d10 100644 --- a/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_sections.scss +++ b/webapp/channels/src/components/admin_console/ip_filtering/edit_section/edit_sections.scss @@ -143,12 +143,8 @@ line-height: 20px; text-align: center; - .btn-primary { + button { margin-top: 16px; - - &:hover { - cursor: pointer; - } } } } diff --git a/webapp/channels/src/components/admin_console/ip_filtering/ip_filtering.scss b/webapp/channels/src/components/admin_console/ip_filtering/ip_filtering.scss index d957fc9b686..f2e2f637b50 100644 --- a/webapp/channels/src/components/admin_console/ip_filtering/ip_filtering.scss +++ b/webapp/channels/src/components/admin_console/ip_filtering/ip_filtering.scss @@ -1,12 +1,6 @@ .IPFiltering { height: 100%; - .admin-console-save { - .btn.btn-primary:disabled { - color: rgba(var(--center-channel-color-rgb), 0.32) !important; - } - } - .MainPanel { display: flex; height: 100%; diff --git a/webapp/channels/src/components/admin_console/ip_filtering/save_confirmation_modal.tsx b/webapp/channels/src/components/admin_console/ip_filtering/save_confirmation_modal.tsx index 6a4323250ff..4c9c22b091b 100644 --- a/webapp/channels/src/components/admin_console/ip_filtering/save_confirmation_modal.tsx +++ b/webapp/channels/src/components/admin_console/ip_filtering/save_confirmation_modal.tsx @@ -6,7 +6,7 @@ import {Modal} from 'react-bootstrap'; import {FormattedMessage, useIntl} from 'react-intl'; import {InformationOutlineIcon} from '@mattermost/compass-icons/components'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import ExternalLink from 'components/external_link'; @@ -77,7 +77,7 @@ export default function SaveConfirmationModal({onExited, onConfirm, title, subti data-testid='save-confirmation-button' type='button' emphasis='primary' - variant='destructive' + destructive={true} onClick={() => onConfirm?.()} > {buttonText} diff --git a/webapp/channels/src/components/admin_console/jobs/table.scss b/webapp/channels/src/components/admin_console/jobs/table.scss index 6c01b5aeae6..11d88c272ab 100644 --- a/webapp/channels/src/components/admin_console/jobs/table.scss +++ b/webapp/channels/src/components/admin_console/jobs/table.scss @@ -34,7 +34,7 @@ background-color: rgba(0, 0, 0, 0.05); .view-details-link { - color: var(--button-bg); + --button-fg: var(--button-bg); } } @@ -48,24 +48,22 @@ text-align: right; } - .view-details-link.btn { - display: inline-flex; - align-items: center; + // Muted at rest so the row hover has something to reveal. Compass + // quaternary is --link-color out of the box, which left the link already + // blue and the hover a no-op. Colours go through --button-fg because the + // Compass label does not read `color`. + .view-details-link { + --button-fg: rgba(var(--sys-center-channel-color-rgb), 0.56); + padding: 0; background: transparent; - color: rgba(var(--sys-center-channel-color-rgb), 0.56); - font-size: 12px; - font-weight: 600; white-space: nowrap; &:hover, &:focus { - background: transparent; - color: var(--button-bg); - } + --button-fg: var(--button-bg); - .icon { - font-size: 16px; + background: transparent; } } diff --git a/webapp/channels/src/components/admin_console/jobs/table.tsx b/webapp/channels/src/components/admin_console/jobs/table.tsx index 86dd621ce5e..26b6776f0aa 100644 --- a/webapp/channels/src/components/admin_console/jobs/table.tsx +++ b/webapp/channels/src/components/admin_console/jobs/table.tsx @@ -5,7 +5,9 @@ import classNames from 'classnames'; import React, {type JSX} from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {ChevronRightIcon} from '@mattermost/compass-icons/components'; +import {Button} from '@mattermost/compass-ui/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import type {Job, JobType} from '@mattermost/types/jobs'; import type {ActionResult} from 'mattermost-redux/types/actions'; @@ -153,8 +155,9 @@ class JobTable extends React.PureComponent { )} diff --git a/webapp/channels/src/components/admin_console/license_settings/__snapshots__/license_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/license_settings/__snapshots__/license_settings.test.tsx.snap index 3ee15dd09a4..fc2029202b1 100644 --- a/webapp/channels/src/components/admin_console/license_settings/__snapshots__/license_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/license_settings/__snapshots__/license_settings.test.tsx.snap @@ -86,9 +86,14 @@ exports[`components/admin_console/license_settings/LicenseSettings load screen a class="purchase-card" > @@ -463,10 +468,14 @@ exports[`components/admin_console/license_settings/LicenseSettings load screen a

@@ -566,9 +575,14 @@ exports[`components/admin_console/license_settings/LicenseSettings load screen w class="purchase-card" > @@ -940,18 +954,24 @@ exports[`components/admin_console/license_settings/LicenseSettings load screen w

@@ -1068,9 +1088,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" >

@@ -1103,10 +1128,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -1611,15 +1655,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
@@ -1731,9 +1776,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" > @@ -1766,10 +1816,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -2274,15 +2343,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
@@ -2380,9 +2450,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" > @@ -2415,10 +2490,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -2939,15 +3033,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
@@ -3045,9 +3140,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" > @@ -3080,10 +3180,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -3588,15 +3707,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
@@ -3694,9 +3814,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" > @@ -3729,10 +3854,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -4238,15 +4382,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
@@ -4344,9 +4489,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" > @@ -4379,10 +4529,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -4893,15 +5062,16 @@ exports[`components/admin_console/license_settings/LicenseSettings should match
-
- -
+ +
@@ -5026,10 +5196,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -5461,15 +5650,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
@@ -5580,10 +5770,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="trial" > @@ -5604,10 +5798,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="StarterLeftPanel" >
@@ -6121,10 +6330,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="trial" > @@ -6145,10 +6358,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="StarterLeftPanel" >
@@ -6669,9 +6897,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" > @@ -7043,10 +7276,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -8100,10 +8360,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -8608,15 +8887,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
@@ -8714,9 +8994,14 @@ exports[`components/admin_console/license_settings/LicenseSettings should match class="purchase-card" > @@ -8749,10 +9034,15 @@ exports[`components/admin_console/license_settings/LicenseSettings should match

@@ -9257,15 +9561,16 @@ See ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. S
-
- -
+ +
diff --git a/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition.scss b/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition.scss index bd3fa16b169..5001ca8f47f 100644 --- a/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition.scss +++ b/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition.scss @@ -37,14 +37,14 @@ } .purchase_buttons { + display: flex; + flex-direction: column; margin-top: 20px; - .btn-primary { - margin-bottom: 8px; - } + gap: 8px; .trial-btn { width: 100%; - margin-left: 0px; + margin-left: 0; } } @@ -173,21 +173,7 @@ } #remove-button { - padding: 0; - border: none !important; margin: 10px 0; - background: none !important; - color: var(--error-text); - font-weight: 700; - - &:hover { - text-decoration: underline; - } - - &:focus, - &:focus-visible { - outline: none !important; - } } } diff --git a/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition_left_panel.tsx b/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition_left_panel.tsx index edcf00330de..9a8f890d6a2 100644 --- a/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition_left_panel.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition_left_panel.tsx @@ -7,8 +7,10 @@ import type {JSX, RefObject} from 'react'; import {FormattedDate, FormattedMessage, FormattedNumber, FormattedTime, defineMessage, defineMessages, useIntl} from 'react-intl'; import {useSelector} from 'react-redux'; +import {UploadOutlineIcon} from '@mattermost/compass-icons/components'; import AlertOutlineIcon from '@mattermost/compass-icons/components/alert-outline'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import {WithTooltip} from '@mattermost/shared/components/tooltip'; import type {ClientLicense} from '@mattermost/types/config'; @@ -98,7 +100,7 @@ const EnterpriseEditionLeftPanel = ({ id='enterprise_edition_view_plans' onClick={openPricingModal} emphasis='tertiary' - size='sm' + size='small' className='PlanDetails__viewPlansButton' > {formatMessage({ @@ -167,8 +169,8 @@ const EnterpriseEditionLeftPanel = ({ emphasis='primary' onClick={() => fileInputRef.current?.click()} disabled={isLicenseSetByEnvVar} + leadingIcon={}/>} > - {'License details'}
); const title = () => { diff --git a/webapp/channels/src/components/admin_console/license_settings/modals/confirm_license_removal_modal.tsx b/webapp/channels/src/components/admin_console/license_settings/modals/confirm_license_removal_modal.tsx index 6a205a49928..0a04bf009cd 100644 --- a/webapp/channels/src/components/admin_console/license_settings/modals/confirm_license_removal_modal.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/modals/confirm_license_removal_modal.tsx @@ -5,8 +5,8 @@ import React, {type JSX} from 'react'; import {FormattedMessage} from 'react-intl'; import {useSelector, useDispatch} from 'react-redux'; +import {Button} from '@mattermost/compass-ui/components/button'; import {GenericModal} from '@mattermost/components'; -import {Button} from '@mattermost/shared/components/button'; import {closeModal} from 'actions/views/modals'; import {isModalOpen} from 'selectors/views/modals'; diff --git a/webapp/channels/src/components/admin_console/license_settings/modals/ee_license_modal.tsx b/webapp/channels/src/components/admin_console/license_settings/modals/ee_license_modal.tsx index c6ca0cb9e4b..eb5b9ffce43 100644 --- a/webapp/channels/src/components/admin_console/license_settings/modals/ee_license_modal.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/modals/ee_license_modal.tsx @@ -4,8 +4,8 @@ import React, {type JSX} from 'react'; import {useSelector, useDispatch} from 'react-redux'; +import {Button} from '@mattermost/compass-ui/components/button'; import {GenericModal} from '@mattermost/components'; -import {Button} from '@mattermost/shared/components/button'; import {closeModal} from 'actions/views/modals'; import {isModalOpen} from 'selectors/views/modals'; diff --git a/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.scss b/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.scss index 9e84166f266..d416e21a1e8 100644 --- a/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.scss +++ b/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.scss @@ -96,6 +96,12 @@ &.preview-footer { flex-direction: row; + // The 8px between Cancel and Apply used to come from the global + // `.btn + .btn` rule in _buttons.scss, which the Compass buttons + // no longer match. This footer is not a .modal-footer, so it does + // not pick up that gap either. + gap: 8px; + button { margin-top: 0 !important; } diff --git a/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.tsx b/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.tsx index 9a19d6dbf45..cc8e6281833 100644 --- a/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/modals/upload_license_modal.tsx @@ -5,8 +5,8 @@ import React, {useEffect, useCallback, type JSX} from 'react'; import {defineMessage, FormattedDate, FormattedMessage, useIntl} from 'react-intl'; import {useSelector, useDispatch} from 'react-redux'; +import {Button} from '@mattermost/compass-ui/components/button'; import {GenericModal} from '@mattermost/components'; -import {Button} from '@mattermost/shared/components/button'; import type {ClientLicense, License} from '@mattermost/types/config'; import {previewLicense, uploadLicense} from 'mattermost-redux/actions/admin'; @@ -248,18 +248,20 @@ const UploadLicenseModal = (props: Props): JSX.Element | null => { emphasis='primary' onClick={handleConfirmUpload} disabled={isLoading} + loading={Boolean(isLoading)} id='confirm-button' > - + {isLoading ? ( + + ) : ( - + )} diff --git a/webapp/channels/src/components/admin_console/license_settings/starter_edition/starter_left_panel.tsx b/webapp/channels/src/components/admin_console/license_settings/starter_edition/starter_left_panel.tsx index e418ae4e191..52cb4f1c9ea 100644 --- a/webapp/channels/src/components/admin_console/license_settings/starter_edition/starter_left_panel.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/starter_edition/starter_left_panel.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type {JSX, RefObject} from 'react'; import {FormattedMessage, defineMessages, useIntl} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import useOpenPricingModal from 'components/common/hooks/useOpenPricingModal'; @@ -39,7 +39,7 @@ const StarterLeftPanel: React.FC = ({ id='starter_edition_view_plans' onClick={openPricingModal} emphasis='tertiary' - size='sm' + size='small' className='PlanDetails__viewPlansButton' > {intl.formatMessage({ diff --git a/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition.scss b/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition.scss index d200a9a07ca..5a1106a4c40 100644 --- a/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition.scss +++ b/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition.scss @@ -34,7 +34,8 @@ } } - button, a.btn { + button, + p:not(.upgrade-legal-terms) a { width: 100%; border-radius: 4px; margin: 5px auto; diff --git a/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition_right_panel.tsx b/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition_right_panel.tsx index f92359a18b1..9946a657708 100644 --- a/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition_right_panel.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/team_edition/team_edition_right_panel.tsx @@ -4,11 +4,10 @@ import React from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; -import {Button, buttonClassNames} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import SetupSystemSvg from 'components/common/svg_images_components/setup_system_svg'; import ExternalLink from 'components/external_link'; -import LoadingWrapper from 'components/widgets/loading/loading_wrapper'; import {LicenseLinks} from 'utils/constants'; import {format} from 'utils/markdown'; @@ -61,17 +60,21 @@ const TeamEditionRightPanel: React.FC = ({ upgradeButton = (

- - - + + + +

); @@ -83,23 +86,20 @@ const TeamEditionRightPanel: React.FC = ({ type='button' onClick={onHandleUpgrade} emphasis='primary' + loading={upgradingPercentage > 0} > - 0} - text={ - - } - > + {upgradingPercentage > 0 ? ( + + ) : ( - + )}

@@ -152,20 +152,19 @@ const TeamEditionRightPanel: React.FC = ({ type='button' onClick={handleRestart} emphasis='primary' + loading={restarting} > - + }) + ) : ( - + )}

{restartError && ( diff --git a/webapp/channels/src/components/admin_console/license_settings/trial_banner/trial_banner.tsx b/webapp/channels/src/components/admin_console/license_settings/trial_banner/trial_banner.tsx index 425ccf8ba04..c744bdc76a8 100644 --- a/webapp/channels/src/components/admin_console/license_settings/trial_banner/trial_banner.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/trial_banner/trial_banner.tsx @@ -5,7 +5,7 @@ import React, {useEffect, useState} from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; import {useDispatch, useSelector} from 'react-redux'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import {savePreferences} from 'mattermost-redux/actions/preferences'; import {getBool as getBoolPreference} from 'mattermost-redux/selectors/entities/preferences'; @@ -14,7 +14,6 @@ import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; import AlertBanner from 'components/alert_banner'; import withOpenStartTrialFormModal from 'components/common/hocs/cloud/with_open_start_trial_form_modal'; import ExternalLink from 'components/external_link'; -import LoadingWrapper from 'components/widgets/loading/loading_wrapper'; import {AboutLinks, LicenseLinks, Preferences, Unique} from 'utils/constants'; import {format} from 'utils/markdown'; @@ -301,32 +300,38 @@ const TrialBanner = ({ ); } else { gettingTrialErrorMsg = null; + + let trialButtonLabel = ( + + ); + if (upgradingPercentage === 100 && restarting) { + trialButtonLabel = ( + + ); + } else if (upgradingPercentage > 0) { + trialButtonLabel = ( + + ); + } + trialButton = ( ); diff --git a/webapp/channels/src/components/admin_console/manage_roles_modal/manage_roles_modal.tsx b/webapp/channels/src/components/admin_console/manage_roles_modal/manage_roles_modal.tsx index de0671a823d..a15efc11c2b 100644 --- a/webapp/channels/src/components/admin_console/manage_roles_modal/manage_roles_modal.tsx +++ b/webapp/channels/src/components/admin_console/manage_roles_modal/manage_roles_modal.tsx @@ -6,7 +6,7 @@ import {Modal} from 'react-bootstrap'; import {FormattedMessage} from 'react-intl'; import {Link} from 'react-router-dom'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {Role} from '@mattermost/types/roles'; import type {UserProfile} from '@mattermost/types/users'; diff --git a/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/remove_from_team_button.test.tsx.snap b/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/remove_from_team_button.test.tsx.snap index 367736b3763..6dd1ce7ec8d 100644 --- a/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/remove_from_team_button.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/remove_from_team_button.test.tsx.snap @@ -3,10 +3,14 @@ exports[`RemoveFromTeamButton should match snapshot init 1`] = `
`; diff --git a/webapp/channels/src/components/admin_console/manage_teams_modal/remove_from_team_button.tsx b/webapp/channels/src/components/admin_console/manage_teams_modal/remove_from_team_button.tsx index 4b25c46a647..b38403ab081 100644 --- a/webapp/channels/src/components/admin_console/manage_teams_modal/remove_from_team_button.tsx +++ b/webapp/channels/src/components/admin_console/manage_teams_modal/remove_from_team_button.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; type Props = { teamId: string; @@ -20,7 +20,7 @@ const RemoveFromTeamButton = ({teamId, handleRemoveUserFromTeam}: Props) => { return ( @@ -317,10 +321,14 @@ exports[`components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx sh class="manage-teams__team-actions" > diff --git a/webapp/channels/src/components/admin_console/openid_convert/__snapshots__/openid_convert.test.tsx.snap b/webapp/channels/src/components/admin_console/openid_convert/__snapshots__/openid_convert.test.tsx.snap index b23f7b9e4e4..af247b0baf4 100644 --- a/webapp/channels/src/components/admin_console/openid_convert/__snapshots__/openid_convert.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/openid_convert/__snapshots__/openid_convert.test.tsx.snap @@ -24,20 +24,29 @@ exports[`components/OpenIdConvert should match snapshot 1`] = ` class="OpenIdConvert_actionWrapper" > - Learn more + + Learn more +

- - +
((props, ref) => { + const {children, ...rest} = props; + return ( + + ); +}); +AddPermissionMenuTrigger.displayName = 'AddPermissionMenuTrigger'; + const roleMessages = defineMessages({ guestLabel: {id: 'admin.permission_policies.role.system_guest.label', defaultMessage: 'Guest users'}, guestDescription: {id: 'admin.permission_policies.role.system_guest.description', defaultMessage: 'Applies only to guest users'}, @@ -455,6 +475,7 @@ function PermissionPolicyDetails({ {/* "Who this policy applies to" */} @@ -528,6 +549,7 @@ function PermissionPolicyDetails({ {/* Attribute-based access rules */} @@ -664,6 +686,7 @@ function PermissionPolicyDetails({ {/* "What permissions are modified" */} @@ -728,15 +751,12 @@ function PermissionPolicyDetails({ - - - + ), }} menu={{ @@ -769,6 +789,7 @@ function PermissionPolicyDetails({ {policyId && ( @@ -791,6 +812,7 @@ function PermissionPolicyDetails({ defaultMessage='Delete' /> } + destructive={true} onClick={() => setShowDeleteConfirmationModal(true)} /> @@ -816,7 +838,7 @@ function PermissionPolicyDetails({ defaultMessage='Delete Policy' /> } - confirmButtonVariant='destructive' + destructive={true} compassDesign={true} > } /> - - - + + + + {serverError && ( diff --git a/webapp/channels/src/components/admin_console/permission_schemes_settings/__snapshots__/permission_schemes_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/permission_schemes_settings/__snapshots__/permission_schemes_settings.test.tsx.snap index 1a51f86d033..92268038635 100644 --- a/webapp/channels/src/components/admin_console/permission_schemes_settings/__snapshots__/permission_schemes_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/permission_schemes_settings/__snapshots__/permission_schemes_settings.test.tsx.snap @@ -95,11 +95,15 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - Edit Scheme + + Edit Scheme +
@@ -134,11 +138,15 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - New Team Override Scheme + + New Team Override Scheme +
@@ -333,11 +341,15 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - Edit Scheme + + Edit Scheme + @@ -372,11 +384,15 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - New Team Override Scheme + + New Team Override Scheme + @@ -459,11 +475,16 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - Edit Scheme + + Edit Scheme + @@ -498,11 +519,16 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - New Team Override Scheme + + New Team Override Scheme + @@ -715,11 +741,16 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - Edit Scheme + + Edit Scheme + @@ -754,11 +785,16 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - New Team Override Scheme + + New Team Override Scheme + @@ -971,11 +1007,15 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - Edit Scheme + + Edit Scheme + @@ -1010,11 +1050,15 @@ exports[`components/admin_console/permission_schemes_settings/permission_schemes class="button" > - New Team Override Scheme + + New Team Override Scheme + diff --git a/webapp/channels/src/components/admin_console/permission_schemes_settings/edit_post_time_limit_modal/edit_post_time_limit_modal.tsx b/webapp/channels/src/components/admin_console/permission_schemes_settings/edit_post_time_limit_modal/edit_post_time_limit_modal.tsx index 1a5a6841aa0..7a10287133a 100644 --- a/webapp/channels/src/components/admin_console/permission_schemes_settings/edit_post_time_limit_modal/edit_post_time_limit_modal.tsx +++ b/webapp/channels/src/components/admin_console/permission_schemes_settings/edit_post_time_limit_modal/edit_post_time_limit_modal.tsx @@ -5,7 +5,7 @@ import React, {useState} from 'react'; import {Modal} from 'react-bootstrap'; import {FormattedMessage, useIntl} from 'react-intl'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {AdminConfig} from '@mattermost/types/config'; import type {DeepPartial} from '@mattermost/types/utilities'; diff --git a/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/__snapshots__/permission_system_scheme_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/__snapshots__/permission_system_scheme_settings.test.tsx.snap index 7bc60e4d5ff..56e63b00c5f 100644 --- a/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/__snapshots__/permission_system_scheme_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/__snapshots__/permission_system_scheme_settings.test.tsx.snap @@ -4206,28 +4206,39 @@ exports[`components/admin_console/permission_schemes_settings/permission_system_ class="admin-console-save" > - Cancel + + Cancel +
- Cancel + + Cancel +
- Cancel + + Cancel +
- Cancel + + Cancel +
, ); expect(ref.current!.state.showResetDefaultModal).toBe(false); - const resetButton = container.querySelector('.btn-quaternary'); + const resetButton = container.querySelector('[data-testid="resetPermissionsToDefault"]'); expect(resetButton).not.toBeNull(); act(() => { (resetButton as HTMLElement).click(); diff --git a/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/permission_system_scheme_settings.tsx b/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/permission_system_scheme_settings.tsx index 77021deb24a..668142721af 100644 --- a/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/permission_system_scheme_settings.tsx +++ b/webapp/channels/src/components/admin_console/permission_schemes_settings/permission_system_scheme_settings/permission_system_scheme_settings.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type {WrappedComponentProps} from 'react-intl'; import {FormattedMessage, defineMessage, injectIntl} from 'react-intl'; -import {Button, buttonClassNames} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import type {ClientConfig, ClientLicense} from '@mattermost/types/config'; import type {Role} from '@mattermost/types/roles'; @@ -543,16 +543,18 @@ export class PermissionSystemSchemeSettings extends React.PureComponent - - - + + + +
diff --git a/webapp/channels/src/components/admin_console/plugin_management/__snapshots__/plugin_management.test.tsx.snap b/webapp/channels/src/components/admin_console/plugin_management/__snapshots__/plugin_management.test.tsx.snap index 616b4c86bb5..54f59a01302 100644 --- a/webapp/channels/src/components/admin_console/plugin_management/__snapshots__/plugin_management.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/plugin_management/__snapshots__/plugin_management.test.tsx.snap @@ -554,13 +554,15 @@ exports[`components/PluginManagement should match snapshot 1`] = ` class="admin-console-save" > @@ -1130,13 +1132,15 @@ exports[`components/PluginManagement should match snapshot when \`Enable Marketp class="admin-console-save" > @@ -1203,13 +1207,15 @@ exports[`components/PluginManagement should match snapshot when \`Enable Plugins class="admin-console-save" > @@ -1777,13 +1783,15 @@ exports[`components/PluginManagement should match snapshot when \`Enable Remote class="admin-console-save" > @@ -2359,13 +2367,15 @@ exports[`components/PluginManagement should match snapshot when \`Require Signat class="admin-console-save" > @@ -2933,13 +2943,15 @@ exports[`components/PluginManagement should match snapshot, No installed plugins class="admin-console-save" > @@ -3506,13 +3518,15 @@ exports[`components/PluginManagement should match snapshot, allow insecure URL e class="admin-console-save" > @@ -4082,13 +4096,15 @@ exports[`components/PluginManagement should match snapshot, disabled 1`] = ` class="admin-console-save" > @@ -4655,13 +4671,15 @@ exports[`components/PluginManagement should match snapshot, text entered into th class="admin-console-save" > @@ -5249,13 +5267,15 @@ exports[`components/PluginManagement should match snapshot, upload disabled 1`] class="admin-console-save" > @@ -6105,13 +6125,15 @@ exports[`components/PluginManagement should match snapshot, with installed plugi class="admin-console-save" > @@ -6759,13 +6781,15 @@ exports[`components/PluginManagement should match snapshot, with installed plugi class="admin-console-save" > @@ -7413,13 +7437,15 @@ exports[`components/PluginManagement should match snapshot, with installed plugi class="admin-console-save" > @@ -8067,13 +8093,15 @@ exports[`components/PluginManagement should match snapshot, with installed plugi class="admin-console-save" > @@ -8907,13 +8935,15 @@ exports[`components/PluginManagement should match snapshot, with installed plugi class="admin-console-save" > diff --git a/webapp/channels/src/components/admin_console/plugin_management/plugin_management.tsx b/webapp/channels/src/components/admin_console/plugin_management/plugin_management.tsx index 2b3f4a99c22..ad6c575c0e7 100644 --- a/webapp/channels/src/components/admin_console/plugin_management/plugin_management.tsx +++ b/webapp/channels/src/components/admin_console/plugin_management/plugin_management.tsx @@ -1020,7 +1020,7 @@ export class PluginManagement extends OLDAdminSettings { show={show} title={title} message={message} - confirmButtonVariant='destructive' + destructive={true} confirmButtonText={removeButton} onConfirm={onConfirm} onCancel={onCancel} diff --git a/webapp/channels/src/components/admin_console/plugin_management/plugin_upload_overwrite_review_modal.tsx b/webapp/channels/src/components/admin_console/plugin_management/plugin_upload_overwrite_review_modal.tsx index f0b4e8a610d..0fd27ff35db 100644 --- a/webapp/channels/src/components/admin_console/plugin_management/plugin_upload_overwrite_review_modal.tsx +++ b/webapp/channels/src/components/admin_console/plugin_management/plugin_upload_overwrite_review_modal.tsx @@ -143,7 +143,7 @@ export default function PluginUploadOverwriteReviewModal({show, conflict, onConf show={show} title={title} message={renderReviewMessage(conflict)} - confirmButtonVariant={direction === 'downgrade' ? 'destructive' : undefined} + destructive={direction === 'downgrade'} confirmButtonText={overwriteButton} onConfirm={onConfirm} onCancel={onCancel} diff --git a/webapp/channels/src/components/admin_console/remove_file_setting.tsx b/webapp/channels/src/components/admin_console/remove_file_setting.tsx index a18be557625..18a788ae5ea 100644 --- a/webapp/channels/src/components/admin_console/remove_file_setting.tsx +++ b/webapp/channels/src/components/admin_console/remove_file_setting.tsx @@ -4,7 +4,7 @@ import React, {memo, useCallback, useState} from 'react'; import type {FC, MouseEvent} from 'react'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; import Setting from './setting'; import type {Props as SettingsProps} from './setting'; @@ -53,7 +53,7 @@ const RemoveFileSetting: FC = ({
{ emphasis={this.props.buttonEmphasis || 'tertiary'} onClick={this.handleRequest} disabled={this.props.disabled} + loading={this.state.busy} > - - ) - } - > - {this.props.buttonText} - + {this.state.busy ? ( + this.props.loadingText || + ( + + ) + ) : this.props.buttonText} {this.props.alternativeActionElement} {message} diff --git a/webapp/channels/src/components/admin_console/revoke_non_compliant_tokens_button/revoke_non_compliant_tokens_button.tsx b/webapp/channels/src/components/admin_console/revoke_non_compliant_tokens_button/revoke_non_compliant_tokens_button.tsx index 261f162f1a6..233d69b636a 100644 --- a/webapp/channels/src/components/admin_console/revoke_non_compliant_tokens_button/revoke_non_compliant_tokens_button.tsx +++ b/webapp/channels/src/components/admin_console/revoke_non_compliant_tokens_button/revoke_non_compliant_tokens_button.tsx @@ -4,6 +4,8 @@ import React, {useCallback, useEffect, useState} from 'react'; import {FormattedMessage} from 'react-intl'; +import {Button} from '@mattermost/compass-ui/components/button'; + import {Client4} from 'mattermost-redux/client'; import AlertBanner from 'components/alert_banner'; @@ -96,9 +98,9 @@ const RevokeNonCompliantTokensButton = ({disabled, registerSaveAction, unRegiste className='RevokeNonCompliantTokensButton' style={{display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: '8px'}} > - + {error && ( )} - confirmButtonVariant='destructive' + destructive={true} confirmButtonText={( { return ( + {showCancel && ( + cancelLink ? ( + + ) : ( + + ) )}
; -export const LinkButton = styled.button.attrs({className: 'btn btn-link'})<{$destructive?: boolean}>` - font-weight: normal; - ${({$destructive}) => $destructive && css` - && { - color: #D24B4E; - } - `}; -`; +export const Button = ({style, ...props}: CompassButtonProps) => ( + +); + +export const LinkButton = ({ + $destructive, + style, + ...props +}: CompassButtonProps & {$destructive?: boolean}) => ( + +); export const ConnectionStatusLabel = ({rc}: {rc: RemoteCluster}) => { if (!isConfirmed(rc)) { diff --git a/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_create_invite_modal.tsx b/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_create_invite_modal.tsx index 5228ead19fb..def58fcfa95 100644 --- a/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_create_invite_modal.tsx +++ b/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_create_invite_modal.tsx @@ -5,6 +5,7 @@ import React, {useEffect, useState} from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; import {CheckIcon, ContentCopyIcon} from '@mattermost/compass-icons/components'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import {SectionNotice} from '@mattermost/compass-ui/components/section-notice'; import {GenericModal} from '@mattermost/components'; import type {RemoteCluster} from '@mattermost/types/remote_clusters'; @@ -146,8 +147,13 @@ function SecureConnectionCreateInviteModal({ data-testid='invite-code' readOnly={true} addon={( - )} /> @@ -165,8 +171,13 @@ function SecureConnectionCreateInviteModal({ data-testid='password' readOnly={done} addon={done ? ( - ) : undefined} @@ -178,18 +189,10 @@ function SecureConnectionCreateInviteModal({ ); } -const copy = ( - <> - - - -); +const copyIcon = }/>; +const copiedIcon = }/>; -const copied = ( - <> - - - -); +const copyLabel = ; +const copiedLabel = ; export default SecureConnectionCreateInviteModal; diff --git a/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_delete_modal.tsx b/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_delete_modal.tsx index 51d6b9f5cf7..101b329d9c2 100644 --- a/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_delete_modal.tsx +++ b/webapp/channels/src/components/admin_console/secure_connections/modals/secure_connection_delete_modal.tsx @@ -47,7 +47,7 @@ function SecureConnectionDeleteModal({ return ( )} - confirmButtonVariant='destructive' + destructive={true} onExited={onExited} compassDesign={true} bodyPadding={false} diff --git a/webapp/channels/src/components/admin_console/secure_connections/secure_connection_detail.tsx b/webapp/channels/src/components/admin_console/secure_connections/secure_connection_detail.tsx index bef1df812c5..8074804b646 100644 --- a/webapp/channels/src/components/admin_console/secure_connections/secure_connection_detail.tsx +++ b/webapp/channels/src/components/admin_console/secure_connections/secure_connection_detail.tsx @@ -11,7 +11,8 @@ import {useHistory, useParams, useLocation} from 'react-router-dom'; import styled from 'styled-components'; import {PlusIcon} from '@mattermost/compass-icons/components'; -import {Button} from '@mattermost/shared/components/button'; +import {Button} from '@mattermost/compass-ui/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import {isRemoteClusterPatch, type RemoteCluster} from '@mattermost/types/remote_clusters'; import {getChannel} from 'mattermost-redux/selectors/entities/channels'; @@ -291,13 +292,15 @@ function SharedChannelRemotes(props: {remoteId: string; rc: RemoteCluster | unde defaultMessage="A list of all the channels shared with your organization and channels you're sharing externally." /> - - + {showTabs && ( @@ -366,10 +369,6 @@ const Placeholder = (props: {filter: 'home' | 'remote'; rc: RemoteCluster}) => { ); }; -const AddChannelsButton = styled(Button)` - padding-left: 15px; -`; - const TabsWrapper = styled.div` .tabs { display: flex; diff --git a/webapp/channels/src/components/admin_console/secure_connections/secure_connection_row.tsx b/webapp/channels/src/components/admin_console/secure_connections/secure_connection_row.tsx index 69c4263c4bb..10c0db9a8f0 100644 --- a/webapp/channels/src/components/admin_console/secure_connections/secure_connection_row.tsx +++ b/webapp/channels/src/components/admin_console/secure_connections/secure_connection_row.tsx @@ -1,16 +1,18 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; +import React, {forwardRef} from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; import {Link, useHistory} from 'react-router-dom'; import styled from 'styled-components'; import {DotsHorizontalIcon, CodeTagsIcon, PencilOutlineIcon, TrashCanOutlineIcon} from '@mattermost/compass-icons/components'; -import {buttonClassNames} from '@mattermost/shared/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; +import {IconButton} from '@mattermost/compass-ui/components/icon-button'; import type {RemoteCluster} from '@mattermost/types/remote_clusters'; import * as Menu from 'components/menu'; +import type {MenuButtonComponentProps} from 'components/menu'; import {ConnectionStatusLabel} from './controls'; import {useRemoteClusterCreateInvite, useRemoteClusterDelete} from './modals/modal_utils'; @@ -43,6 +45,17 @@ export default function SecureConnectionRow(props: Props) { const menuId = 'secure_connection_row_menu'; +const RowMenuTrigger = forwardRef((props, ref) => ( + }/>} + /> +)); +RowMenuTrigger.displayName = 'RowMenuTrigger'; + const RowMenu = ({remoteCluster: rc, onDeleteSuccess, disabled}: Props) => { const {formatMessage} = useIntl(); const history = useHistory(); @@ -65,9 +78,8 @@ const RowMenu = ({remoteCluster: rc, onDeleteSuccess, disabled}: Props) => { , 'aria-label': formatMessage({id: 'admin.secure_connection_row.menu-button.aria_label', defaultMessage: 'Connection options for {connection}'}, {connection: rc.display_name}), }} menu={{ @@ -131,10 +143,6 @@ const RowLink = styled(Link).attrs({className: 'secure-connection &:last-child { border-bottom: 0; } - - .connection-row-menu-button { - padding: 0px 8px; - } `; const Title = styled.strong` diff --git a/webapp/channels/src/components/admin_console/secure_connections/secure_connections.tsx b/webapp/channels/src/components/admin_console/secure_connections/secure_connections.tsx index ab8e49c5c29..a574720c224 100644 --- a/webapp/channels/src/components/admin_console/secure_connections/secure_connections.tsx +++ b/webapp/channels/src/components/admin_console/secure_connections/secure_connections.tsx @@ -2,16 +2,18 @@ // See LICENSE.txt for license information. import type {ReactNode} from 'react'; -import React from 'react'; +import React, {forwardRef} from 'react'; import {useIntl, FormattedMessage, defineMessages} from 'react-intl'; import {useHistory} from 'react-router-dom'; +import {ChevronDownIcon} from '@mattermost/compass-icons/components'; +import {Button, type ButtonEmphasis} from '@mattermost/compass-ui/components/button'; +import {Icon} from '@mattermost/compass-ui/components/icon'; import {SectionNotice} from '@mattermost/compass-ui/components/section-notice'; -import type {ButtonEmphasis} from '@mattermost/shared/components/button'; -import {buttonClassNames} from '@mattermost/shared/components/button'; import LoadingScreen from 'components/loading_screen'; import * as Menu from 'components/menu'; +import type {MenuButtonComponentProps} from 'components/menu'; import AdminHeader from 'components/widgets/admin_console/admin_header'; import BuildingSvg from './building.svg'; @@ -115,6 +117,28 @@ const Placeholder = ({disabled, serviceNotRunning}: {disabled: boolean; serviceN const menuId = 'secure_connections_add_menu'; +const makeAddConnectionMenuTrigger = (emphasis: ButtonEmphasis) => { + const Trigger = forwardRef((props, ref) => { + const {children, disabled, ...rest} = props; + return ( + + ); + }); + Trigger.displayName = 'AddConnectionMenuTrigger'; + return Trigger; +}; + +const AddConnectionPrimaryMenuTrigger = makeAddConnectionMenuTrigger('primary'); +const AddConnectionTertiaryMenuTrigger = makeAddConnectionMenuTrigger('tertiary'); + const AddMenu = ({buttonEmphasis = 'primary', disabled}: {buttonEmphasis?: ButtonEmphasis; disabled: boolean}) => { const {formatMessage} = useIntl(); const history = useHistory(); @@ -135,19 +159,9 @@ const AddMenu = ({buttonEmphasis = 'primary', disabled}: {buttonEmphasis?: Butto - - {!disabled && ( -