MM-61891 Fix styles for attachment card overflow issue (#30544)

* Fix styles for attachment card overflow issue

* fixed style linter issues

* fix linting issues

* fixed positioning issue

* updated snapshots

* E2E fix for playwrite test

---------

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
Этот коммит содержится в:
Matthew Birtch
2025-04-11 03:55:17 -04:00
коммит произвёл GitHub
родитель 357aa58163
Коммит 19bea2c8d7
10 изменённых файлов: 62 добавлений и 99 удалений

Просмотреть файл

@@ -21,7 +21,9 @@ export default class ChannelsCenterView {
readonly scheduledDraftChannelIcon;
readonly scheduledDraftChannelInfoMessage;
readonly scheduledDraftChannelInfoMessageLocator;
readonly scheduledDraftDMChannelLocator;
readonly scheduledDraftChannelInfoMessageText;
readonly scheduledDraftDMChannelLocatorString;
readonly scheduledDraftSeeAllLink;
readonly postEdit;
readonly editedPostIcon;
@@ -29,6 +31,7 @@ export default class ChannelsCenterView {
constructor(container: Locator) {
this.container = container;
this.scheduledDraftChannelInfoMessageLocator = 'span:has-text("Message scheduled for")';
this.scheduledDraftDMChannelLocatorString = 'div.ScheduledPostIndicator span a';
this.header = new ChannelsHeader(this.container.locator('.channel-header'));
this.postCreate = new ChannelsPostCreate(container.getByTestId('post-create'));
this.scheduledDraftOptions = new ChannelsPostCreate(container.locator('#dropdown_send_post_options'));
@@ -37,6 +40,7 @@ export default class ChannelsCenterView {
this.scheduledDraftChannelIcon = container.locator('#create_post i.icon-draft-indicator');
this.scheduledDraftChannelInfoMessage = container.locator('div.ScheduledPostIndicator span');
this.scheduledDraftChannelInfoMessageText = container.locator(this.scheduledDraftChannelInfoMessageLocator);
this.scheduledDraftDMChannelLocator = container.locator(this.scheduledDraftDMChannelLocatorString);
this.scheduledDraftSeeAllLink = container.locator('a:has-text("See all")');
this.editedPostIcon = (postID: string) => container.locator(`#postEdited_${postID}`);
}
@@ -127,16 +131,20 @@ export default class ChannelsCenterView {
);
}
async goToScheduledDraftsFromDMChannel() {
if (await this.scheduledDraftDMChannelLocator.isVisible()) {
await this.scheduledDraftDMChannelLocator.click();
return;
}
await this.scheduledDraftSeeAllLink.isVisible();
await this.scheduledDraftSeeAllLink.click();
}
async verifyscheduledDraftChannelInfo() {
await this.postBoxIndicator.isVisible();
await this.scheduledDraftChannelIcon.isVisible();
const messageLocator = this.scheduledDraftChannelInfoMessage.first();
try {
await expect(messageLocator).toContainText('Message scheduled for');
} catch {
// First assertion failed, trying fallback
await expect(messageLocator).toContainText('You have one scheduled message.');
}
await expect(messageLocator).toContainText('Message scheduled for');
}
async clickOnLastEditedPost(postID: string | null) {

Просмотреть файл

@@ -192,11 +192,7 @@ test('MM-T5643_3 should create a scheduled message from a DM', async ({pw}) => {
await setupChannelPage(channelsPage, draftMessage, team.name, `@${user2.username}`);
await scheduleMessage(channelsPage);
await channelsPage.centerView.verifyscheduledDraftChannelInfo();
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
await channelsPage.centerView.goToScheduledDraftsFromDMChannel();
// # Hover and verify options
await scheduledDraftPage.verifyOnHoverActionItems(draftMessage);
@@ -288,7 +284,7 @@ test('MM-T5650 should copy scheduled message', async ({pw, browserName}) => {
const {user} = await pw.initSetup();
const {page, channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
await setupChannelPage(channelsPage, draftMessage);
await setupChannelPage(channelsPage, draftMessage, '', 'town-square');
await scheduleMessage(channelsPage);
await channelsPage.centerView.verifyscheduledDraftChannelInfo();

Просмотреть файл

@@ -45,6 +45,7 @@ exports[`FileAttachment should match snapshot when file is deleted 1`] = `
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.pdf"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -106,6 +107,7 @@ exports[`FileAttachment should match snapshot with thumbnail disabled 1`] = `
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.pdf"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -168,6 +170,7 @@ exports[`FileAttachment should match snapshot, after change from file to image 1
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.png"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -229,6 +232,7 @@ exports[`FileAttachment should match snapshot, regular file 1`] = `
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.pdf"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -290,6 +294,7 @@ exports[`FileAttachment should match snapshot, regular image 1`] = `
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.png"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -351,6 +356,7 @@ exports[`FileAttachment should match snapshot, small image 1`] = `
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.png"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -412,6 +418,7 @@ exports[`FileAttachment should match snapshot, svg image 1`] = `
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.svg"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -473,6 +480,7 @@ exports[`FileAttachment should match snapshot, when file is not loaded 1`] = `
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.pdf"
href="/api/v4/files/noLoad?download=1"
location="filename_overlay"
@@ -498,7 +506,7 @@ exports[`FileAttachment should match snapshot, with compact display 1`] = `
class="post-image__details"
>
<a
class="post-image__name"
class="post-image__name btn btn-icon btn-sm"
href="#"
rel="noopener noreferrer"
>
@@ -633,6 +641,7 @@ exports[`FileAttachment should not render menu items when disable actions is set
>
<a
aria-label="download"
class="btn btn-icon btn-sm"
download="test.pdf"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"

Просмотреть файл

@@ -5,7 +5,7 @@ exports[`components/file_attachment/FilenameOverlay should match snapshot, compa
title="test_filename"
>
<a
className="post-image__name"
className="post-image__name btn btn-icon btn-sm"
href="#"
onClick={[MockFunction]}
rel="noopener noreferrer"
@@ -40,6 +40,7 @@ exports[`components/file_attachment/FilenameOverlay should match snapshot, stand
>
<ForwardRef
aria-label="download"
className="btn btn-icon btn-sm"
download="test_filename"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"
@@ -64,6 +65,7 @@ exports[`components/file_attachment/FilenameOverlay should match snapshot, with
>
<ForwardRef
aria-label="download"
className="btn btn-icon btn-sm"
download="test_filename"
href="/api/v4/files/thumbnail_id?download=1"
location="filename_overlay"

Просмотреть файл

@@ -233,7 +233,7 @@ export default function FileAttachment(props: Props) {
id={`file_action_button_${props.fileInfo.id}`}
aria-label={formatMessage({id: 'file_search_result_item.more_actions', defaultMessage: 'More Actions'}).toLowerCase()}
className={classNames(
'file-dropdown-icon', 'dots-icon',
'file-dropdown-icon', 'dots-icon', 'btn', 'btn-icon', 'btn-sm',
{'a11y--active': keepOpen},
)}
aria-expanded={keepOpen}

Просмотреть файл

@@ -71,7 +71,7 @@ export default class FilenameOverlay extends React.PureComponent<Props> {
<a
href='#'
onClick={handleImageClick}
className='post-image__name'
className='post-image__name btn btn-icon btn-sm'
rel='noopener noreferrer'
>
<AttachmentIcon className='icon'/>
@@ -88,6 +88,7 @@ export default class FilenameOverlay extends React.PureComponent<Props> {
<ExternalLink
href={getFileDownloadUrl(fileInfo.id)}
aria-label={localizeMessage({id: 'view_image_popover.download', defaultMessage: 'Download'}).toLowerCase()}
className='btn btn-icon btn-sm'
download={fileName}
location='filename_overlay'
>

Просмотреть файл

@@ -85,7 +85,7 @@ exports[`components/file_search_result/FileSearchResultItem should match snapsho
}
>
<a
className="action-icon download-icon"
className="action-icon download-icon btn btn-icon btn-sm"
href="/api/v4/files/file_info_id?download=1"
onClick={[Function]}
>
@@ -192,7 +192,7 @@ exports[`components/file_search_result/FileSearchResultItem should match snapsho
}
>
<a
className="action-icon download-icon"
className="action-icon download-icon btn btn-icon btn-sm"
href="/api/v4/files/file_info_id?download=1"
onClick={[Function]}
>
@@ -299,7 +299,7 @@ exports[`components/file_search_result/FileSearchResultItem should match snapsho
}
>
<a
className="action-icon download-icon"
className="action-icon download-icon btn btn-icon btn-sm"
href="/api/v4/files/file_info_id?download=1"
onClick={[Function]}
>
@@ -401,7 +401,7 @@ exports[`components/file_search_result/FileSearchResultItem should match snapsho
}
>
<a
className="action-icon download-icon"
className="action-icon download-icon btn btn-icon btn-sm"
href="/api/v4/files/file_info_id?download=1"
onClick={[Function]}
>

Просмотреть файл

@@ -85,33 +85,16 @@
}
.action-icon {
display: flex;
width: 32px;
min-width: 32px;
height: 32px;
justify-content: center;
border-radius: 4px;
margin-left: 8px;
background-color: var(--center-channel-bg);
color: rgba(var(--center-channel-color-rgb), 0.64);
cursor: pointer;
fill: rgba(var(--center-channel-color-rgb), 0.64);
opacity: 0;
text-decoration: none;
transition: opacity 0.15s ease;
display: none;
margin-left: 2px;
&.download-icon {
margin-right: 6px;
margin-right: 2px;
}
svg {
display: flex;
}
&:hover {
background-color: rgba(var(--center-channel-color-rgb), 0.08);
color: rgba(var(--center-channel-color-rgb), 0.8);
}
}
.MenuWrapper {

Просмотреть файл

@@ -154,7 +154,7 @@ export default class FileSearchResultItem extends React.PureComponent<Props, Sta
>
<a
href='#'
className='action-icon dots-icon'
className='action-icon dots-icon btn btn-icon btn-sm'
>
<i className='icon icon-dots-vertical'/>
</a>
@@ -181,7 +181,7 @@ export default class FileSearchResultItem extends React.PureComponent<Props, Sta
title={defineMessage({id: 'file_search_result_item.download', defaultMessage: 'Download'})}
>
<a
className='action-icon download-icon'
className='action-icon download-icon btn btn-icon btn-sm'
href={getFileDownloadUrl(fileInfo.id)}
onClick={this.stopPropagation}
>

Просмотреть файл

@@ -352,7 +352,6 @@
&:hover,
&:focus-within,
&.keep-open {
overflow: visible;
box-shadow: 0 2px 3px 0 rgba(variables.$black, 0.1), 0 2px 3px 0 rgba(variables.$black, 0.1);
.file-dropdown-icon {
@@ -463,20 +462,6 @@
.file-dropdown-icon {
display: none;
width: 32px;
min-width: 32px;
height: 32px;
align-items: center;
justify-content: center;
border: 0;
border-radius: 4px;
margin-left: 8px;
background-color: var(--center-channel-bg);
color: rgba(var(--center-channel-color-rgb), 0.64);
cursor: pointer;
fill: rgba(var(--center-channel-color-rgb), 0.64);
text-decoration: none;
transition: opacity 0.15s ease;
svg {
display: flex;
@@ -484,8 +469,6 @@
&:hover {
display: flex;
background-color: rgba(var(--center-channel-color-rgb), 0.08);
color: rgba(var(--center-channel-color-rgb), 0.8);
}
&:focus {
@@ -497,9 +480,15 @@
position: relative;
display: flex;
overflow: hidden;
width: 100%;
min-width: 0;
height: 100%;
flex: 1;
flex-direction: row;
align-items: center;
padding-right: 12px;
background: transparent;
color: functions.v(center-channel-color);
font-size: 12px;
text-align: left;
@@ -529,7 +518,9 @@
.post-image__detail_wrapper {
display: flex;
min-width: 0;
flex: 1;
flex-direction: row;
padding: 0;
.post--compact & {
@@ -538,6 +529,7 @@
.post-image__detail {
width: 100%;
min-width: 0;
height: 100%;
line-height: normal;
@@ -590,67 +582,39 @@
}
.post-image__download {
top: 0;
right: 0;
display: flex;
height: 100%;
align-items: center;
justify-content: center;
padding: 0 1.6rem;
margin-left: 2px;
background: transparent;
line-height: 0;
opacity: 1;
text-align: center;
transition: opacity 0.15s ease;
a {
display: flex;
width: 3.2rem;
height: 3.2rem;
align-items: center;
justify-content: center;
border-radius: 4px;
color: rgba(functions.v(center-channel-color-rgb), 0.75);
font-size: 1.6rem;
text-decoration: none;
&:focus {
color: rgba(functions.v(center-channel-color-rgb), 0.75);
}
&:hover {
background: rgba(functions.v(center-channel-color-rgb), 0.08);
color: rgba(functions.v(center-channel-color-rgb), 0.75);
}
&:active {
background: rgba(var(--button-bg-rgb), 0.08);
color: functions.v(button-bg);
}
}
span {
display: inline-block;
}
transition: opacity 0.15s ease, background-color 0.15s ease;
svg {
display: inline-block;
width: 30px;
height: 30px;
border: 1px solid;
border-color: rgba(var(--center-channel-color-rgb), 0.35);
border: 1px solid rgba(var(--center-channel-color-rgb), 0.35);
border-radius: 50%;
opacity: 0.7;
stroke: rgba(var(--center-channel-color-rgb), 0.4);
transition: all 0.1s linear;
transition: opacity 0.15s ease;
&:hover {
opacity: 1;
}
}
}
div.MenuWrapper + .post-image__download {
padding-left: 8px;
.btn-icon {
display: flex;
}
span {
display: inline-block;
}
}
.post-image__progressBar {