* MM-70072: Update team admin assignment during team join
* Assert SchemeUser in team rejoin test case
* MM-70072: Fix team admin assignment in bulk import path
* Preserve computed admin status through scheme role sync in bulk import
---------
Co-authored-by: Bill Gardner <billg@wavearts.com>
* Add weekly recurring scheduled posts.
Extend scheduled posts so users can schedule weekly repeats and keep the series healthy across sends, reschedules, and UI updates instead of falling back to one-shot behavior.
Made-with: Cursor
* Add Playwright coverage for recurring scheduled posts.
Cover weekly recurring scheduled messages in the scheduled-messages spec so the recurring UI and reschedule flow stay protected without adding a separate test surface.
Made-with: Cursor
* Fix recurring scheduled post CI failures.
Resolve the initial lint and formatting issues and renumber the new scheduled-post migration so it no longer collides with master during Postgres-backed test setup.
Made-with: Cursor
* Sync recurring scheduled post translation files.
Regenerate the affected English translation catalogs so the recurring scheduled post strings match the source extraction order expected by CI.
Made-with: Cursor
* Fix recurring scheduled post review follow-ups.
Preserve overdue cleanup behavior during weekly catch-up, defer delete websocket events until deletion succeeds, and address the remaining migration and UI review nits.
Made-with: Cursor
* Address recurring scheduled post review feedback
Made-with: Cursor
* Fix recurring scheduled post CI checks
Made-with: Cursor
* Make pending scheduled post keyset cursor index-scannable
EXPLAIN ANALYZE on a 5M-row ScheduledPosts table showed the pure OR-form
cursor forced Postgres to scan idx_scheduledposts_pending_scheduled_at_id
from the top on every page (~383ms/page, ~2M rows filtered). Keeping the
ScheduledAt <= beforeTime bound outside the tie-break restores the index
boundary (~0.12ms/page). Adds storetest coverage for cursor pagination.
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Address code quality review findings for recurring scheduled posts
Server:
- Replace silent-fallback AdvanceWeeklyScheduledNextOccurrence with
error-returning ScheduledPost.ComputeNextScheduledAt; a recurring post
whose timezone fails to load is now routed through the failed-post path
instead of being reposted every job run or silently deleted
- Add ScheduledPost.IsRecurring and partition batches in
processScheduledPostBatch; advance/delete now run independently so a
store failure in one path can't cause reposts in the other
- Drop dead generality in UpdateRecurringScheduledPosts (only ScheduledAt
varies per row; ErrorCode/ProcessedAt are constants)
- Simplify redundant repeat-type condition in GetPendingScheduledPosts
Webapp:
- Add shared isRecurringScheduledPost helper, replacing six scattered
repeat_type === 'weekly' literals
- Recurrence timezone is now simply the scheduler's current timezone;
removes initialRepeatTimezone/effectiveTimezone plumbing and the
modal-label/picker timezone mismatch
- Single enforcement point for hiding send-now on recurring posts
- Use canonical getTeamIdByChannelId at both SCHEDULED_POST_UPDATED
dispatch sites; rewrite errorsByTeamId update case as remove-then-add
and add reducer tests
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Simplify recurring scheduled post code per review
- End a recurring series when its channel no longer exists instead of
advancing it forever (matches the one-shot channel-not-found handling)
- Collapse the errorsByTeamId SCHEDULED_POST_UPDATED case into the
identical SINGLE_SCHEDULED_POST_RECEIVED case (a scheduled post's team
can't change) and combine duplicate byId cases; preserves state
references on no-op updates
- Drop no-op timezone conversions in ComputeNextScheduledAt
- Remove redundant checkbox aria-label (label htmlFor already names it)
- Schedule new job tests in the past instead of sleeping a real second
- Remove redundant test assignment and e2e positional boolean
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Remove slop from recurring scheduled post changes
- Drop the business-rule CHECK constraint from the recurrence migration;
no other migration enforces model-layer validation in the database,
and BaseIsValid plus the job's failure handling already own it
- Fold the standalone repeat-validation test file into the existing
TestScheduledPostBaseIsValid, matching its conventions
- Revert unrelated benchmark modernization in utils_test.go
- Drop an unneeded cast, unused fixture fields, and naming/assertion
inconsistencies in tests
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Regenerate ScheduledPostStore mock with mockery ordering
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Address CodeRabbit review feedback
- Reject the host-dependent 'Local' value for RepeatTimezone; recurring
schedules need a fixed zone (UTC or IANA name)
- Hide reschedule for deactivated DMs, matching send-now eligibility
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Resolve scheduled post team bucket from existing state when channel is unloaded
An admin can reschedule before fetchMissingChannels resolves, in which case
deriving the team from the channel returns undefined and the update was
misfiled under directChannels. getScheduledPostTeamId falls back to the
byTeamId bucket that already holds the post.
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Retrigger CI after transient enterprise npm network failure
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Clear hover/focus before asserting scheduled post header details in e2e
The drafts panel hides its timestamp/tag info section while hovered or
focus-within; after the reschedule modal closes, focus returns to the row
and the 'Repeats weekly' tag assertion saw a hidden element.
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Move recurrence columns into baseColumns and dispatch ComputeNextScheduledAt on repeat type
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Preserve recurrence when scheduled post updates omit repeat fields
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Disallow file attachments on recurring scheduled posts
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Stop pinning the channel indicator for recurring-only scheduled posts
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Re-home nullable-Type comment onto baseColumns
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Gate recurring scheduled posts behind a default-off feature flag
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Move presence-preservation rationale to the copy site
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Extract draftHasAttachments helper and require allowRecurring at single-caller layers
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Return null from the indicator selector when nothing should show
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Gate only recurrence transitions and preserve existing series in the modal
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Avoid err shadowing in scheduled post update handler
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Disable the repeat weekly checkbox with a tooltip when the message has attachments
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Return an explicit disposition from postScheduledPost
The batch loop inferred 'channel permanently gone' from the one return
path with a nil error and an error code set - an invariant a future
change could silently break, deleting recurring series by accident.
postScheduledPost now returns posted/failed/unsendable explicitly, the
switch refuses to delete on an unhandled disposition, and a test pins
that both recurring and one-shot posts in a nonexistent channel are
permanently deleted.
Co-authored-by: nick.misasi <nick.misasi@mattermost.com>
* Fix Repeat weekly attachments tooltip centering on the modal row (#37927)
Shrink-wrap the repeat checkbox row so WithTooltip anchors to the
control/label instead of the full modal body width.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* Fix Manage Teams dropdown overflowing outside modal for last rows
The role dropdown in the Admin Console Manage Teams modal always opened
downward, so for users with many teams the menu for the last rows was
pushed below the modal and out of view. Compute openUp for rows near the
bottom of the list, mirroring the TeamMembersDropdown behavior.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Render Manage Teams role dropdown via floating menu to fix overflow
Migrate ManageTeamsDropdown from the deprecated Menu/MenuWrapper widget to
the modern components/menu (MUI Popover). The old widget positioned the
menu relative to the modal content, so for users with many teams the role
dropdown on the last rows was pushed below the modal and off-screen. The
new menu renders in a portal anchored to the trigger and opens upward for
rows near the bottom of the list, mirroring TeamMembersDropdown.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Add openUp helper coverage and action tests for ManageTeamsDropdown
Extract the open-up positioning rule into a testable shouldOpenUp helper
and cover its boundaries, plus the demote and error paths, so the fix for
the dropdown overflow is exercised directly.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Satisfy lint for table-driven test comment
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Gate onMemberChange assertions behind waitFor in dropdown tests
Move onMemberChange expectations inside waitFor so they wait for the
async updateTeamMemberSchemeRoles promise to resolve before asserting.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Fix Manage Teams e2e to target MUI menu button and items
The Manage Teams role dropdown was migrated from the deprecated
components/widgets/menu (div.MenuWrapper) to the modern components/menu
(MUI Popover). The Playwright spec still clicked div.MenuWrapper and
looked for menu items inside the team row, but the new menu renders in a
portal. Target the accessible role button and role menuitem elements
instead.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* MM-70216: Adjust post and thread payload sanitization
* MM-70216: Preserve MM blocks actions in thread test fixture
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* [MM-64357] Fix ABAC simple-expression detection for apostrophe values
The isSimpleCondition/isMultiselectOrGroup helpers used a quoted-string
regex fragment (['"][^'"]*['"]) that rejected any quote character inside
a value. A valid value like "Matt's Department" therefore failed the
simple-expression check, disabling "Switch to Simple Mode" and trapping
the policy editor in advanced mode.
Replace the fragment with a proper CEL string-literal pattern that allows
apostrophes inside double-quoted strings (and double quotes inside
single-quoted strings), plus escaped quotes, matching what the CEL parser
accepts and what celStringLiteral emits.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-64357] Add tests for quote characters in ABAC simple-expression detection
Cover the apostrophe regression: values like "Matt's Department" must be
classified as simple expressions across equality, string operators, in-lists,
scalar-in, native email, single-quoted values, and multiselect OR groups. A
round-trip test ties rowToCEL/celStringLiteral output to isSimpleExpression,
and a negative case guards against accepting unterminated quoted values.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-64357] Strengthen quote-handling tests per review
Add bug-catching round-trip for "has any of" (multiselect OR group), plus
ranked-operator, session-namespace, and unescaped-embedded-quote cases.
Clarify that the in-list matcher and single-quoted case are intentionally
detection-only, and reword the celStringLiteral characterization comment.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-64357] Tighten CEL list pattern in simple-expression detection
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Add editor-surface and e2e tests for apostrophe values (MM-64357)
Address review feedback requesting the coverage gaps Linda/Matty flagged:
- Membership Policy surface (policy_details): rendered mode-toggle state
(Switch to Simple Mode enabled) for apostrophe equality and multiselect
OR-group values, plus a complex-expression negative control.
- Permission Policy surface (permission_policy_details): apostrophe
equality/in-list/OR-group open in Simple mode and keep the toggle enabled,
covering the shared isSimpleExpression path on both surfaces.
- Playwright e2e: apostrophe 'is' value round-trips through save/reopen and
the Switch to Simple Mode toggle stays enabled (button state + persistence).
* Fix apostrophe values e2e test cleanup to be independent of list rendering
- Add fallback policy lookup by name in finally block
- Ensures cleanup happens even when navigation/assertions fail after save
- Addresses CodeRabbit feedback on test stability
Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>
* the main fix + unit tests
* add actual analysis-icu-less docker containers in CI to lock it down
* fix AppError test assertions
* fix CI search startup tests
* fix bulk processor flusher shutdown
* fix bulk shutdown test assertion
* Revert "add actual analysis-icu-less docker containers in CI to lock it down"
This reverts commit dfa9aacb08.
* simplify analysis-icu startup guidance
* fix OpenSearch bulk flusher shutdown
* linting fix
* query nodes directly for plugins instead of trying and catching err
* remove unneeded comments
* Fix link preview image layout shift by reserving space with SizeAwareImage
Open graph link previews rendered a plain <img> with no upfront dimensions.
When metadata reported large images (e.g. 2400×1256), the preview started at
zero height and expanded after load, pushing content below and causing scroll
pop in the channel and permalink views.
Use SizeAwareImage (same approach as post images and message attachments) so
known dimensions reserve layout before the image loads. Add
getScaledImageDimensions() to scale metadata down to the preview's CSS limits
(392×240 for large images, 80×80 for thumbnails) so placeholders match the
final rendered size rather than SizeAwareImage's default 350px cap.
Centralize layout constants in constants.ts and sass/utils/_variables.scss
with cross-reference comments, and wire post_attachment_opengraph.scss to
those variables to keep TS layout math and CSS in sync.
Also hide copy/download utility buttons on link preview images via
hideUtilities={true}.
* Change the opengraph dimention variables from SCSS to CSS
* Lint and update snapshot
* Add additional E2E test
This test passes on master in Chrome but not in Firefox.
* Update URL in opengraph-huge.html
---------
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
* [MM-69557] Fix post actions menu not closing on outside click in mobile view
In the narrow/mobile-responsive layout the post actions ("…") menu renders
as a full-height GenericModal. React-bootstrap only dismisses the modal when
its outer container is clicked directly, but the full-height dialog element
intercepted every click in the dimmed area around the menu, so clicking
outside never closed it.
Let clicks on the empty dialog area fall through to the modal container via
pointer-events (scoped to .menuModal) so clicking outside dismisses the menu,
matching standard popup behavior, while keeping the menu itself interactive.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69557] Add E2E test for mobile post actions menu outside-click dismissal
Adds a Playwright spec covering the mobile/narrow layout where the post actions
("…") menu renders as a full-screen modal. Verifies clicking the dimmed area
outside the menu (both above and below the menu list) dismisses it, and that
selecting a menu item still works. The outside-click test fails without the
pointer-events fix, so it is coupled to the real behavior.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69557] Use type-only import for PlaywrightExtended in mobile dot menu spec
Satisfies the @typescript-eslint/consistent-type-imports lint rule.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69557] Don't treat pointer-events: none as non-focusable in focus trap
The mobile menu fix sets pointer-events: none on .menuModal (restoring
auto on .modal-content). useFocusTrap's isElementVisible() walked the
ancestor chain and rejected any element under a pointer-events: none
ancestor, which broke keyboard focus trapping inside the modal.
pointer-events only affects mouse/touch hit-testing, not keyboard
focusability, and can be re-enabled on descendants, so remove it from
the visibility check. Adds a regression test.
* Address PR feedback: make focus-trap test spy cleanup exception-safe
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
PR #37646 (Migrate UserStore Get to request context) migrated
context.Background() call sites to request.CTX but left the now-dead
"context" import in place, assuming other usages in the same files
would keep it alive. A concurrently merged sibling PR (#37637,
GetAllProfilesInChannel migration) removed those other usages first,
so by the time #37646 landed on top of the moved master tip the
import had no remaining references, breaking go vet/build on master.
Affected: server/channels/store/sqlstore/user_store.go,
server/channels/store/storetest/user_store.go,
server/channels/store/storetest/mocks/UserStore.go,
server/channels/store/localcachelayer/user_layer.go(_test.go),
server/channels/app/post_persistent_notification.go
Co-authored-by: Claude <noreply@anthropic.com>
* MM-69886: Refresh Channel Members RHS on websocket add and reconnect
The Channel Members RHS (participant list) could omit members in two
general cases:
- On a user_added websocket event, handleUserAddedEvent recorded the
profile-in-channel entry and loaded the profile but never loaded the
ChannelMembership. buildProfileList drops any user without a
membership, so a member added while the channel was open did not
appear until the list was fully reloaded. It also affected members
whose profile was already loaded (e.g. after they posted) but who
still had no membership. Fetch the membership via getChannelMember
when it is missing.
- On websocket reconnect, reconnect() reloads only the current user's
own memberships, never the channel roster, and missed user_added /
user_removed events are not replayed on a fresh (non-resumed)
connection. Members added or removed while disconnected stayed stale
until the channel was re-opened. The RHS now reloads the roster when
the websocket connection id changes.
This extends the reconcile-on-load work from MM-68660 (PR #36964, same
loadProfilesAndReloadChannelMembers path), which pruned removals only
on channel (re)load and did not cover live adds or reconnects.
Found while re-testing MM-67616 (Shared Channels), where synced members
were not reflected in the participant list even though the server-side
sync was correct.
* Add comment to caution about changing remote cluster service ping frequency.
* [MM-69726] Fix Message actions menu rendering off screen in narrow view
In mobile/single-column view the post Message actions menu renders as a
full-screen fixed overlay. Because posts live inside the virtualized post
list, whose `will-change: transform` establishes a containing block for
fixed-position descendants, the overlay anchored to the scrolled post list
content instead of the viewport. For longer channels/threads this pushed the
menu off screen (to the top of the message pane) so it appeared to do nothing.
Portal the mobile Message actions menu to document.body so its fixed overlay
is positioned relative to the viewport, and extend the mobile overlay styles
to the portaled container.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69726] Keep portaled Message actions menu open until item click resolves
The mobile Message actions menu is portaled to the body, so it lives outside
the MenuWrapper node in the DOM. MenuWrapper's capture-phase blur handler
treated clicks inside the portaled menu as outside clicks and closed the menu
before the item's onClick fired (synchronously under the legacy React root),
so selecting an item did nothing. Mark the portal and skip blur-close for
clicks inside it.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69726] Add tests for portaled mobile Message actions menu
Cover that the ActionsMenu portals its menu to the body in mobile view and
renders inline on desktop, and that MenuWrapper's blur handling keeps a
portaled menu open while still closing on genuine outside clicks.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69726] Add integration coverage for portaled menu item clicks
Add a test that clicking an item in the portaled mobile Message actions menu
runs its action (the exact behavior the blur-handler fix restored), and a TAB
keyboard test mirroring the click-based portal exception.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69726] Clarify portaled menu item test name
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69726] Fix import order in actions_menu test
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69726] Move portaled-menu blur handling out of generic MenuWrapper
Replace the hardcoded [data-menu-portal] selector in MenuWrapper.closeOnBlur
with a generic, opt-in portalNodeRef prop. ActionsMenu now owns the portal
detail and passes its portal node ref, keeping the generic (deprecated) widget
free of consumer-specific conditions.
* [MM-69726] Satisfy jsx-max-props-per-line in menu wrapper test
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* fix(mmctl): lengthen sampledata passwords to meet FIPS minimum
Zero-pad user index to 3 digits in guest and regular-user password
format strings so all generated passwords are >= 14 characters,
matching PasswordFIPSMinimumLength. Update inject-test-data login
hint and add a regression test.
Co-authored-by: Julien Tant <JulienTant@users.noreply.github.com>
* Simplify sampledata password length test comment
Co-authored-by: Julien Tant <JulienTant@users.noreply.github.com>
* Use subtests in sampledata password length coverage
So a single require failure reports only that case instead of
aborting the rest of the matrix.
Co-authored-by: Julien Tant <JulienTant@users.noreply.github.com>
* Name default-user subtests as user for clarity
Co-authored-by: Julien Tant <JulienTant@users.noreply.github.com>
* Run sampledata password length subtests in parallel
Co-authored-by: Julien Tant <JulienTant@users.noreply.github.com>
* Empty commit to re-trigger CI
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Julien Tant <JulienTant@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* [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.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* 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.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* 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.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* 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: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* MM-70016: Fix edge case in team invitation handling
* Add test coverage for guest magic link invitation token
---------
Co-authored-by: Bill Gardner <billg@wavearts.com>
* [MM-70186] Add tooltips to platform icons in session attribute picker
Wrap the browser/desktop/mobile platform icons rendered as trailing
elements in the session attribute selector menu with WithTooltip so
hovering reveals the client context each icon represents.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70186] Add tests for platform icon tooltips in attribute picker
Cover the accessible label mapping for each platform icon and assert the
Desktop/Mobile/Web Browser tooltips open on hover in the session
attribute selector menu.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70186] Cover unknown-platform guard and simplify hover target
Add a case ensuring platforms without a matching icon are dropped while
known platforms still render, and target the icon's parent span directly
for the hover assertions.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Add tooltips to platform icons in main Session Attributes table
- Wrap each platform icon in WithTooltip
- Update browser label from 'Browser' to 'Web Browser' for consistency with attribute selector
- Add hover tests to verify tooltip behavior
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
* Fix import order lint issue in platform_icons.test.tsx
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
* Refactor platform icons to use shared component and fix tooltip rendering
- Fix tooltip issue in session attributes table by wrapping icon in span
- Make PlatformIcons component flexible with variant prop (all-slots vs active-only)
- Export PLATFORM_ICONS and platformLabels for reuse
- Update attribute selector to use shared PlatformIcons component
- Remove duplicate icon definitions and i18n keys from attribute selector
- This eliminates code duplication and ensures consistent tooltip behavior
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
* Fix lint and type errors from shared PlatformIcons refactor
The shared-component refactor left attribute_selector_menu.tsx referencing
WithTooltip without an import (a runtime ReferenceError for synced/disallowed
attributes), kept now-unused ComponentType/defineMessages imports, and passed a
string[] to PlatformIcons which expects SessionPlatform[]. Restore the tooltip
import, drop the unused imports, and narrow platforms via getSessionAttrs.
Also apply eslint autofixes to platform_icons.tsx.
* Fix platform icon spacing by moving WithTooltip outside styled wrapper
- Move WithTooltip to wrap the outer span instead of adding inner wrapper
- This preserves the original CSS structure for both table and menu
- Fixes: table background now square with proper padding
- Fixes: menu icons maintain original spacing
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
* Fix dropdown menu icon spacing by rendering icons individually
- Replace PlatformIcons component usage in menu with individual icon rendering
- Each icon is now a separate element in trailingElements array
- Maintains proper spacing between icons in the dropdown menu
- Preserves shared PLATFORM_ICONS and platformLabels from platform_icons module
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
* Remove irrelevant package-lock.json changes
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
* Revert browser label from 'Web Browser' back to 'Browser'
- Keep the existing 'Browser' verbiage in i18n and all references
- Update platformLabels default message to 'Browser'
- Update all test assertions to expect 'Browser' instead of 'Web Browser'
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
* MM-70072: Fix role validation for channel and team member updates
* MM-70072: Assert specific error ID in guest/admin role regression tests
Make the new regression tests assert the specific error ID returned for
the guest+admin role combination, rather than only checking for a
generic bad-request status.
* [MM-70153] Fix error deleting the only remaining channel permission rule
Deleting the last permission rule in a channel's Permissions Policy tab
left the channel policy with no rules and no imports, which the server
rejects with "Unable to save access control policy." Mirror the
Membership Policy tab and delete the channel policy instead when the
resulting policy would be empty, returning the channel to standard access.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70153] Add tests for removing the last channel permission rule
Covers deleting the empty channel policy on save, preserving a remaining
membership rule, and surfacing a non-404 delete failure.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70153] Cover 404-as-success and imports-present branches
Add tests confirming a 404 delete is treated as success and that a policy
with remaining imports is saved rather than deleted when the last
permission rule is removed.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70153] Reset originalActive after empty channel policy delete
After deleting an emptied channel policy, clear the stale active flag so
a subsequent save in the same tab session does not re-enable membership
auto-sync. Mirrors the Membership Policy tab empty-delete path.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70142] Fix simulate access editor popover overflow
Cap the session-attribute editor form to the viewport height and make
the field grid scroll so the Apply/Cancel actions stay reachable when
many environmental attributes are configured.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70142] Cap simulate access popover to available viewport height
Use Floating UI's size middleware to constrain the session-attribute
editor popover to the space available on its chosen side, and make the
panel a flex column whose field grid scrolls, so the Apply/Cancel
actions stay reachable regardless of anchor position or attribute count.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Save / Cancel buttons in non-US (e.g. ja-JP) had wrapped button
text in the button at narrow widths.
Signed-off-by: Takuya Noguchi <takninnovationresearch@gmail.com>
* [MM-70155] Wrap role/permission dropdown descriptions in channel permission policy editor
The role and permission option dropdowns in the channel Permissions Policy
editor render two-line menu items (title + description). The shared menu item
sizes its label column to its content width, so long descriptions overflowed
the menu horizontally instead of wrapping.
Scope a rule to these dropdowns that lets the label column shrink and the
description wrap onto multiple lines.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70155] Raise dropdown wrap selector specificity to outrank MUI styles
The emotion-generated menu item rule (.MuiMenuItem-root > .label-elements)
outranked the initial fix, so the flex override never applied. Qualify the
selector with li.MuiMenuItem-root so the label column can shrink and the
description wraps.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Center trailing check icon in permissions policy dropdowns
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-70025: Fix team search filter combination logic
See MM-70025 for more details.
* MM-70025: Strengthen team search filter tests
Address CodeRabbit review feedback on PR #37749.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* [MM-70154] Truncate long attribute names in permission policy table editor
The attribute selector button renders its icon and label as direct flex
children with no inner wrapper, so the existing truncation selector
(which targets an inner span used by the value selector) never applied
and long attribute names overflowed the Attribute column. Wrap the label
in a span with min-width: 0 and ellipsis truncation.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70154] Add test for truncatable attribute label container
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70154] Fix stylelint property order in attribute label rule
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* [MM-70140] Remove experimental AD/LDAP login button color settings
Remove the dead-code LdapSettings.LoginButtonColor / LoginButtonBorderColor /
LoginButtonTextColor experimental settings. These values were plumbed into the
client config but never consumed by the web or mobile clients, so no AD/LDAP
login button was ever rendered or colored.
Removes the fields from the server config struct and defaults, the client
config payload, the Admin Console Experimental Features section, the webapp
config type, related en.json strings, API definitions, docs, and test/default
config fixtures.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70140] Add test guarding removal of LDAP login button color keys
Assert that GenerateLimitedClientConfig still emits LdapLoginFieldName under an
LDAP license but never emits the removed LdapLoginButtonColor/BorderColor/
TextColor keys, guarding against reintroduction of the dead settings.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70140] Remove LDAP login button colors from webapp LdapSettings type
Keep AdminConfig LdapSettings in sync with the server model after the
experimental AD/LDAP login button color settings were removed.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70140] Update admin console index test after LDAP color removal
Drop experimental/features from the ldap search expectation now that
the AD/LDAP login button color settings are no longer under Experimental.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Address PR feedback: remove test for removed LDAP login button color settings
Per @lieut-data's review, drop TestGenerateLimitedClientConfigOmitsLdapLoginButtonColors;
there's no need to perpetually test that a removed feature stays removed.
* chore: retrigger CI after GitHub Actions service outage
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* chore: retrigger CI after Actions service recovery
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: mattermost-build <mattermost-build@users.noreply.github.com>
* [MM-70141] Remove dead SAML login button color settings
SamlSettings.LoginButtonColor / LoginButtonBorderColor / LoginButtonTextColor
were never consumed by any client (web or mobile) — the values reached the
client config but were never applied to the SAML login button, which renders
with fixed themed CSS. Remove the settings from the server model, client config
payload, Admin Console Experimental Features, webapp config types, config
fixtures, and documentation. The SAML login button label (LoginButtonText)
is retained.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70141] Update admin console index test after SAML color removal
Searching for "saml" no longer matches Experimental Features once the
unused SAML login button color settings are removed from that section.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Address PR feedback: remove unnecessary SAML color removal test case
Per reviewer feedback, drop the GenerateClientConfig test case that
asserted the removed SAML login button color props are absent. There is
no value in perpetually testing that a deleted feature stays deleted.
* chore: retrigger CI after transient Actions outage
Previous Server CI / API / Web App CI failures on 0f03c475 were GitHub
Actions infrastructure errors (Failed to resolve action download info /
Service Unavailable), not related to this PR's changes.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Allow renaming a team's name (slug) via the team update API
The team update API path is sanitized and intentionally ignores the
Name field, so the previously orphaned RenameTeam app method (which no
longer persisted the Name change) is now wired into the updateTeam
handler and fixed to persist the new slug and emit a team update event.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Add --name flag to mmctl team rename
Allow changing a team's name (the URL slug) via mmctl team rename. The
command now accepts --name and/or --display-name, and at least one must
be provided.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Polish team rename error message and fix err shadow
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Strengthen team rename tests
Add regression coverage that the rename path cannot leak non-renamable
fields (email/type), that invalid and duplicate renames leave the slug
unchanged, and a unit case for renaming name and display name together.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Address PR feedback: 1 answered, 1 resolved, 0 declined
* Remove unused App.RenameTeam method
The rename path now goes through App.UpdateTeam (via the team update API
and mmctl), leaving App.RenameTeam orphaned. Remove it and update the
name-occupied error source label to UpdateTeam.
* Return non-not-found errors from team name lookup
Only treat store.ErrNotFound from GetByName as an available slug; any
other lookup failure is now returned instead of silently allowing the
rename to proceed. Addresses CodeRabbit review feedback on the team
update path.
* Remove low-value TestUpdateTeamNameLookupError per review feedback
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Add Playwright E2E tests for demo plugin webapp components
Adds 7 new spec files covering the demo plugin's webapp components:
Root Modal (user actions, menus, post dropdown), sidebar components,
channel header button/RHS, file upload/preview components, and user
settings. Updates helpers.ts with shared assertRootModal and
closeRootModal helpers. Adds sample-file.demo test asset.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Address CodeRabbit review feedback
- Scope 'more actions' button to post container in demo_file_components
- Replace regex with string for profile popover accessible name
- Replace evaluate click with .click() and clean up dialog handler in demo_user_settings
- Remove Cancel bug test from demo_root_modal_menus with explanatory comment
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Implement feedback as per review
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Implement CodeRabbit suggestion: wait for upload response in uploadFileViaYourComputer
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Implement CodeRabbit suggestion: scope hover to post container in demo_file_components
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix: use import type for Client4 to satisfy consistent-type-imports rule
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* E2E/Test: Skip broken Sample Confirmation Dialog test; fix default_config after master merge
- Skip demo_root_modal_menus "Sample Confirmation Dialog": unable to resolve this test failure, it is a bug with the demo plugin. v0.10.3 does not set a URL on the openInteractiveDialog call, causing the webapp to log "Interactive dialog missing URL" and render nothing. Test will be re-enabled once the plugin is fixed and the build bumped.
- Remove EnableAccessControlAuditLogging and AIRecapSettings from default_config.ts — both fields were removed when I synced up from master.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* E2E/Test: Restore EnableAccessControlAuditLogging and AIRecapSettings to default_config
Both fields are still required in @mattermost/types as of master. They were
incorrectly removed in the previous commit because the local dist was stale
after the master merge. Rebuilt webapp platform packages to confirm correct
type state before restoring.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Return error when inviting deactivated users to team
When a user account is deactivated, attempts to invite them to a team
via email should return an error rather than attempting to send the
invitation email.
Added deactivated user checks in:
- InviteNewUsersToTeamGracefully
- InviteNewUsersToTeam
- InviteGuestsToChannelsGracefully
- InviteGuestsToChannels
- localInviteUsersToTeam (mmctl path)
For each invite email, the code now calls GetUserByEmail and checks
whether the returned user has DeleteAt != 0 (deactivated). If so, the
invite is rejected with api.team.invite_members.account_deactivated.app_error.
Fixes MM-57390
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Add missing deactivated-user invite tests for CI coverage
Add tests for InviteGuestsToChannels (non-graceful) and
localInviteUsersToTeam (graceful and non-graceful) to satisfy
PR test analysis requirements.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Handle GetUserByEmail errors in deactivated-user invite checks
Add IsDeactivatedUserEmail helper that distinguishes user-not-found
from lookup failures, and use it across invite paths to avoid
silently proceeding when email lookups fail.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Extract checkForDeactivatedInvites helper to DRY up invite paths
* Tighten checkForDeactivatedInvites doc comment
* Fix govet err shadow in InviteGuestsToChannels
Reuse the existing err from prepareInviteGuestsToChannels instead of
redeclaring it when calling checkForDeactivatedInvites, which was
failing check-style (govet shadow). Apply the same pattern in
InviteNewUsersToTeam for consistency.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* chore: retrigger CI and CodeRabbit review
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Reuse CheckForDeactivatedInvites in local invite path
Export the helper and replace the duplicated non-graceful deactivated
email loop in localInviteUsersToTeam so it shares the same logic as
InviteNewUsersToTeam and InviteGuestsToChannels.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* chore: retrigger CodeRabbit after quiet period
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69737] Add production warning callouts to System Console settings
Add a reactive red danger SectionNotice under System Console settings when
they are configured to a value not recommended for production. Introduces an
optional production_warning descriptor on the admin schema pipeline (and the
LDAP wizard pipeline) that renders between the control and the help text.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69737] Add tests for production warning callout rendering
Cover the schema pipeline rendering path: danger SectionNotice shows for the
insecure value, is absent for the recommended value, toggles reactively without
saving, and works for a wildcard text setting.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69737] Suppress production warning for disabled settings; expand tests
Do not render the danger callout when the setting control is disabled (e.g. SAML
Verify while SAML sign-in is off), so the warning only appears for active,
editable settings. Add coverage for the disabled case, the warns-on-false
predicate, and the LDAP wizard render pipeline.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69737] Address CodeRabbit nitpicks for production warning
Reuse isDisabled in renderHelpTextWithWarning and document that
production_warning is wired for bool/text settings only.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69737] Fix eslint lines-around-comment on production_warning doc
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Fix SectionNotice title margin in admin console
Remove unwanted bottom margin on SectionNotice h4 titles caused by
admin console's general h4 styling rule.
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
* Remove redundant banner warning and scope SectionNotice title fix
- Remove redundant top-level banner warning for testing commands on
Developer Settings page, since inline production warnings now cover
this functionality
- Scope SectionNoticeTitle margin fix to only production warning
callouts (.admin-console__production-warning) rather than all
SectionNotice components in admin console
Addresses feedback from @matthewbirtch and CodeRabbit review.
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
* Remove unused i18n string admin.service.testingWarning
The banner using this string was removed in favor of inline
production warnings, so the i18n string is no longer needed.
Co-authored-by: Joram Wilander <joram@mattermost.com>
* Remove obsolete test for deleted warning banner
The test was checking for a warning banner before the EnableTesting
setting, but that banner was removed in favor of inline production
warnings. The remaining test (checking help text guidance) still passes
and provides the necessary validation.
Co-authored-by: Joram Wilander <joram@mattermost.com>
* Address PR feedback: copy changes to production warning text
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
Co-authored-by: Joram Wilander <joram@mattermost.com>
Use the team-name generator that excludes reserved route prefixes; random IDs can begin with a reserved prefix and make Team.Save fail before the export assertions run.
Tests-only change.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70113] Gate Classification Markings behind Enterprise Advanced license
The Classification Markings System Console section was gated at the
Enterprise license tier, so Enterprise (non-Advanced) admins saw a fully
configurable settings page even though the feature requires Enterprise
Advanced. The feature discovery upsell and restricted indicator already
targeted Enterprise Advanced, confirming the settings gate tier was wrong.
Raise the gate to LicenseSkus.EnterpriseAdvanced for both the settings
subsection and its feature discovery counterpart so Enterprise admins now
see the upgrade prompt, consistent with other Enterprise Advanced features
(e.g. Data Spillage Handling).
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-70113] Assert Classification Markings upsell advertises Enterprise Advanced
Harden the discovery test so the restricted indicator's advertised tier is
verified (not merely defined), guarding against a partial revert of the
license gate.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69587] Remove CustomProfileAttributes feature flag
Remove the CustomProfileAttributes feature flag and all associated
conditional gating, leaving custom profile attributes permanently
enabled (still Enterprise-license gated).
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* [MM-69587] Update admin sidebar snapshots for permanent CPA
User Attributes now appears based solely on license tier since the
feature flag no longer gates it.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* Update channel_header snapshot styled-components icon hash after master merge
Align pending-join-requests snapshot with the Icon-clPswv hash used by all
other ChannelHeader snapshots; CI received this after merging discoverable
channels from master.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
* chore: retrigger CI after unrelated Postgres shard 1 flake
Server CI Postgres (shard 1) failed on TestCheckLdapUserPasswordConcurrency
(mock DoLogin panic under concurrent On/Called) and a one-shot
TestLicenseFromBytesEnvironmentMismatch mismatch that passed on re-run.
Neither touches CustomProfileAttributes removal; empty commit to retrigger.
Co-authored-by: mattermost-code <matty-code@mattermost.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>