Julien Tant 338dc6c74d [MM-69863] Add external source picker (AD/LDAP, SAML) to New attribute (#37845)
* [MM-69863] Add external source picker (AD/LDAP, SAML) to New attribute

Adds a "Link to external source" control to the Definition card, letting
an admin link AD/LDAP and/or SAML to a new attribute (both may be linked
at once, matching Custom Profile Attributes' own dot-menu behavior).
Each linked source renders as its own removable/editable chip; the "add"
trigger's menu only offers not-yet-linked sources and disappears once
both are linked. Reuses the existing AttributeModal component and
ModalIdentifiers unmodified -- no new modal code.

No server-side changes: the access_control property group's existing
AccessControlAttributeValidationHook already validates, persists, and
strips attrs.ldap/attrs.saml for non-Text fields, and the Manage
Attributes list already renders a linked source's icon/label. The
client mirrors that server behavior by forcing the field's type to Text
whenever a link is set, and clearing any links if the type is manually
switched away from Text.

* Cap the Attribute column's width at 65ch on the Manage Attributes list

The table uses table-layout: auto, so this needs to live on the td/th
itself (mirroring the existing td.actions/th.actions rule) rather than
on the inner name span alone -- the column's rendered width is decided
by the auto-layout algorithm, not by max-width on a cell's content.

* Style the "Link to external source" trigger as a quaternary button

Adds the design's separator (margin-top/padding-top: 12px, border-top)
above the trigger, and swaps the ad-hoc link styling for
buttonClassNames({emphasis: 'quaternary'}) -- transparent/no-border at
rest, matching the Cancel button elsewhere on this page -- with the
hover tint overridden to --link-color-rgb per design, since the
quaternary default uses --button-bg-rgb instead.

* Fix trigger button sizing, extract a real Divider, reorder chips, and show the linked value

- The trigger was stretching full-width because display:flex (block-level)
  fought .btn's own display:inline-flex, and its flex-column parent
  defaults every child to align-self: stretch regardless of which display
  wins -- fixed with align-self: flex-start and dropping the display
  override entirely.
- The border-top/margin-top/padding-top separator was living on the
  trigger button itself, so it only ever spanned the button's own
  (now inline) width, not the full row. Extracted a small reusable
  Divider component (webapp/channels/src/components/divider/) -- a
  theme-CSS-var-based hairline <hr>, unlike Menu.Separator/MUI Divider
  which needs a CompassDesignProvider ancestor -- and render it as its
  own full-width element instead.
- Chips now render below the trigger, not above, and show the actual
  linked value ("AD/LDAP: department"), not just the source name.

* [MM-69863] Add e2e coverage for dual-linking, chip edit/remove, and Type-switch clearing

Covers linking both AD/LDAP and SAML (menu exclusion, trigger disappearance,
chip label format), editing/removing a chip without a modal, the
type-mismatch warning, and the status announcement when Type is switched
away from Text.

* [MM-69863] Show "AD/LDAP, SAML" when an attribute is linked to both sources

getSourceKind previously collapsed a dual-linked field's Source cell to
just "AD/LDAP" since ldap was checked before saml. Add a dedicated
ldap_and_saml kind checked ahead of the individual branches, with its
own label and icon, and update the dual-linking e2e test's stale
assertion/comment to match.

* Fix prettier formatting in the dual-linking e2e spec

Pre-existing lines exceeded the project's 120-char printWidth;
prettier --write wraps the long test titles and toHaveText
assertions onto multiple lines with no behavior change.

* Gate AttributeExternalSource on saving/disabled, add chip action focus ring

A delegated (non-sysadmin) admin could still open the link modal and
mutate ldapAttr/samlAttr while every other control on the page was
disabled, and got stuck with an unclearable unsaved-changes prompt.
Thread disabled into the trigger and both chip action buttons.

Also add a :focus-visible style to the chip edit/remove buttons -- the
app's global *:focus{outline:none} reset left keyboard users with no
visible focus indicator on them.

* Clear stale focus-visible on the external source trigger

After linking a source, the modal restores focus to the trigger
programmatically, and because that restore comes from a keyboard-focused
input the trigger inherits :focus-visible. A later mouse click does not
clear it -- an already-focused element fires no new focus event -- so the
item MUI auto-focuses when the menu reopens inherits it in turn and gets
painted with the keyboard focus ring, on a menu opened with the mouse.

Blur the trigger on mousedown when it is already focused and matches
:focus-visible; the click's own default focus then re-evaluates the
interaction as a pointer one. Keyboard opens never fire mousedown, so
they keep their focus ring, and the first item still receives focus
either way so arrow-key navigation is unchanged.

Menu gets an opt-in onMouseDown passthrough on menuButton so the fix
stays scoped to this menu rather than changing every menu in the app.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 09:20:40 -07:00
2026-04-01 13:03:36 +00:00

Mattermost logo

Mattermost is an open core, self-hosted collaboration platform that offers chat, workflow automation, voice calling, screen sharing, and AI integration. This repo is the primary source for core development on the Mattermost platform; it's written in Go and React, runs as a single Linux binary, and relies on PostgreSQL. A new compiled version is released under an MIT license every month on the 16th.

Deploy Mattermost on-premises, or try it for free in the cloud.

mattermost user interface

Learn more about the following use cases with Mattermost:

Other useful resources:

Table of contents

Install Mattermost

Other install guides:

Native mobile and desktop apps

In addition to the web interface, you can also download Mattermost clients for Android, iOS, Windows PC, macOS, and Linux.

Get Mattermost on Google Play Get Mattermost on the App Store Get Mattermost on Windows PC Get Mattermost on Mac OSX Get Mattermost on Linux

Get security bulletins

Receive notifications of critical security updates. The sophistication of online attackers is perpetually increasing. If you're deploying Mattermost it's highly recommended you subscribe to the Mattermost Security Bulletin mailing list for updates on critical security releases.

Subscribe here

Get involved

Learn more

License

See the LICENSE file for license rights and limitations.

Get the latest news

Contributing

Small Image

Please see CONTRIBUTING.md. Join the Mattermost Contributors server to join community discussions about contributions, development, and more.

S
Description
Mattermost is an open source platform for secure collaboration across the entire software development lifecycle..
Readme 2.3 GiB
Languages
TypeScript 48.2%
Go 41.4%
JavaScript 5.4%
SCSS 2.6%
HTML 2.1%
Other 0.2%