-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[MM-50467] Change usage of anchor tag in favour of new ExternalLink #12277
Conversation
|
||
/* eslint-disable mattermost/use-external-link */ | ||
|
||
import React from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The component itself
package.json
Outdated
@@ -39,6 +39,7 @@ | |||
"emoji-datasource": "6.1.1", | |||
"emoji-datasource-apple": "6.0.1", | |||
"emoji-regex": "10.2.1", | |||
"eslint-plugin-mattermost": "github:mattermost/eslint-plugin-mattermost#9372e95228f2517c45f83418ea9c4d5b1e390cde", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will need to replace this with the tip of master
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall! The only blocking things to me are:
- There was an extra/double paste of a link
- I think we need support for if the href prop already contains a query parameter.
Not sure if we want to support utils/markdown/link_only_renderer.tsx
or utils/markdown/renderer.tsx
ever (might be hard to do in any case), but wanted to raise that its possible we could get markdown linking off to mattermost.com and it wouldn't have the ExternalLink enhancement. I think we're ok with that since dynamic content isn't really part of a campaign per se, and I don't think we'd know what "location" to meaningfully attribute it to.
Found a few places that maybe should be external links:
components/seats_calculator/consequences.tsx , seeHowBillingWorks link
This one is an external link, but formulated in javascript instead of as plain links because of the cloud condition. Not sure how we want to handle it.
components/youtube_video/youtube_video.tsx
when noopener is used, nonempty target names other than _top, _self, and _parent are all treated like _blank in terms of deciding whether to open a new window/tab.
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/noopener
components/admin_console/admin_definition.jsx
id: 'CustomIntegrationSettings',
name: t('admin.integrations.integrationManagement.title'),
name_default: 'Integration Management',
settings: [
{
type: Constants.SettingsTypes.TYPE_BOOL,
key: 'ServiceSettings.EnableIncomingWebhooks',
label: t('admin.service.webhooksTitle'),
label_default: 'Enable Incoming Webhooks: ',
help_text: t('admin.service.webhooksDescription'),
help_text_default: 'When true, incoming webhooks will be allowed. To help combat phishing attacks, all posts from webhooks will be labelled by a BOT tag. See <link>documentation</link> to learn more.',
help_text_values: {
link: (msg) => (
<a
href='https://developers.mattermost.com/integrate/admin-guide/admin-webhooks-incoming/'
components/admin_console/license_settings/trial_banner/trial_banner.tsx
export const EmbargoedEntityTrialError = () => {
return (
<FormattedMessage
id='admin.license.trial-request.embargoed'
defaultMessage='We were unable to process the request due to limitations for embargoed countries. <link>Learn more in our documentation</link>, or reach out to [email protected] for questions around export limitations.'
values={{
link: (text: string) => (
<a href={LicenseLinks.EMBARGOED_COUNTRIES}>
{text}
</a>
),
}}
/>
);
};
components/activity_and_insights/insights/insights_title/insights_title.tsx
Outdated
Show resolved
Hide resolved
components/external_link/index.tsx
Outdated
} | ||
|
||
type Props = React.AnchorHTMLAttributes<HTMLAnchorElement> & { | ||
href?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be the minimum required?
components/external_link/index.tsx
Outdated
let href = props.href; | ||
let queryParams = {}; | ||
if (href?.includes('mattermost.com')) { | ||
// encode this stuff so it's not so transparent to the user? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this comment if we are not taking that direction
utm_source: 'mattermost', | ||
utm_medium: license.Cloud === 'true' ? 'in-product-cloud' : 'in-product', | ||
utm_content: props.location || '', | ||
uid: userId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is user id necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kevin mentioned it in lieu of PII. I think it would be useful for the data team since we'd be able to map this value to the user_actual_id
from rudder events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @nickmisasi! Didn't do a review on all the replacements but the components LGTM with some non-blocking comments
it('should attach parameters if telemetry is enabled', () => { | ||
const state = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this test still applicable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the name of the test, it's applicable now!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. There's just one thing that I think needs addressing (the dependency vs dev dependency one), but hopefully it's quick
className='GenericModal__button actionButton' | ||
href={presentNoticeInfo.actionParam} | ||
location='product_notices_modal' | ||
href={presentNoticeInfo.actionParam || ''} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the first place I've noticed this during my review, but if we end up doing this a lot, we could always consider making this prop optional
package.json
Outdated
@@ -39,6 +39,7 @@ | |||
"emoji-datasource": "6.1.1", | |||
"emoji-datasource-apple": "6.0.1", | |||
"emoji-regex": "10.2.1", | |||
"eslint-plugin-mattermost": "github:mattermost/eslint-plugin-mattermost#5b0c972eacf19286e4c66221b39113bf8728a99e", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this back to being a dev dependency? Strictly speaking, it doesn't matter for the web app (it would only really have an effect if we uploaded mattermost-webapp as an NPM package), but I think Security Team had some process around new non-dev dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how this happened tbh. I think maybe the npm link
from testing? Fixed
@@ -280,13 +282,12 @@ export default class DatabaseSettings extends AdminSettings { | |||
defaultMessage='Minimum number of characters in a hashtag. This must be greater than or equal to 2. MySQL databases must be configured to support searching strings shorter than three characters, <link>see documentation</link>.' | |||
values={{ | |||
link: (msg) => ( | |||
<a | |||
<ExternalLink | |||
location='database_settings' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing to change here, but seeing these location
things repeated does make me wonder if we'd benefit from wrapping the entire contents of these screens/modals/components in a Context that provides this. That'd be overkill to just save us from having to pass the same location repeatedly for multiple ExternalLink
s, but I could see that sort of pattern being useful for other things in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like a "breadcrumb" in a context would be pretty cool for sure. I know there are some patterns around Cloud telemetry that sort of mimics that by appending 'location1 > location2' + 'location3'
through props, which is a bit messy imo
Test server destroyed |
Summary
We want to be able to enrich link-outs from mattermost to *.mattermost.com with contextual information. This will help us to identify PQL's. This PR implements changes required to satisfy the the new linter rule enforcing usage of this new component mattermost/eslint-plugin-mattermost#6
Ticket Link
https://mattermost.atlassian.net/browse/MM-50467
Related Pull Requests
Screenshots
Release Note