* [MM-69849] Let Card opt out of its expand animation
CardBody's measure-then-animate expand mechanism relies on a CSS
transitionend to clear its `expanding` class, but every current
`.console`-styled Card consumer disables that transition outright
(`.console .Card__body.expanding { transition: none; }`), so the
event never fires and content stays clipped until something else
(e.g. a child re-render) forces a reflow.
Add a `disableExpandAnimation` prop that skips the measure/animate
path entirely for cards that are always expanded from mount and never
toggle, and a fallback timer so the existing toggle-capable consumers
recover even without the prop.
* [MM-69849] Add New Attribute creation page for Text attributes
Global Attributes today only lists attributes created elsewhere
(Classification Markings, LDAP/SAML sync) -- there's no way to define
a new one from the admin console itself. This adds that entry point
for the simplest case: a bare Text attribute, reusing the existing
generic PropertyField creation endpoint and CPA name-slugging/
validation logic already in place for Custom Profile Attributes, so
no server-side changes are needed.
Select/Multiselect/Rank types, the options editor, and the "Applies
to" targeting block are separate tickets and appear here only as
disabled/placeholder UI per the design spec.
* [MM-69849] Add e2e coverage for the create-attribute flow
Covers the full happy path (open the New Attribute page, type a
display name, verify the live-slugged unique name, edit/commit it
manually, save, confirm the new row) plus the reserved-word inline
error path that must block navigation without a round trip to the
server.
* [MM-69849] Fix prettier formatting in the create-attribute e2e spec
* [MM-69850] Unlock full Type selector and add options editor to New attribute
Select, Multiselect, and Rank are now selectable (previously locked to
Text with a "Coming soon" placeholder), with a real options editor:
free-form removable chips for Select/Multiselect and numbered chips for
Rank, both reordering via a keyboard-accessible "Move to position"
popover rather than drag-and-drop. Switching type before Save preserves
already-entered options. No server-side changes -- option sanitization
and Rank validation already run for this feature's access_control group.
* [MM-69850] Extract the invalid_options i18n key into en.json
Missed in the prior commit -- en.json was out of sync with the
optionsInvalid message added during review fixes, caught by the
pre-push i18n-extract:check hook.
* Revert CardBody's expand-animation fallback timer; keep options editor Save gated on committed options
CardBody's 350ms fallback timer changed rendered height/transition
behavior for every .console Card consumer, including five pre-existing
ones this branch doesn't touch or test (data retention settings, custom
and global policy forms, access control and permission policy details).
Reverted to the pre-MM-69849 behavior; disableExpandAnimation (used only
by this page) is untouched since it skips that code path entirely.
Also keeps Save on the New Attribute page disabled until an option is
actually committed via Enter/Tab/blur -- typing into the add-input alone
does not count, matching the existing chip-add convention elsewhere in
the codebase.
* Extract Global Attributes constants to their own module; polish the New attribute page's save-error banner and Name auto-derivation
Moves GLOBAL_ATTRIBUTES_GROUP_NAME/OBJECT_TYPE/TARGET_TYPE out of
global_attributes_table.tsx into a dedicated constants.ts so utils.ts
doesn't import them from a component file. Also fixes handleDoneClick
comparing against the auto-derived slug (instead of unconditionally
treating any non-empty manual edit as an override), surfaces the
server's own name-conflict message inline instead of a generic banner,
and caps the Display name input's length.
* Remove stale save_error.title i18n key left behind by the error-banner change
en.json wasn't regenerated when the previous commit removed the
saveErrorTitle message reference; re-running i18n-extract catches it.
* Address CodeRabbit review: honor isDisabled in AttributeDetails, fix CardBody stale-state blink, fix mock leakage in tests
- AttributeDetails ignored the isDisabled value SchemaAdminSettings forwards
as `disabled`; a non-system-admin reaching the page could still edit and
save. Threads disabled through the form controls, options editors, and
canSave.
- CardBody's disableExpandAnimation branch never synced local expanded state,
so re-enabling animation after expanded changed while disabled could render
one frame with the stale value.
- utils.test.ts read `mock.calls[0]` without ever clearing mocks between
tests, so later assertions were checking the first test's call args, not
their own. Added jest.restoreAllMocks() there and in attribute_details.test.tsx.
- Added a length cap to the manual Name input and Select/Rank e2e coverage
for the auto-derived unique name.
* Block Done/Enter while the manual Unique name is invalid
Previously "Done" (and Enter, which routes through the same handler)
committed whatever was typed, so a reserved word like "for" was left
sitting in the field behind a lingering error with Save disabled.
Done now refuses to commit an invalid Name. The block is expressed as
aria-disabled rather than the disabled attribute, so the button stays in
the tab order and a keyboard user lands on it and hears the reason via
aria-describedby instead of finding it silently gone.
This is not a focus trap -- there are three ways out: fix the name, clear
the field (an empty Name has no validation error, so Done goes live again
and applies its usual revert), or press Escape to discard the session.
* Address review: drop the inert JSX space in the Unique name caption
The `{' '}` between the "Unique name:" prefix and the value was a literal
space from before the caption became a flex container. Per the flexbox
spec a child text run containing only white space is not rendered, so it
became an anonymous flex item that gets dropped -- the 8px gap on
.AttributeDetails__uniqueNameCaption does the spacing. Removing it
changes nothing visually.
Four assertions read the caption's combined textContent, which does
include the whitespace node even though it never rendered, so they went
from 'Unique name: my_attribute' to 'Unique name:my_attributeEdit'.
Rescoped them to attributeUniqueNameValue, which is the element those
tests are actually about; the first one keeps a prefix check so the label
itself stays covered.
* Address review: move moveOptionByIndex into its own utils module
Its ranked counterpart, moveOptionByAscIndex, already lives in a pure
utils module (system_properties/rank_utils.ts), so the two reorder
helpers sat at different altitudes for no reason. option_utils.ts is the
unranked mirror of that file -- Select/Multiselect order is array
position, with no rank values to redistribute.
Not global_attributes/utils.ts: that one is API-payload-shaped and pulls
in Client4, which a plain array splice has no business importing.
Being addressable on its own also makes it directly testable, so this
adds the cases the component tests only covered incidentally: forward and
backward moves, the same-position no-op, that no rank field is
introduced, and that the input array is not mutated.
---------
Co-authored-by: Hanzo Dev <[email protected]>
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.
Learn more about the following use cases with Mattermost:
Other useful resources:
- Download and Install Mattermost - Install, setup, and configure your own Mattermost instance.
- Product documentation - Learn how to run a Mattermost instance and take advantage of all the features.
- Developer documentation - Contribute code to Mattermost or build an integration via APIs, Webhooks, slash commands, Apps, and plugins.
Table of contents
- Install Mattermost
- Native mobile and desktop apps
- Get security bulletins
- Get involved
- Learn more
- License
- Get the latest news
- Contributing
Install Mattermost
- Download and Install Mattermost Self-Hosted - Deploy a Mattermost Self-hosted instance in minutes via Docker, Ubuntu, or tar.
- Get started in the cloud to try Mattermost today.
- Developer machine setup - Follow this guide if you want to write code for Mattermost.
Other install guides:
- Deploy Mattermost on Docker
- Mattermost Omnibus
- Install Mattermost from Tar
- Ubuntu 20.04 LTS
- Kubernetes
- Helm
- Debian Buster
- RHEL 8
- More server 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 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.
Get involved
- Contribute to Mattermost
- Find "Help Wanted" projects
- Join Developer Discussion on a Mattermost server for contributors
- Get Help With Mattermost
Learn more
- API options - webhooks, slash commands, drivers, and web service
- See who's using Mattermost
- Browse over 700 Mattermost integrations
License
See the LICENSE file for license rights and limitations.
Get the latest news
- X - Follow Mattermost on X, formerly Twitter.
- Blog - Get the latest updates from the Mattermost blog.
- Facebook - Follow Mattermost on Facebook.
- LinkedIn - Follow Mattermost on LinkedIn.
- Email - Subscribe to our newsletter (1 or 2 per month).
- Mattermost - Join the ~contributors channel on the Mattermost Community Server.
- IRC - Join the #matterbridge channel on Freenode (thanks to matterircd).
- YouTube - Subscribe to Mattermost.
Contributing
Please see CONTRIBUTING.md. Join the Mattermost Contributors server to join community discussions about contributions, development, and more.




