mattermost-redux 11.1.0 → 11.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/lib/action_types/agents.d.ts +6 -0
  2. package/lib/action_types/agents.js +13 -0
  3. package/lib/action_types/index.d.ts +2 -1
  4. package/lib/action_types/index.js +3 -1
  5. package/lib/action_types/posts.d.ts +3 -0
  6. package/lib/action_types/posts.js +3 -0
  7. package/lib/actions/access_control.d.ts +2 -1
  8. package/lib/actions/access_control.js +7 -0
  9. package/lib/actions/agents.d.ts +1 -0
  10. package/lib/actions/agents.js +16 -0
  11. package/lib/actions/groups.d.ts +1 -1
  12. package/lib/actions/groups.js +1 -1
  13. package/lib/actions/status_profile_polling.d.ts +7 -0
  14. package/lib/actions/status_profile_polling.js +56 -26
  15. package/lib/actions/teams.d.ts +1 -1
  16. package/lib/actions/teams.js +2 -1
  17. package/lib/constants/permissions.d.ts +4 -1
  18. package/lib/constants/permissions.js +4 -1
  19. package/lib/constants/posts.d.ts +19 -0
  20. package/lib/constants/posts.js +18 -0
  21. package/lib/constants/preferences.d.ts +2 -0
  22. package/lib/constants/preferences.js +2 -0
  23. package/lib/constants/websocket.d.ts +3 -0
  24. package/lib/constants/websocket.js +3 -0
  25. package/lib/reducers/entities/agents.d.ts +10 -0
  26. package/lib/reducers/entities/agents.js +19 -0
  27. package/lib/reducers/entities/index.d.ts +8 -0
  28. package/lib/reducers/entities/index.js +2 -0
  29. package/lib/reducers/entities/posts.js +84 -4
  30. package/lib/reducers/index.d.ts +8 -0
  31. package/lib/selectors/entities/access_control.d.ts +1 -1
  32. package/lib/selectors/entities/access_control.js +4 -7
  33. package/lib/selectors/entities/agents.d.ts +4 -0
  34. package/lib/selectors/entities/agents.js +13 -0
  35. package/lib/selectors/entities/channel_banner.d.ts +0 -1
  36. package/lib/selectors/entities/channel_banner.js +1 -11
  37. package/lib/selectors/entities/posts.js +9 -2
  38. package/lib/store/initial_state.js +3 -0
  39. package/lib/utils/file_utils.d.ts +1 -1
  40. package/lib/utils/file_utils.js +12 -2
  41. package/lib/utils/post_list.js +10 -0
  42. package/lib/utils/post_utils.js +3 -0
  43. package/package.json +3 -3
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ RECEIVED_AGENTS: "RECEIVED_AGENTS";
3
+ AGENTS_REQUEST: "AGENTS_REQUEST";
4
+ AGENTS_FAILURE: "AGENTS_FAILURE";
5
+ };
6
+ export default _default;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const key_mirror_1 = __importDefault(require("mattermost-redux/utils/key_mirror"));
9
+ exports.default = (0, key_mirror_1.default)({
10
+ RECEIVED_AGENTS: null,
11
+ AGENTS_REQUEST: null,
12
+ AGENTS_FAILURE: null,
13
+ });
@@ -1,5 +1,6 @@
1
1
  import type { AnyAction } from 'redux';
2
2
  import AdminTypes from './admin';
3
+ import AgentTypes from './agents';
3
4
  import AppsTypes from './apps';
4
5
  import BotTypes from './bots';
5
6
  import ChannelBookmarkTypes from './channel_bookmarks';
@@ -29,7 +30,7 @@ import SharedChannelTypes from './shared_channels';
29
30
  import TeamTypes from './teams';
30
31
  import ThreadTypes from './threads';
31
32
  import UserTypes from './users';
32
- export { ErrorTypes, GeneralTypes, UserTypes, TeamTypes, ChannelTypes, PostTypes, FileTypes, PreferenceTypes, IntegrationTypes, EmojiTypes, AdminTypes, JobTypes, LimitsTypes, SearchTypes, RoleTypes, SchemeTypes, GroupTypes, BotTypes, PluginTypes, ChannelCategoryTypes, CloudTypes, AppsTypes, ThreadTypes, HostedCustomerTypes, DraftTypes, PlaybookType, ChannelBookmarkTypes, ScheduledPostTypes, SharedChannelTypes, ContentFlaggingTypes, };
33
+ export { ErrorTypes, GeneralTypes, UserTypes, TeamTypes, ChannelTypes, PostTypes, FileTypes, PreferenceTypes, IntegrationTypes, EmojiTypes, AdminTypes, JobTypes, LimitsTypes, SearchTypes, RoleTypes, SchemeTypes, GroupTypes, BotTypes, PluginTypes, ChannelCategoryTypes, CloudTypes, AppsTypes, ThreadTypes, HostedCustomerTypes, DraftTypes, PlaybookType, ChannelBookmarkTypes, ScheduledPostTypes, SharedChannelTypes, ContentFlaggingTypes, AgentTypes, };
33
34
  /**
34
35
  * An MMReduxAction is any non-Thunk Redux action accepted by mattermost-redux.
35
36
  */
@@ -5,9 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
6
  };
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.ContentFlaggingTypes = exports.SharedChannelTypes = exports.ScheduledPostTypes = exports.ChannelBookmarkTypes = exports.PlaybookType = exports.DraftTypes = exports.HostedCustomerTypes = exports.ThreadTypes = exports.AppsTypes = exports.CloudTypes = exports.ChannelCategoryTypes = exports.PluginTypes = exports.BotTypes = exports.GroupTypes = exports.SchemeTypes = exports.RoleTypes = exports.SearchTypes = exports.LimitsTypes = exports.JobTypes = exports.AdminTypes = exports.EmojiTypes = exports.IntegrationTypes = exports.PreferenceTypes = exports.FileTypes = exports.PostTypes = exports.ChannelTypes = exports.TeamTypes = exports.UserTypes = exports.GeneralTypes = exports.ErrorTypes = void 0;
8
+ exports.AgentTypes = exports.ContentFlaggingTypes = exports.SharedChannelTypes = exports.ScheduledPostTypes = exports.ChannelBookmarkTypes = exports.PlaybookType = exports.DraftTypes = exports.HostedCustomerTypes = exports.ThreadTypes = exports.AppsTypes = exports.CloudTypes = exports.ChannelCategoryTypes = exports.PluginTypes = exports.BotTypes = exports.GroupTypes = exports.SchemeTypes = exports.RoleTypes = exports.SearchTypes = exports.LimitsTypes = exports.JobTypes = exports.AdminTypes = exports.EmojiTypes = exports.IntegrationTypes = exports.PreferenceTypes = exports.FileTypes = exports.PostTypes = exports.ChannelTypes = exports.TeamTypes = exports.UserTypes = exports.GeneralTypes = exports.ErrorTypes = void 0;
9
9
  const admin_1 = __importDefault(require("./admin"));
10
10
  exports.AdminTypes = admin_1.default;
11
+ const agents_1 = __importDefault(require("./agents"));
12
+ exports.AgentTypes = agents_1.default;
11
13
  const apps_1 = __importDefault(require("./apps"));
12
14
  exports.AppsTypes = apps_1.default;
13
15
  const bots_1 = __importDefault(require("./bots"));
@@ -41,5 +41,8 @@ declare const _default: {
41
41
  DELETE_ACK_POST_SUCCESS: "DELETE_ACK_POST_SUCCESS";
42
42
  MOVE_POST_SUCCESS: "MOVE_POST_SUCCESS";
43
43
  MOVE_POST_FAILURE: "MOVE_POST_FAILURE";
44
+ REVEAL_BURN_ON_READ_SUCCESS: "REVEAL_BURN_ON_READ_SUCCESS";
45
+ POST_RECIPIENTS_UPDATED: "POST_RECIPIENTS_UPDATED";
46
+ BURN_ON_READ_ALL_REVEALED: "BURN_ON_READ_ALL_REVEALED";
44
47
  };
45
48
  export default _default;
@@ -49,4 +49,7 @@ exports.default = (0, key_mirror_1.default)({
49
49
  DELETE_ACK_POST_SUCCESS: null,
50
50
  MOVE_POST_SUCCESS: null,
51
51
  MOVE_POST_FAILURE: null,
52
+ REVEAL_BURN_ON_READ_SUCCESS: null,
53
+ POST_RECIPIENTS_UPDATED: null,
54
+ BURN_ON_READ_ALL_REVEALED: null,
52
55
  });
@@ -1,4 +1,4 @@
1
- import type { AccessControlPoliciesResult, AccessControlPolicy, AccessControlTestResult } from '@mattermost/types/access_control';
1
+ import type { AccessControlPoliciesResult, AccessControlPolicy, AccessControlPolicyActiveUpdate, AccessControlTestResult } from '@mattermost/types/access_control';
2
2
  import type { ChannelSearchOpts, ChannelsWithTotalCount } from '@mattermost/types/channels';
3
3
  import type { ActionFuncAsync } from 'mattermost-redux/types/actions';
4
4
  export declare function getAccessControlPolicy(id: string, channelId?: string): ActionFuncAsync<AccessControlPolicy, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
@@ -18,3 +18,4 @@ export declare function validateExpressionAgainstRequester(expression: string, c
18
18
  export declare function createAccessControlSyncJob(jobData: {
19
19
  policy_id: string;
20
20
  }): ActionFuncAsync<any>;
21
+ export declare function updateAccessControlPoliciesActive(states: AccessControlPolicyActiveUpdate[]): ActionFuncAsync<AccessControlPolicy[], import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
@@ -15,6 +15,7 @@ exports.searchUsersForExpression = searchUsersForExpression;
15
15
  exports.getVisualAST = getVisualAST;
16
16
  exports.validateExpressionAgainstRequester = validateExpressionAgainstRequester;
17
17
  exports.createAccessControlSyncJob = createAccessControlSyncJob;
18
+ exports.updateAccessControlPoliciesActive = updateAccessControlPoliciesActive;
18
19
  const redux_batched_actions_1 = require("redux-batched-actions");
19
20
  const action_types_1 = require("mattermost-redux/action_types");
20
21
  const client_1 = require("mattermost-redux/client");
@@ -170,3 +171,9 @@ function createAccessControlSyncJob(jobData) {
170
171
  return { data };
171
172
  };
172
173
  }
174
+ function updateAccessControlPoliciesActive(states) {
175
+ return (0, helpers_1.bindClientFunc)({
176
+ clientFunc: client_1.Client4.updateAccessControlPoliciesActive,
177
+ params: [states],
178
+ });
179
+ }
@@ -0,0 +1 @@
1
+ export declare function getAgents(): import("../types/actions").ActionFuncAsync<import("@mattermost/types/agents").Agent[], import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.getAgents = getAgents;
6
+ const helpers_1 = require("./helpers");
7
+ const action_types_1 = require("../action_types");
8
+ const client_1 = require("../client");
9
+ function getAgents() {
10
+ return (0, helpers_1.bindClientFunc)({
11
+ clientFunc: client_1.Client4.getAgents,
12
+ onSuccess: [action_types_1.AgentTypes.RECEIVED_AGENTS],
13
+ onFailure: action_types_1.AgentTypes.AGENTS_FAILURE,
14
+ onRequest: action_types_1.AgentTypes.AGENTS_REQUEST,
15
+ });
16
+ }
@@ -33,7 +33,7 @@ export declare function getGroupStats(groupID: string): ActionFuncAsync<import("
33
33
  export declare function createGroupWithUserIds(group: GroupCreateWithUserIds): ActionFuncAsync<Group>;
34
34
  export declare function addUsersToGroup(groupId: string, userIds: string[]): ActionFuncAsync<GroupMember[]>;
35
35
  export declare function removeUsersFromGroup(groupId: string, userIds: string[]): ActionFuncAsync<GroupMember[]>;
36
- export declare function searchGroups(params: GroupSearchParams): ActionFuncAsync;
36
+ export declare function searchGroups(params: GroupSearchParams): ActionFuncAsync<Group[]>;
37
37
  export declare function archiveGroup(groupId: string): ActionFuncAsync<Group>;
38
38
  export declare function restoreGroup(groupId: string): ActionFuncAsync<Group>;
39
39
  export declare function createGroupTeamsAndChannels(userID: string): ActionFuncAsync<{
@@ -402,7 +402,7 @@ function searchGroups(params) {
402
402
  dispatches.push({ type: action_types_1.ChannelTypes.RECEIVED_CHANNEL_MEMBER_COUNTS_FROM_GROUPS_LIST, data, channelId: params.include_channel_member_count });
403
403
  }
404
404
  dispatch((0, redux_batched_actions_1.batchActions)(dispatches));
405
- return { data: true };
405
+ return { data };
406
406
  };
407
407
  }
408
408
  function archiveGroup(groupId) {
@@ -12,9 +12,16 @@ export declare function addUserIdsForStatusFetchingPoll(userIdsForStatus: Array<
12
12
  */
13
13
  export declare function addUserIdsForProfileFetchingPoll(userIdsForProfile: Array<UserProfile['id']>): ActionFunc<boolean>;
14
14
  export declare function cleanUpStatusAndProfileFetchingPoll(): ThunkActionFunc<void>;
15
+ interface UserIdsAndMentions {
16
+ userIdsForProfilePoll: Array<UserProfile['id']>;
17
+ userIdsForStatusPoll: Array<UserProfile['id']>;
18
+ mentionedUsernamesAndGroups: string[];
19
+ }
20
+ export declare function extractUserIdsAndMentionsFromPosts(posts: Post[]): ActionFunc<UserIdsAndMentions>;
15
21
  /**
16
22
  * Gets in batch the user profiles, user statuses and user groups for the users in the posts list
17
23
  * This action however doesn't refetch the profiles and statuses except for groups if they are already fetched once
18
24
  */
19
25
  export declare function batchFetchStatusesProfilesGroupsFromPosts(postsArrayOrMap: Post[] | PostList['posts'] | Post): ActionFunc<boolean>;
20
26
  export declare function getUsersFromMentionedUsernamesAndGroups(usernamesAndGroups: string[], isLicensed: boolean): ActionFuncAsync<string[]>;
27
+ export {};
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.addUserIdsForStatusFetchingPoll = addUserIdsForStatusFetchingPoll;
6
6
  exports.addUserIdsForProfileFetchingPoll = addUserIdsForProfileFetchingPoll;
7
7
  exports.cleanUpStatusAndProfileFetchingPoll = cleanUpStatusAndProfileFetchingPoll;
8
+ exports.extractUserIdsAndMentionsFromPosts = extractUserIdsAndMentionsFromPosts;
8
9
  exports.batchFetchStatusesProfilesGroupsFromPosts = batchFetchStatusesProfilesGroupsFromPosts;
9
10
  exports.getUsersFromMentionedUsernamesAndGroups = getUsersFromMentionedUsernamesAndGroups;
10
11
  const groups_1 = require("mattermost-redux/actions/groups");
@@ -72,28 +73,17 @@ function cleanUpStatusAndProfileFetchingPoll() {
72
73
  loaders.pollingProfileLoader?.stopInterval();
73
74
  };
74
75
  }
75
- /**
76
- * Gets in batch the user profiles, user statuses and user groups for the users in the posts list
77
- * This action however doesn't refetch the profiles and statuses except for groups if they are already fetched once
78
- */
79
- function batchFetchStatusesProfilesGroupsFromPosts(postsArrayOrMap) {
76
+ function extractUserIdsAndMentionsFromPosts(posts) {
80
77
  return (dispatch, getState) => {
81
- if (!postsArrayOrMap) {
82
- return { data: false };
83
- }
84
- let posts = [];
85
- if (Array.isArray(postsArrayOrMap)) {
86
- posts = postsArrayOrMap;
87
- }
88
- else if (typeof postsArrayOrMap === 'object' && 'id' in postsArrayOrMap) {
89
- posts = [postsArrayOrMap];
90
- }
91
- else if (typeof postsArrayOrMap === 'object') {
92
- posts = Object.values(postsArrayOrMap);
93
- }
94
78
  if (posts.length === 0) {
95
- return { data: false };
79
+ return { data: {
80
+ userIdsForProfilePoll: [],
81
+ userIdsForStatusPoll: [],
82
+ mentionedUsernamesAndGroups: [],
83
+ } };
96
84
  }
85
+ const userIdsForProfilePoll = new Set();
86
+ const userIdsForStatusPoll = new Set();
97
87
  const mentionedUsernamesAndGroupsInPosts = new Set();
98
88
  const state = getState();
99
89
  const currentUser = (0, common_1.getCurrentUser)(state);
@@ -109,10 +99,10 @@ function batchFetchStatusesProfilesGroupsFromPosts(postsArrayOrMap) {
109
99
  if (embed.type === 'permalink' && embed.data) {
110
100
  const permalinkPostPreviewMetaData = embed.data;
111
101
  if (permalinkPostPreviewMetaData.post?.user_id && !users[permalinkPostPreviewMetaData.post.user_id] && permalinkPostPreviewMetaData.post.user_id !== currentUserId) {
112
- dispatch(addUserIdsForProfileFetchingPoll([permalinkPostPreviewMetaData.post.user_id]));
102
+ userIdsForProfilePoll.add(permalinkPostPreviewMetaData.post.user_id);
113
103
  }
114
104
  if (permalinkPostPreviewMetaData.post?.user_id && !userStatuses[permalinkPostPreviewMetaData.post.user_id] && permalinkPostPreviewMetaData.post.user_id !== currentUserId && isUserStatusesConfigEnabled) {
115
- dispatch(addUserIdsForStatusFetchingPoll([permalinkPostPreviewMetaData.post.user_id]));
105
+ userIdsForStatusPoll.add(permalinkPostPreviewMetaData.post.user_id);
116
106
  }
117
107
  }
118
108
  });
@@ -121,7 +111,7 @@ function batchFetchStatusesProfilesGroupsFromPosts(postsArrayOrMap) {
121
111
  if (post.metadata.acknowledgements) {
122
112
  post.metadata.acknowledgements.forEach((ack) => {
123
113
  if (ack.acknowledged_at > 0 && ack.user_id && !users[ack.user_id] && ack.user_id !== currentUserId) {
124
- dispatch(addUserIdsForProfileFetchingPoll([ack.user_id]));
114
+ userIdsForProfilePoll.add(ack.user_id);
125
115
  }
126
116
  });
127
117
  }
@@ -129,12 +119,12 @@ function batchFetchStatusesProfilesGroupsFromPosts(postsArrayOrMap) {
129
119
  // This is sufficient to check if the profile is already fetched
130
120
  // as we receive the websocket events for the profiles changes
131
121
  if (!users[post.user_id] && post.user_id !== currentUserId) {
132
- dispatch(addUserIdsForProfileFetchingPoll([post.user_id]));
122
+ userIdsForProfilePoll.add(post.user_id);
133
123
  }
134
124
  // This is sufficient to check if the status is already fetched
135
125
  // as we do the polling for statuses for current channel's channel members every 1 minute in channel_controller
136
126
  if (!userStatuses[post.user_id] && post.user_id !== currentUserId && isUserStatusesConfigEnabled) {
137
- dispatch(addUserIdsForStatusFetchingPoll([post.user_id]));
127
+ userIdsForStatusPoll.add(post.user_id);
138
128
  }
139
129
  // We need to check for all @mentions in the post, they can be either users or groups
140
130
  const mentioned = (0, posts_1.getNeededAtMentionedUsernamesAndGroups)(state, [post]);
@@ -146,8 +136,48 @@ function batchFetchStatusesProfilesGroupsFromPosts(postsArrayOrMap) {
146
136
  });
147
137
  }
148
138
  });
149
- if (mentionedUsernamesAndGroupsInPosts.size > 0) {
150
- dispatch(getUsersFromMentionedUsernamesAndGroups(Array.from(mentionedUsernamesAndGroupsInPosts), (0, general_1.getLicense)(state).IsLicensed === 'true'));
139
+ return { data: {
140
+ userIdsForProfilePoll: Array.from(userIdsForProfilePoll),
141
+ userIdsForStatusPoll: Array.from(userIdsForStatusPoll),
142
+ mentionedUsernamesAndGroups: Array.from(mentionedUsernamesAndGroupsInPosts),
143
+ } };
144
+ };
145
+ }
146
+ /**
147
+ * Gets in batch the user profiles, user statuses and user groups for the users in the posts list
148
+ * This action however doesn't refetch the profiles and statuses except for groups if they are already fetched once
149
+ */
150
+ function batchFetchStatusesProfilesGroupsFromPosts(postsArrayOrMap) {
151
+ return (dispatch, getState) => {
152
+ if (!postsArrayOrMap) {
153
+ return { data: false };
154
+ }
155
+ let posts = [];
156
+ if (Array.isArray(postsArrayOrMap)) {
157
+ posts = postsArrayOrMap;
158
+ }
159
+ else if (typeof postsArrayOrMap === 'object' && 'id' in postsArrayOrMap) {
160
+ posts = [postsArrayOrMap];
161
+ }
162
+ else if (typeof postsArrayOrMap === 'object') {
163
+ posts = Object.values(postsArrayOrMap);
164
+ }
165
+ if (posts.length === 0) {
166
+ return { data: false };
167
+ }
168
+ const state = getState();
169
+ const { data: result } = dispatch(extractUserIdsAndMentionsFromPosts(posts));
170
+ if (!result) {
171
+ return { data: false };
172
+ }
173
+ if (result.userIdsForProfilePoll.length > 0) {
174
+ dispatch(addUserIdsForProfileFetchingPoll(result.userIdsForProfilePoll));
175
+ }
176
+ if (result.userIdsForStatusPoll.length > 0) {
177
+ dispatch(addUserIdsForStatusFetchingPoll(result.userIdsForStatusPoll));
178
+ }
179
+ if (result.mentionedUsernamesAndGroups.length > 0) {
180
+ dispatch(getUsersFromMentionedUsernamesAndGroups(result.mentionedUsernamesAndGroups, (0, general_1.getLicense)(state).IsLicensed === 'true'));
151
181
  }
152
182
  return { data: true };
153
183
  };
@@ -41,7 +41,7 @@ export declare function removeUserFromTeam(teamId: string, userId: string): Acti
41
41
  export declare function sendEmailInvitesToTeam(teamId: string, emails: string[]): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, AnyAction>;
42
42
  export declare function sendEmailGuestInvitesToChannels(teamId: string, channelIds: string[], emails: string[], message: string): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, AnyAction>;
43
43
  export declare function sendEmailInvitesToTeamGracefully(teamId: string, emails: string[]): ActionFuncAsync<import("@mattermost/types/teams").TeamInviteWithError[], import("@mattermost/types/store").GlobalState, AnyAction>;
44
- export declare function sendEmailGuestInvitesToChannelsGracefully(teamId: string, channelIds: string[], emails: string[], message: string): ActionFuncAsync<import("@mattermost/types/teams").TeamInviteWithError[], import("@mattermost/types/store").GlobalState, AnyAction>;
44
+ export declare function sendEmailGuestInvitesToChannelsGracefully(teamId: string, channelIds: string[], emails: string[], message: string, guestMagicLink?: boolean): ActionFuncAsync<import("@mattermost/types/teams").TeamInviteWithError[], import("@mattermost/types/store").GlobalState, AnyAction>;
45
45
  export declare function sendEmailInvitesToTeamAndChannelsGracefully(teamId: string, channelIds: string[], emails: string[], message: string): ActionFuncAsync<import("@mattermost/types/teams").TeamInviteWithError[], import("@mattermost/types/store").GlobalState, AnyAction>;
46
46
  export declare function getTeamInviteInfo(inviteId: string): ActionFuncAsync<{
47
47
  display_name: string;
@@ -544,7 +544,7 @@ function sendEmailInvitesToTeamGracefully(teamId, emails) {
544
544
  ],
545
545
  });
546
546
  }
547
- function sendEmailGuestInvitesToChannelsGracefully(teamId, channelIds, emails, message) {
547
+ function sendEmailGuestInvitesToChannelsGracefully(teamId, channelIds, emails, message, guestMagicLink = false) {
548
548
  return (0, helpers_1.bindClientFunc)({
549
549
  clientFunc: client_1.Client4.sendEmailGuestInvitesToChannelsGracefully,
550
550
  params: [
@@ -552,6 +552,7 @@ function sendEmailGuestInvitesToChannelsGracefully(teamId, channelIds, emails, m
552
552
  channelIds,
553
553
  emails,
554
554
  message,
555
+ guestMagicLink,
555
556
  ],
556
557
  });
557
558
  }
@@ -2,6 +2,7 @@ declare const values: {
2
2
  INVITE_USER: string;
3
3
  ADD_USER_TO_TEAM: string;
4
4
  MANAGE_SLASH_COMMANDS: string;
5
+ MANAGE_OWN_SLASH_COMMANDS: string;
5
6
  MANAGE_OTHERS_SLASH_COMMANDS: string;
6
7
  CREATE_PUBLIC_CHANNEL: string;
7
8
  CREATE_PRIVATE_CHANNEL: string;
@@ -44,12 +45,14 @@ declare const values: {
44
45
  MANAGE_WEBHOOKS: string;
45
46
  MANAGE_OTHERS_WEBHOOKS: string;
46
47
  MANAGE_INCOMING_WEBHOOKS: string;
48
+ MANAGE_OWN_INCOMING_WEBHOOKS: string;
49
+ BYPASS_INCOMING_WEBHOOK_CHANNEL_LOCK: string;
47
50
  MANAGE_OTHERS_INCOMING_WEBHOOKS: string;
48
51
  MANAGE_OUTGOING_WEBHOOKS: string;
52
+ MANAGE_OWN_OUTGOING_WEBHOOKS: string;
49
53
  MANAGE_OTHERS_OUTGOING_WEBHOOKS: string;
50
54
  MANAGE_OAUTH: string;
51
55
  MANAGE_OUTGOING_OAUTH_CONNECTIONS: string;
52
- MANAGE_SYSTEM_WIDE_OAUTH: string;
53
56
  CREATE_POST: string;
54
57
  CREATE_POST_PUBLIC: string;
55
58
  EDIT_POST: string;
@@ -6,6 +6,7 @@ const values = {
6
6
  INVITE_USER: 'invite_user',
7
7
  ADD_USER_TO_TEAM: 'add_user_to_team',
8
8
  MANAGE_SLASH_COMMANDS: 'manage_slash_commands',
9
+ MANAGE_OWN_SLASH_COMMANDS: 'manage_own_slash_commands',
9
10
  MANAGE_OTHERS_SLASH_COMMANDS: 'manage_others_slash_commands',
10
11
  CREATE_PUBLIC_CHANNEL: 'create_public_channel',
11
12
  CREATE_PRIVATE_CHANNEL: 'create_private_channel',
@@ -48,12 +49,14 @@ const values = {
48
49
  MANAGE_WEBHOOKS: 'manage_webhooks',
49
50
  MANAGE_OTHERS_WEBHOOKS: 'manage_others_webhooks',
50
51
  MANAGE_INCOMING_WEBHOOKS: 'manage_incoming_webhooks',
52
+ MANAGE_OWN_INCOMING_WEBHOOKS: 'manage_own_incoming_webhooks',
53
+ BYPASS_INCOMING_WEBHOOK_CHANNEL_LOCK: 'bypass_incoming_webhook_channel_lock',
51
54
  MANAGE_OTHERS_INCOMING_WEBHOOKS: 'manage_others_incoming_webhooks',
52
55
  MANAGE_OUTGOING_WEBHOOKS: 'manage_outgoing_webhooks',
56
+ MANAGE_OWN_OUTGOING_WEBHOOKS: 'manage_own_outgoing_webhooks',
53
57
  MANAGE_OTHERS_OUTGOING_WEBHOOKS: 'manage_others_outgoing_webhooks',
54
58
  MANAGE_OAUTH: 'manage_oauth',
55
59
  MANAGE_OUTGOING_OAUTH_CONNECTIONS: 'manage_outgoing_oauth_connections',
56
- MANAGE_SYSTEM_WIDE_OAUTH: 'manage_system_wide_oauth',
57
60
  CREATE_POST: 'create_post',
58
61
  CREATE_POST_PUBLIC: 'create_post_public',
59
62
  EDIT_POST: 'edit_post',
@@ -27,6 +27,7 @@ export declare const PostTypes: {
27
27
  REMINDER: PostType;
28
28
  WRANGLER: PostType;
29
29
  GM_CONVERTED_TO_CHANNEL: PostType;
30
+ BURN_ON_READ: PostType;
30
31
  };
31
32
  declare const _default: {
32
33
  POST_CHUNK_SIZE: number;
@@ -61,6 +62,7 @@ declare const _default: {
61
62
  REMINDER: PostType;
62
63
  WRANGLER: PostType;
63
64
  GM_CONVERTED_TO_CHANNEL: PostType;
65
+ BURN_ON_READ: PostType;
64
66
  };
65
67
  MESSAGE_TYPES: {
66
68
  POST: string;
@@ -70,5 +72,22 @@ declare const _default: {
70
72
  POST_COLLAPSE_TIMEOUT: number;
71
73
  IGNORE_POST_TYPES: PostType[];
72
74
  USER_ACTIVITY_POST_TYPES: PostType[];
75
+ BURN_ON_READ: {
76
+ DURATION_1_MINUTE: number;
77
+ DURATION_5_MINUTES: number;
78
+ DURATION_10_MINUTES: number;
79
+ DURATION_30_MINUTES: number;
80
+ DURATION_1_HOUR: number;
81
+ DURATION_8_HOURS: number;
82
+ DURATION_DEFAULT: number;
83
+ MAX_TTL_2_MINUTES: number;
84
+ MAX_TTL_5_MINUTES: number;
85
+ MAX_TTL_1_DAY: number;
86
+ MAX_TTL_3_DAYS: number;
87
+ MAX_TTL_7_DAYS: number;
88
+ MAX_TTL_14_DAYS: number;
89
+ MAX_TTL_30_DAYS: number;
90
+ MAX_TTL_DEFAULT: number;
91
+ };
73
92
  };
74
93
  export default _default;
@@ -31,6 +31,7 @@ exports.PostTypes = {
31
31
  REMINDER: 'reminder',
32
32
  WRANGLER: 'system_wrangler',
33
33
  GM_CONVERTED_TO_CHANNEL: 'system_gm_to_channel',
34
+ BURN_ON_READ: 'burn_on_read',
34
35
  };
35
36
  exports.default = {
36
37
  POST_CHUNK_SIZE: 60,
@@ -68,4 +69,21 @@ exports.default = {
68
69
  exports.PostTypes.LEAVE_TEAM,
69
70
  exports.PostTypes.REMOVE_FROM_TEAM,
70
71
  ],
72
+ BURN_ON_READ: {
73
+ DURATION_1_MINUTE: 60,
74
+ DURATION_5_MINUTES: 300,
75
+ DURATION_10_MINUTES: 600,
76
+ DURATION_30_MINUTES: 1800,
77
+ DURATION_1_HOUR: 3600,
78
+ DURATION_8_HOURS: 28800,
79
+ DURATION_DEFAULT: 600,
80
+ MAX_TTL_2_MINUTES: 120,
81
+ MAX_TTL_5_MINUTES: 300,
82
+ MAX_TTL_1_DAY: 86400,
83
+ MAX_TTL_3_DAYS: 259200,
84
+ MAX_TTL_7_DAYS: 604800,
85
+ MAX_TTL_14_DAYS: 1209600,
86
+ MAX_TTL_30_DAYS: 2592000,
87
+ MAX_TTL_DEFAULT: 604800,
88
+ },
71
89
  };
@@ -62,6 +62,8 @@ declare const Preferences: {
62
62
  HIDE_MYSQL_STATS_NOTIFICATION: string;
63
63
  CATEGORY_OVERAGE_USERS_BANNER: string;
64
64
  CATEGORY_POST_HISTORY_LIMIT_BANNER: string;
65
+ CATEGORY_BURN_ON_READ: string;
66
+ BURN_ON_READ_SKIP_CONFIRMATION: string;
65
67
  CATEGORY_THEME: string;
66
68
  THEMES: Record<ThemeKey, Theme>;
67
69
  RECENT_EMOJIS: string;
@@ -66,6 +66,8 @@ const Preferences = {
66
66
  HIDE_MYSQL_STATS_NOTIFICATION: 'hide_mysql_stats_notifcation',
67
67
  CATEGORY_OVERAGE_USERS_BANNER: 'overage_users_banner',
68
68
  CATEGORY_POST_HISTORY_LIMIT_BANNER: 'post_history_limit_banner',
69
+ CATEGORY_BURN_ON_READ: 'burn_on_read',
70
+ BURN_ON_READ_SKIP_CONFIRMATION: 'skip_delete_confirmation',
69
71
  CATEGORY_THEME: 'theme',
70
72
  THEMES: {
71
73
  denim: {
@@ -49,5 +49,8 @@ declare const WebsocketEvents: {
49
49
  THREAD_READ_CHANGED: string;
50
50
  FIRST_ADMIN_VISIT_MARKETPLACE_STATUS_RECEIVED: string;
51
51
  GROUP_MEMBER_DELETED: string;
52
+ BURN_ON_READ_POST_REVEALED: string;
53
+ BURN_ON_READ_POST_BURNED: string;
54
+ BURN_ON_READ_ALL_REVEALED: string;
52
55
  };
53
56
  export default WebsocketEvents;
@@ -53,5 +53,8 @@ const WebsocketEvents = {
53
53
  THREAD_READ_CHANGED: 'thread_read_changed',
54
54
  FIRST_ADMIN_VISIT_MARKETPLACE_STATUS_RECEIVED: 'first_admin_visit_marketplace_status_received',
55
55
  GROUP_MEMBER_DELETED: 'group_member_deleted',
56
+ BURN_ON_READ_POST_REVEALED: 'post_revealed',
57
+ BURN_ON_READ_POST_BURNED: 'post_burned',
58
+ BURN_ON_READ_ALL_REVEALED: 'burn_on_read_all_revealed',
56
59
  };
57
60
  exports.default = WebsocketEvents;
@@ -0,0 +1,10 @@
1
+ import type { Agent } from '@mattermost/types/agents';
2
+ export interface AgentsState {
3
+ agents: Agent[];
4
+ }
5
+ declare const _default: import("redux").Reducer<{
6
+ agents: Agent[];
7
+ }, import("redux").AnyAction, Partial<{
8
+ agents: Agent[] | undefined;
9
+ }>>;
10
+ export default _default;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ const redux_1 = require("redux");
6
+ const action_types_1 = require("../../action_types");
7
+ function agents(state = [], action) {
8
+ switch (action.type) {
9
+ case action_types_1.AgentTypes.RECEIVED_AGENTS:
10
+ return action.data || [];
11
+ case action_types_1.AgentTypes.AGENTS_FAILURE:
12
+ return [];
13
+ default:
14
+ return state;
15
+ }
16
+ }
17
+ exports.default = (0, redux_1.combineReducers)({
18
+ agents,
19
+ });
@@ -8,6 +8,9 @@ declare const _default: import("redux").Reducer<{
8
8
  firstAdminCompleteSetup: any;
9
9
  cwsAvailability: import("./general").CWSAvailabilityState;
10
10
  };
11
+ agents: {
12
+ agents: import("@mattermost/types/agents").Agent[];
13
+ };
11
14
  users: {
12
15
  currentUserId: any;
13
16
  mySessions: any[];
@@ -337,6 +340,11 @@ declare const _default: import("redux").Reducer<{
337
340
  firstAdminCompleteSetup: boolean | undefined;
338
341
  cwsAvailability: import("./general").CWSAvailabilityState | undefined;
339
342
  }> | undefined;
343
+ agents: {
344
+ agents: import("@mattermost/types/agents").Agent[];
345
+ } | Partial<{
346
+ agents: import("@mattermost/types/agents").Agent[] | undefined;
347
+ }> | undefined;
340
348
  users: {
341
349
  currentUserId: any;
342
350
  mySessions: any[];
@@ -7,6 +7,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  const redux_1 = require("redux");
9
9
  const admin_1 = __importDefault(require("./admin"));
10
+ const agents_1 = __importDefault(require("./agents"));
10
11
  const apps_1 = __importDefault(require("./apps"));
11
12
  const bots_1 = __importDefault(require("./bots"));
12
13
  const channel_bookmarks_1 = __importDefault(require("./channel_bookmarks"));
@@ -36,6 +37,7 @@ const usage_1 = __importDefault(require("./usage"));
36
37
  const users_1 = __importDefault(require("./users"));
37
38
  exports.default = (0, redux_1.combineReducers)({
38
39
  general: general_1.default,
40
+ agents: agents_1.default,
39
41
  users: users_1.default,
40
42
  limits: limits_1.default,
41
43
  teams: teams_1.default,
@@ -20,6 +20,7 @@ exports.limitedViews = limitedViews;
20
20
  exports.default = reducer;
21
21
  const action_types_1 = require("mattermost-redux/action_types");
22
22
  const constants_1 = require("mattermost-redux/constants");
23
+ const posts_1 = require("mattermost-redux/constants/posts");
23
24
  const post_utils_1 = require("mattermost-redux/utils/post_utils");
24
25
  function removeUnneededMetadata(post) {
25
26
  if (!post.metadata) {
@@ -151,6 +152,11 @@ function handlePosts(state = {}, action) {
151
152
  if (!state[post.id]) {
152
153
  return state;
153
154
  }
155
+ if (state[post.id].type === posts_1.PostTypes.BURN_ON_READ) {
156
+ const nextState = { ...state };
157
+ Reflect.deleteProperty(nextState, post.id);
158
+ return nextState;
159
+ }
154
160
  // Mark the post as deleted
155
161
  const nextState = {
156
162
  ...state,
@@ -229,6 +235,68 @@ function handlePosts(state = {}, action) {
229
235
  },
230
236
  };
231
237
  }
238
+ case action_types_1.PostTypes.REVEAL_BURN_ON_READ_SUCCESS: {
239
+ const { post, expireAt } = action.data;
240
+ if (!state[post.id]) {
241
+ return state;
242
+ }
243
+ const currentPost = state[post.id];
244
+ const currentMetadata = currentPost.metadata || {};
245
+ const newMetadata = post.metadata || {};
246
+ return {
247
+ ...state,
248
+ [post.id]: {
249
+ ...currentPost,
250
+ ...post,
251
+ metadata: {
252
+ ...currentMetadata,
253
+ ...newMetadata,
254
+ expire_at: expireAt,
255
+ },
256
+ },
257
+ };
258
+ }
259
+ case action_types_1.PostTypes.POST_RECIPIENTS_UPDATED: {
260
+ const { postId, recipients } = action.data;
261
+ if (!state[postId]) {
262
+ return state;
263
+ }
264
+ const currentPost = state[postId];
265
+ const currentMetadata = currentPost.metadata || {};
266
+ const currentRecipients = currentMetadata.recipients || [];
267
+ // Merge new recipients with existing ones (don't replace).
268
+ // Server sends incremental updates (only the revealing user), so we must merge.
269
+ const mergedRecipients = [...new Set([...currentRecipients, ...recipients])];
270
+ return {
271
+ ...state,
272
+ [postId]: {
273
+ ...currentPost,
274
+ metadata: {
275
+ ...currentMetadata,
276
+ recipients: mergedRecipients,
277
+ },
278
+ },
279
+ };
280
+ }
281
+ case action_types_1.PostTypes.BURN_ON_READ_ALL_REVEALED: {
282
+ const { postId, senderExpireAt } = action.data;
283
+ if (!state[postId]) {
284
+ return state;
285
+ }
286
+ const currentPost = state[postId];
287
+ const currentMetadata = currentPost.metadata || {};
288
+ // Set sender's expiration time to trigger timer display
289
+ return {
290
+ ...state,
291
+ [postId]: {
292
+ ...currentPost,
293
+ metadata: {
294
+ ...currentMetadata,
295
+ expire_at: senderExpireAt,
296
+ },
297
+ },
298
+ };
299
+ }
232
300
  case action_types_1.ChannelTypes.LEAVE_CHANNEL: {
233
301
  const channelId = action.data.id;
234
302
  let postDeleted = false;
@@ -605,17 +673,24 @@ function postsInChannel(state = {}, action, prevPosts, nextPosts) {
605
673
  }
606
674
  case action_types_1.PostTypes.POST_DELETED: {
607
675
  const post = action.data;
608
- // Deleting a post removes its comments from the order, but does not remove the post itself
609
676
  const postsForChannel = state[post.channel_id] || [];
610
677
  if (postsForChannel.length === 0) {
611
678
  return state;
612
679
  }
613
680
  let changed = false;
614
681
  let nextPostsForChannel = [...postsForChannel];
682
+ const isBoRPost = prevPosts[post.id]?.type === posts_1.PostTypes.BURN_ON_READ;
683
+ const shouldRemovePost = (postId) => {
684
+ const isTheDeletedPost = postId === post.id;
685
+ const isReplyToDeletedPost = prevPosts[postId]?.root_id === post.id;
686
+ if (isBoRPost) {
687
+ return isTheDeletedPost;
688
+ }
689
+ return isReplyToDeletedPost;
690
+ };
615
691
  for (let i = 0; i < nextPostsForChannel.length; i++) {
616
692
  const block = nextPostsForChannel[i];
617
- // Remove any comments for this post
618
- const nextOrder = block.order.filter((postId) => prevPosts[postId].root_id !== post.id);
693
+ const nextOrder = block.order.filter((postId) => !shouldRemovePost(postId));
619
694
  if (nextOrder.length !== block.order.length) {
620
695
  nextPostsForChannel[i] = {
621
696
  ...block,
@@ -642,11 +717,16 @@ function postsInChannel(state = {}, action, prevPosts, nextPosts) {
642
717
  return state;
643
718
  }
644
719
  let changed = false;
720
+ const isBoRPost = prevPosts[post.id]?.type === posts_1.PostTypes.BURN_ON_READ;
645
721
  // Remove the post and its comments from the channel
646
722
  let nextPostsForChannel = [...postsForChannel];
647
723
  for (let i = 0; i < nextPostsForChannel.length; i++) {
648
724
  const block = nextPostsForChannel[i];
649
- const nextOrder = block.order.filter((postId) => postId !== post.id && prevPosts[postId].root_id !== post.id);
725
+ // For BoR posts: only remove the post itself (BoR doesn't support threads)
726
+ // For regular posts: remove the post and its thread replies
727
+ const nextOrder = isBoRPost ?
728
+ block.order.filter((postId) => postId !== post.id) :
729
+ block.order.filter((postId) => postId !== post.id && prevPosts[postId]?.root_id !== post.id);
650
730
  if (nextOrder.length !== block.order.length) {
651
731
  nextPostsForChannel[i] = {
652
732
  ...block,
@@ -10,6 +10,9 @@ declare const _default: {
10
10
  firstAdminCompleteSetup: any;
11
11
  cwsAvailability: import("./entities/general").CWSAvailabilityState;
12
12
  };
13
+ agents: {
14
+ agents: import("@mattermost/types/agents").Agent[];
15
+ };
13
16
  users: {
14
17
  currentUserId: any;
15
18
  mySessions: any[];
@@ -339,6 +342,11 @@ declare const _default: {
339
342
  firstAdminCompleteSetup: boolean | undefined;
340
343
  cwsAvailability: import("./entities/general").CWSAvailabilityState | undefined;
341
344
  }> | undefined;
345
+ agents: {
346
+ agents: import("@mattermost/types/agents").Agent[];
347
+ } | Partial<{
348
+ agents: import("@mattermost/types/agents").Agent[] | undefined;
349
+ }> | undefined;
342
350
  users: {
343
351
  currentUserId: any;
344
352
  mySessions: any[];
@@ -1,7 +1,7 @@
1
1
  import type { Channel, ChannelWithTeamData, ChannelSearchOpts } from '@mattermost/types/channels';
2
2
  import type { AccessControlSettings } from '@mattermost/types/config';
3
3
  import type { GlobalState } from '@mattermost/types/store';
4
- export declare function getAccessControlSettings(state: GlobalState): AccessControlSettings;
4
+ export declare const getAccessControlSettings: import("../create_selector").OutputSelector<GlobalState, AccessControlSettings, (res1: AccessControlSettings, res2: any) => AccessControlSettings>;
5
5
  export declare function isChannelScopeAccessControlEnabled(state: GlobalState): boolean;
6
6
  export declare function getAccessControlPolicy(state: GlobalState, id: string): import("@mattermost/types/access_control").AccessControlPolicy;
7
7
  export declare const getChannelIdsForAccessControlPolicy: (state: GlobalState, parentId: string) => string[];
@@ -2,8 +2,7 @@
2
2
  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
3
  // See LICENSE.txt for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.getChannelIdsForAccessControlPolicy = void 0;
6
- exports.getAccessControlSettings = getAccessControlSettings;
5
+ exports.getChannelIdsForAccessControlPolicy = exports.getAccessControlSettings = void 0;
7
6
  exports.isChannelScopeAccessControlEnabled = isChannelScopeAccessControlEnabled;
8
7
  exports.getAccessControlPolicy = getAccessControlPolicy;
9
8
  exports.makeGetChannelsInAccessControlPolicy = makeGetChannelsInAccessControlPolicy;
@@ -12,22 +11,20 @@ const general_1 = require("mattermost-redux/selectors/entities/general");
12
11
  const channel_utils_1 = require("mattermost-redux/utils/channel_utils");
13
12
  const channels_1 = require("./channels");
14
13
  const create_selector_1 = require("../create_selector");
15
- function getAccessControlSettings(state) {
14
+ exports.getAccessControlSettings = (0, create_selector_1.createSelector)('getAccessControlSettings', (state) => state.entities.admin.config.AccessControlSettings, (state) => (0, general_1.getConfig)(state), (adminConfig, config) => {
16
15
  // First try to get from admin config (for admin console pages)
17
- const adminConfig = state.entities.admin.config.AccessControlSettings;
18
16
  if (adminConfig) {
19
17
  return adminConfig;
20
18
  }
21
19
  // Otherwise, build from client config (for regular users/channel admins)
22
- const config = (0, general_1.getConfig)(state);
23
20
  return {
24
21
  EnableAttributeBasedAccessControl: config?.EnableAttributeBasedAccessControl === 'true',
25
22
  EnableChannelScopeAccessControl: config?.EnableChannelScopeAccessControl === 'true',
26
23
  EnableUserManagedAttributes: config?.EnableUserManagedAttributes === 'true',
27
24
  };
28
- }
25
+ });
29
26
  function isChannelScopeAccessControlEnabled(state) {
30
- const settings = getAccessControlSettings(state);
27
+ const settings = (0, exports.getAccessControlSettings)(state);
31
28
  return settings?.EnableChannelScopeAccessControl || false;
32
29
  }
33
30
  function getAccessControlPolicy(state, id) {
@@ -0,0 +1,4 @@
1
+ import type { Agent } from '@mattermost/types/agents';
2
+ import type { GlobalState } from '@mattermost/types/store';
3
+ export declare function getAgents(state: GlobalState): Agent[];
4
+ export declare function getAgent(state: GlobalState, agentId: string): Agent | undefined;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.getAgents = getAgents;
6
+ exports.getAgent = getAgent;
7
+ function getAgents(state) {
8
+ return state.entities.agents?.agents;
9
+ }
10
+ function getAgent(state, agentId) {
11
+ const agents = getAgents(state);
12
+ return agents.find((agent) => agent.id === agentId);
13
+ }
@@ -1,3 +1,2 @@
1
1
  import type { GlobalState } from '@mattermost/types/store';
2
- export declare const selectChannelBannerEnabled: (state: GlobalState) => boolean;
3
2
  export declare const selectShowChannelBanner: (state: GlobalState, channelId: string) => boolean;
@@ -2,21 +2,11 @@
2
2
  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
3
  // See LICENSE.txt for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.selectShowChannelBanner = exports.selectChannelBannerEnabled = void 0;
5
+ exports.selectShowChannelBanner = void 0;
6
6
  const channels_1 = require("@mattermost/types/channels");
7
7
  const constants_1 = require("mattermost-redux/constants");
8
8
  const channels_2 = require("mattermost-redux/selectors/entities/channels");
9
- const general_1 = require("mattermost-redux/selectors/entities/general");
10
- const selectChannelBannerEnabled = (state) => {
11
- const license = (0, general_1.getLicense)(state);
12
- return license?.SkuShortName === constants_1.General.SKUEnterpriseAdvanced;
13
- };
14
- exports.selectChannelBannerEnabled = selectChannelBannerEnabled;
15
9
  const selectShowChannelBanner = (state, channelId) => {
16
- const enabled = (0, exports.selectChannelBannerEnabled)(state);
17
- if (!enabled) {
18
- return false;
19
- }
20
10
  const channelBannerInfo = (0, channels_2.getChannelBanner)(state, channelId);
21
11
  const channel = (0, channels_2.getChannel)(state, channelId);
22
12
  const isValidChannelType = Boolean(channel && (channel.type === constants_1.General.OPEN_CHANNEL || channel.type === constants_1.General.PRIVATE_CHANNEL));
@@ -132,7 +132,8 @@ function isPostInteractable(post) {
132
132
  !(0, post_utils_1.isPostEphemeral)(post) &&
133
133
  !(0, post_utils_1.isSystemMessage)(post) &&
134
134
  !(0, post_utils_1.isPostPendingOrFailed)(post) &&
135
- post.state !== constants_1.Posts.POST_DELETED;
135
+ post.state !== constants_1.Posts.POST_DELETED &&
136
+ post.type !== constants_1.Posts.POST_TYPES.BURN_ON_READ;
136
137
  }
137
138
  function getLatestInteractablePostId(state, channelId, rootId = '') {
138
139
  const postsIds = rootId ? getPostsInThreadOrdered(state, rootId) : getPostIdsInChannel(state, channelId);
@@ -398,7 +399,13 @@ function getUnreadPostsChunk(state, channelId, timeStamp) {
398
399
  return oldestPostsChunk;
399
400
  }
400
401
  }
401
- return getPostsChunkInChannelAroundTime(state, channelId, timeStamp);
402
+ // Try to find a chunk where lastViewedAt falls within the post range
403
+ const chunkAroundTime = getPostsChunkInChannelAroundTime(state, channelId, timeStamp);
404
+ if (chunkAroundTime) {
405
+ return chunkAroundTime;
406
+ }
407
+ // All fetched posts are newer than lastViewedAt. Return the recent chunk.
408
+ return recentChunk;
402
409
  }
403
410
  const isPostsChunkIncludingUnreadsPosts = (state, chunk, timeStamp) => {
404
411
  const postsEntity = state.entities.posts;
@@ -5,6 +5,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
5
5
  const posts_1 = require("../reducers/entities/posts");
6
6
  const state = {
7
7
  entities: {
8
+ agents: {
9
+ agents: [],
10
+ },
8
11
  general: {
9
12
  config: {},
10
13
  license: {},
@@ -2,7 +2,7 @@ import type { FileInfo } from '@mattermost/types/files';
2
2
  export declare function getFormattedFileSize(bytes: number): string;
3
3
  export declare function getFileType(file: FileInfo): string;
4
4
  export declare function getFileUrl(fileId: string): string;
5
- export declare function getFileDownloadUrl(fileId: string): string;
5
+ export declare function getFileDownloadUrl(fileId: string, asContentReviewer?: boolean, flaggedPostId?: string): string;
6
6
  export declare function getFileThumbnailUrl(fileId: string): string;
7
7
  export declare function getFilePreviewUrl(fileId: string): string;
8
8
  export declare function getFileMiniPreviewUrl(fileInfo?: FileInfo): string | undefined;
@@ -10,6 +10,7 @@ exports.getFileThumbnailUrl = getFileThumbnailUrl;
10
10
  exports.getFilePreviewUrl = getFilePreviewUrl;
11
11
  exports.getFileMiniPreviewUrl = getFileMiniPreviewUrl;
12
12
  exports.sortFileInfos = sortFileInfos;
13
+ const helpers_1 = require("@mattermost/client/lib/helpers");
13
14
  const client_1 = require("mattermost-redux/client");
14
15
  const constants_1 = require("../constants");
15
16
  function getFormattedFileSize(bytes) {
@@ -54,8 +55,17 @@ function getFileType(file) {
54
55
  function getFileUrl(fileId) {
55
56
  return client_1.Client4.getFileRoute(fileId);
56
57
  }
57
- function getFileDownloadUrl(fileId) {
58
- return `${client_1.Client4.getFileRoute(fileId)}?download=1`;
58
+ function getFileDownloadUrl(fileId, asContentReviewer, flaggedPostId) {
59
+ const queryParamsArgs = {};
60
+ queryParamsArgs.download = 1;
61
+ if (asContentReviewer) {
62
+ queryParamsArgs.as_content_reviewer = true;
63
+ }
64
+ if (flaggedPostId) {
65
+ queryParamsArgs.flagged_post_id = flaggedPostId;
66
+ }
67
+ const queryParams = (0, helpers_1.buildQueryString)(queryParamsArgs);
68
+ return `${client_1.Client4.getFileRoute(fileId)}${queryParams}`;
59
69
  }
60
70
  function getFileThumbnailUrl(fileId) {
61
71
  return `${client_1.Client4.getFileRoute(fileId)}/thumbnail`;
@@ -73,6 +73,16 @@ function makeFilterPostsAndAddSeparators() {
73
73
  if ((0, post_utils_1.shouldFilterJoinLeavePost)(post, showJoinLeave, currentUser.username)) {
74
74
  continue;
75
75
  }
76
+ // Filter out expired burn-on-read posts
77
+ // Note: BoR posts should display regardless of feature flag being enabled/disabled
78
+ // The feature flag only controls creation of NEW BoR messages, not display of existing ones
79
+ if (post.type === constants_1.Posts.POST_TYPES.BURN_ON_READ) {
80
+ // Skip if already expired and deleted
81
+ const expireAt = post.metadata?.expire_at;
82
+ if (expireAt && typeof expireAt === 'number' && expireAt <= Date.now()) {
83
+ continue;
84
+ }
85
+ }
76
86
  lastDate = pushPostDateIfNeeded(post, currentUser, out, lastDate);
77
87
  if (lastViewedAt &&
78
88
  post.create_at > lastViewedAt &&
@@ -62,6 +62,9 @@ function canEditPost(state, config, license, teamId, channelId, userId, post) {
62
62
  if (!post || isSystemMessage(post)) {
63
63
  return false;
64
64
  }
65
+ if (post.type === constants_1.Posts.POST_TYPES.BURN_ON_READ) {
66
+ return false;
67
+ }
65
68
  const isOwner = isPostOwner(userId, post);
66
69
  let canEdit = true;
67
70
  const permission = isOwner ? constants_1.Permissions.EDIT_POST : constants_1.Permissions.EDIT_OTHERS_POSTS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mattermost-redux",
3
- "version": "11.1.0",
3
+ "version": "11.3.0",
4
4
  "description": "Common code (API client, Redux stores, logic, utility functions) for building a Mattermost client",
5
5
  "keywords": [
6
6
  "mattermost"
@@ -39,8 +39,8 @@
39
39
  "directory": "webapp/platform/mattermost-redux"
40
40
  },
41
41
  "dependencies": {
42
- "@mattermost/client": "11.1.0",
43
- "@mattermost/types": "11.1.0",
42
+ "@mattermost/client": "11.3.0",
43
+ "@mattermost/types": "11.3.0",
44
44
  "@redux-devtools/extension": "3.3.0",
45
45
  "lodash": "^4.17.21",
46
46
  "moment-timezone": "^0.5.38",