[GH24626] Remove ExperimentalTimezone as this is always true (#24657)
* Remove all occurrences of ExperimentalTimezone in /server
This removes all uses of ExperimentalTimezone and makes all conditions using this setting being either removed (== false) or always used (== true)
* Remove timezone parameter for getChannelMemberByGroup
As timezone is always enabled this function no longer has a second parameter. The endpoint will always be called with includeTimezones set to true
* Remove all uses of ExperimentalTimezone in webapp
All conditions dependent of this are adjusted to always be true if experimentalTimezone should be true and vice versa
* Change all tests checking for correct usage of ExperimentalTimezone
As this parameter is no longer used, the tests which check for correct behaviour of this is no longer needed
* Fix type errors
Tests regarding types does now pass
'npm run check-types' will run successfully
* fix lint issues
Fix all current lint errors and now lint test goes through
* Fix test regarding profile popover
enableTimezone now is gone and all profile_popover.test.tsx can run successfully.
Added state.entities.users.profiles[] as it before threw an error without it.
* Fix tests where "April 1 2019" was changed to "April 01 2019"
Now it will show "April 1 2019" and "timeZone" will only show if its other than empty ("").
* Fix test where date was set to NaN
Now date will show correctly and will not be NaN
* fix minor test case that failed before
* fix linting in server
* Delete tests that are not valid with timeZoneEnabled removed
tests in advanced_create_comment and advanced_create_post had timeZoneEnabled
set to false as default. The tests that use this are now changed to once which are meant to have timeZoneEnabled set to true.
Adjust jest function in advanced_create_post to get correct stacktrace
* Parameter deleted
isTimeZoneEnabled is always true and therefore the parameter can be deleted
* adjust to prettier standard
* Remove all occurrences of ExperimentalTimezone in /server
This removes all uses of ExperimentalTimezone and makes all conditions using this setting being either removed (== false) or always used (== true)
* Remove timezone parameter for getChannelMemberByGroup
As timezone is always enabled this function no longer has a second parameter. The endpoint will always be called with includeTimezones set to true
* Remove all uses of ExperimentalTimezone in webapp
All conditions dependent of this are adjusted to always be true if experimentalTimezone should be true and vice versa
* Change all tests checking for correct usage of ExperimentalTimezone
As this parameter is no longer used, the tests which check for correct behaviour of this is no longer needed
* Fix type errors
Tests regarding types does now pass
'npm run check-types' will run successfully
* fix lint issues
Fix all current lint errors and now lint test goes through
* Fix test regarding profile popover
enableTimezone now is gone and all profile_popover.test.tsx can run successfully.
Added state.entities.users.profiles[] as it before threw an error without it.
* Fix tests where "April 1 2019" was changed to "April 01 2019"
Now it will show "April 1 2019" and "timeZone" will only show if its other than empty ("").
* Fix test where date was set to NaN
Now date will show correctly and will not be NaN
* fix minor test case that failed before
* fix linting in server
* Delete tests that are not valid with timeZoneEnabled removed
tests in advanced_create_comment and advanced_create_post had timeZoneEnabled
set to false as default. The tests that use this are now changed to once which are meant to have timeZoneEnabled set to true.
Adjust jest function in advanced_create_post to get correct stacktrace
* Parameter deleted
isTimeZoneEnabled is always true and therefore the parameter can be deleted
* adjust to prettier standard
---------
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -72,9 +72,6 @@ describe('Verify Accessibility Support in different sections in Settings and Pro
|
|||||||
ServiceSettings: {
|
ServiceSettings: {
|
||||||
EnableMultifactorAuthentication: true,
|
EnableMultifactorAuthentication: true,
|
||||||
},
|
},
|
||||||
DisplaySettings: {
|
|
||||||
ExperimentalTimezone: true,
|
|
||||||
},
|
|
||||||
SamlSettings: {
|
SamlSettings: {
|
||||||
Enable: false,
|
Enable: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,13 +16,6 @@ describe('Messaging', () => {
|
|||||||
const sysadmin = getAdminAccount();
|
const sysadmin = getAdminAccount();
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// # Enable Timezone
|
|
||||||
cy.apiUpdateConfig({
|
|
||||||
DisplaySettings: {
|
|
||||||
ExperimentalTimezone: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// # Create and visit new channel
|
// # Create and visit new channel
|
||||||
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
|
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
|
||||||
cy.visit(`/${team.name}/channels/${channel.name}`);
|
cy.visit(`/${team.name}/channels/${channel.name}`);
|
||||||
|
|||||||
@@ -23,13 +23,6 @@ describe('Settings > Display > Clock Display Mode', () => {
|
|||||||
let testChannel;
|
let testChannel;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// # Enable Timezone
|
|
||||||
cy.apiUpdateConfig({
|
|
||||||
DisplaySettings: {
|
|
||||||
ExperimentalTimezone: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// # Login as new user, visit off-topic and post a message
|
// # Login as new user, visit off-topic and post a message
|
||||||
cy.apiInitSetup({loginAfter: true}).then(({team, channel, offTopicUrl}) => {
|
cy.apiInitSetup({loginAfter: true}).then(({team, channel, offTopicUrl}) => {
|
||||||
testTeam = team;
|
testTeam = team;
|
||||||
|
|||||||
@@ -40,13 +40,6 @@ describe('Profile > Display > Timezone', () => {
|
|||||||
let userId;
|
let userId;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// # Enable Timezone
|
|
||||||
cy.apiUpdateConfig({
|
|
||||||
DisplaySettings: {
|
|
||||||
ExperimentalTimezone: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// # Create and visit off-topic
|
// # Create and visit off-topic
|
||||||
cy.apiInitSetup({loginAfter: true}).then(({user, offTopicUrl}) => {
|
cy.apiInitSetup({loginAfter: true}).then(({user, offTopicUrl}) => {
|
||||||
userId = user.id;
|
userId = user.id;
|
||||||
|
|||||||
@@ -417,9 +417,7 @@
|
|||||||
"ChimeraOAuthProxyURL": ""
|
"ChimeraOAuthProxyURL": ""
|
||||||
},
|
},
|
||||||
"DisplaySettings": {
|
"DisplaySettings": {
|
||||||
"CustomURLSchemes": [],
|
"CustomURLSchemes": []
|
||||||
"MaxMarkdownNodes": 0,
|
|
||||||
"ExperimentalTimezone": false
|
|
||||||
},
|
},
|
||||||
"GuestAccountsSettings": {
|
"GuestAccountsSettings": {
|
||||||
"Enable": true,
|
"Enable": true,
|
||||||
|
|||||||
@@ -591,9 +591,7 @@
|
|||||||
"ChimeraOAuthProxyURL": ""
|
"ChimeraOAuthProxyURL": ""
|
||||||
},
|
},
|
||||||
"DisplaySettings": {
|
"DisplaySettings": {
|
||||||
"CustomURLSchemes": [],
|
"CustomURLSchemes": []
|
||||||
"MaxMarkdownNodes": 0,
|
|
||||||
"ExperimentalTimezone": false
|
|
||||||
},
|
},
|
||||||
"GuestAccountsSettings": {
|
"GuestAccountsSettings": {
|
||||||
"Enable": true,
|
"Enable": true,
|
||||||
|
|||||||
@@ -667,7 +667,6 @@ const defaultServerConfig: AdminConfig = {
|
|||||||
DisplaySettings: {
|
DisplaySettings: {
|
||||||
CustomURLSchemes: [],
|
CustomURLSchemes: [],
|
||||||
MaxMarkdownNodes: 0,
|
MaxMarkdownNodes: 0,
|
||||||
ExperimentalTimezone: true,
|
|
||||||
},
|
},
|
||||||
GuestAccountsSettings: {
|
GuestAccountsSettings: {
|
||||||
Enable: false,
|
Enable: false,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li
|
|||||||
props["DisableAppBar"] = strconv.FormatBool(*c.ExperimentalSettings.DisableAppBar)
|
props["DisableAppBar"] = strconv.FormatBool(*c.ExperimentalSettings.DisableAppBar)
|
||||||
|
|
||||||
props["ExperimentalEnableAutomaticReplies"] = strconv.FormatBool(*c.TeamSettings.ExperimentalEnableAutomaticReplies)
|
props["ExperimentalEnableAutomaticReplies"] = strconv.FormatBool(*c.TeamSettings.ExperimentalEnableAutomaticReplies)
|
||||||
props["ExperimentalTimezone"] = strconv.FormatBool(*c.DisplaySettings.ExperimentalTimezone)
|
props["ExperimentalTimezone"] = "true"
|
||||||
|
|
||||||
props["SendEmailNotifications"] = strconv.FormatBool(*c.EmailSettings.SendEmailNotifications)
|
props["SendEmailNotifications"] = strconv.FormatBool(*c.EmailSettings.SendEmailNotifications)
|
||||||
props["SendPushNotifications"] = strconv.FormatBool(*c.EmailSettings.SendPushNotifications)
|
props["SendPushNotifications"] = strconv.FormatBool(*c.EmailSettings.SendPushNotifications)
|
||||||
|
|||||||
@@ -80,9 +80,6 @@ func init() {
|
|||||||
ServiceSettings: model.ServiceSettings{
|
ServiceSettings: model.ServiceSettings{
|
||||||
SiteURL: model.NewString("http://custom.com"),
|
SiteURL: model.NewString("http://custom.com"),
|
||||||
},
|
},
|
||||||
DisplaySettings: model.DisplaySettings{
|
|
||||||
ExperimentalTimezone: model.NewBool(false),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,6 @@ func TestDatabaseStoreNew(t *testing.T) {
|
|||||||
defer ds.Close()
|
defer ds.Close()
|
||||||
|
|
||||||
assert.Equal(t, *customConfigDefaults.ServiceSettings.SiteURL, *ds.Get().ServiceSettings.SiteURL)
|
assert.Equal(t, *customConfigDefaults.ServiceSettings.SiteURL, *ds.Get().ServiceSettings.SiteURL)
|
||||||
assert.Equal(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *ds.Get().DisplaySettings.ExperimentalTimezone)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("existing config, initialization required", func(t *testing.T) {
|
t.Run("existing config, initialization required", func(t *testing.T) {
|
||||||
@@ -181,7 +180,6 @@ func TestDatabaseStoreNew(t *testing.T) {
|
|||||||
assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL)
|
assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL)
|
||||||
// not existing value should be overwritten by the custom
|
// not existing value should be overwritten by the custom
|
||||||
// default value
|
// default value
|
||||||
assert.Equal(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *ds.Get().DisplaySettings.ExperimentalTimezone)
|
|
||||||
assertDatabaseNotEqualsConfig(t, testConfig)
|
assertDatabaseNotEqualsConfig(t, testConfig)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -208,7 +206,6 @@ func TestDatabaseStoreNew(t *testing.T) {
|
|||||||
// as the whole config has default values already, custom
|
// as the whole config has default values already, custom
|
||||||
// defaults should have no effect
|
// defaults should have no effect
|
||||||
assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL)
|
assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL)
|
||||||
assert.NotEqual(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *ds.Get().DisplaySettings.ExperimentalTimezone)
|
|
||||||
assertDatabaseEqualsConfig(t, minimalConfigNoFF)
|
assertDatabaseEqualsConfig(t, minimalConfigNoFF)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ func TestFileStoreNew(t *testing.T) {
|
|||||||
assert.Equal(t, "http://TestStoreNew", *configStore.Get().ServiceSettings.SiteURL)
|
assert.Equal(t, "http://TestStoreNew", *configStore.Get().ServiceSettings.SiteURL)
|
||||||
// nonexisting value should be overwritten by the custom
|
// nonexisting value should be overwritten by the custom
|
||||||
// defaults
|
// defaults
|
||||||
assert.Equal(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *configStore.Get().DisplaySettings.ExperimentalTimezone)
|
|
||||||
assertFileNotEqualsConfig(t, testConfig, path)
|
assertFileNotEqualsConfig(t, testConfig, path)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -156,7 +155,6 @@ func TestFileStoreNew(t *testing.T) {
|
|||||||
// as the whole config has default values already, custom
|
// as the whole config has default values already, custom
|
||||||
// defaults should have no effect
|
// defaults should have no effect
|
||||||
assert.Equal(t, "http://minimal", *configStore.Get().ServiceSettings.SiteURL)
|
assert.Equal(t, "http://minimal", *configStore.Get().ServiceSettings.SiteURL)
|
||||||
assert.NotEqual(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *configStore.Get().DisplaySettings.ExperimentalTimezone)
|
|
||||||
assertFileEqualsConfig(t, minimalConfigNoFF, path)
|
assertFileEqualsConfig(t, minimalConfigNoFF, path)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -195,7 +193,6 @@ func TestFileStoreNew(t *testing.T) {
|
|||||||
defer configStore.Close()
|
defer configStore.Close()
|
||||||
|
|
||||||
assert.Equal(t, *customConfigDefaults.ServiceSettings.SiteURL, *configStore.Get().ServiceSettings.SiteURL)
|
assert.Equal(t, *customConfigDefaults.ServiceSettings.SiteURL, *configStore.Get().ServiceSettings.SiteURL)
|
||||||
assert.Equal(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *configStore.Get().DisplaySettings.ExperimentalTimezone)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("absolute path, path to file does not exist", func(t *testing.T) {
|
t.Run("absolute path, path to file does not exist", func(t *testing.T) {
|
||||||
|
|||||||
@@ -849,7 +849,6 @@ func (ts *TelemetryService) trackConfig() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
ts.SendTelemetry(TrackConfigDisplay, map[string]any{
|
ts.SendTelemetry(TrackConfigDisplay, map[string]any{
|
||||||
"experimental_timezone": *cfg.DisplaySettings.ExperimentalTimezone,
|
|
||||||
"isdefault_custom_url_schemes": len(cfg.DisplaySettings.CustomURLSchemes) != 0,
|
"isdefault_custom_url_schemes": len(cfg.DisplaySettings.CustomURLSchemes) != 0,
|
||||||
"isdefault_max_markdown_nodes": isDefault(*cfg.DisplaySettings.MaxMarkdownNodes, 0),
|
"isdefault_max_markdown_nodes": isDefault(*cfg.DisplaySettings.MaxMarkdownNodes, 0),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3160,9 +3160,8 @@ func (s *MessageExportSettings) SetDefaults() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DisplaySettings struct {
|
type DisplaySettings struct {
|
||||||
CustomURLSchemes []string `access:"site_posts"`
|
CustomURLSchemes []string `access:"site_posts"`
|
||||||
MaxMarkdownNodes *int `access:"site_posts"`
|
MaxMarkdownNodes *int `access:"site_posts"`
|
||||||
ExperimentalTimezone *bool `access:"experimental_features"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DisplaySettings) SetDefaults() {
|
func (s *DisplaySettings) SetDefaults() {
|
||||||
@@ -3174,10 +3173,6 @@ func (s *DisplaySettings) SetDefaults() {
|
|||||||
if s.MaxMarkdownNodes == nil {
|
if s.MaxMarkdownNodes == nil {
|
||||||
s.MaxMarkdownNodes = NewInt(0)
|
s.MaxMarkdownNodes = NewInt(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.ExperimentalTimezone == nil {
|
|
||||||
s.ExperimentalTimezone = NewBool(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GuestAccountsSettings struct {
|
type GuestAccountsSettings struct {
|
||||||
|
|||||||
@@ -386,7 +386,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DisplaySettings": {
|
"DisplaySettings": {
|
||||||
"CustomUrlSchemes": [],
|
"CustomUrlSchemes": []
|
||||||
"ExperimentalTimezone": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import {searchGroups} from 'mattermost-redux/actions/groups';
|
import {searchGroups} from 'mattermost-redux/actions/groups';
|
||||||
import Permissions from 'mattermost-redux/constants/permissions';
|
import Permissions from 'mattermost-redux/constants/permissions';
|
||||||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
|
||||||
import {searchAssociatedGroupsForReferenceLocal} from 'mattermost-redux/selectors/entities/groups';
|
import {searchAssociatedGroupsForReferenceLocal} from 'mattermost-redux/selectors/entities/groups';
|
||||||
import {isCustomGroupsEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
import {isCustomGroupsEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {haveIChannelPermission} from 'mattermost-redux/selectors/entities/roles';
|
import {haveIChannelPermission} from 'mattermost-redux/selectors/entities/roles';
|
||||||
@@ -18,10 +17,6 @@ export function searchAssociatedGroupsForReference(prefix, teamId, channelId, op
|
|||||||
)) {
|
)) {
|
||||||
return {data: []};
|
return {data: []};
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = getConfig(state);
|
|
||||||
const isTimezoneEnabled = config.ExperimentalTimezone === 'true';
|
|
||||||
|
|
||||||
if (isCustomGroupsEnabled(state)) {
|
if (isCustomGroupsEnabled(state)) {
|
||||||
const params = {
|
const params = {
|
||||||
q: prefix,
|
q: prefix,
|
||||||
@@ -30,7 +25,6 @@ export function searchAssociatedGroupsForReference(prefix, teamId, channelId, op
|
|||||||
per_page: 60,
|
per_page: 60,
|
||||||
include_member_count: true,
|
include_member_count: true,
|
||||||
include_channel_member_count: channelId,
|
include_channel_member_count: channelId,
|
||||||
include_timezones: isTimezoneEnabled,
|
|
||||||
...opts,
|
...opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -989,7 +989,6 @@ function handleUserAddedEvent(msg) {
|
|||||||
const state = doGetState();
|
const state = doGetState();
|
||||||
const config = getConfig(state);
|
const config = getConfig(state);
|
||||||
const license = getLicense(state);
|
const license = getLicense(state);
|
||||||
const isTimezoneEnabled = config.ExperimentalTimezone === 'true';
|
|
||||||
const currentChannelId = getCurrentChannelId(state);
|
const currentChannelId = getCurrentChannelId(state);
|
||||||
if (currentChannelId === msg.broadcast.channel_id) {
|
if (currentChannelId === msg.broadcast.channel_id) {
|
||||||
doDispatch(getChannelStats(currentChannelId));
|
doDispatch(getChannelStats(currentChannelId));
|
||||||
@@ -998,7 +997,7 @@ function handleUserAddedEvent(msg) {
|
|||||||
data: {id: msg.broadcast.channel_id, user_id: msg.data.user_id},
|
data: {id: msg.broadcast.channel_id, user_id: msg.data.user_id},
|
||||||
});
|
});
|
||||||
if (license?.IsLicensed === 'true' && license?.LDAPGroups === 'true' && config.EnableConfirmNotificationsToChannel === 'true') {
|
if (license?.IsLicensed === 'true' && license?.LDAPGroups === 'true' && config.EnableConfirmNotificationsToChannel === 'true') {
|
||||||
doDispatch(getChannelMemberCountsByGroup(currentChannelId, isTimezoneEnabled));
|
doDispatch(getChannelMemberCountsByGroup(currentChannelId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1032,7 +1031,6 @@ export function handleUserRemovedEvent(msg) {
|
|||||||
const currentUser = getCurrentUser(state);
|
const currentUser = getCurrentUser(state);
|
||||||
const config = getConfig(state);
|
const config = getConfig(state);
|
||||||
const license = getLicense(state);
|
const license = getLicense(state);
|
||||||
const isTimezoneEnabled = config.ExperimentalTimezone === 'true';
|
|
||||||
|
|
||||||
if (msg.broadcast.user_id === currentUser.id) {
|
if (msg.broadcast.user_id === currentUser.id) {
|
||||||
dispatch(loadChannelsForCurrentUser());
|
dispatch(loadChannelsForCurrentUser());
|
||||||
@@ -1085,7 +1083,7 @@ export function handleUserRemovedEvent(msg) {
|
|||||||
data: {id: msg.broadcast.channel_id, user_id: msg.data.user_id},
|
data: {id: msg.broadcast.channel_id, user_id: msg.data.user_id},
|
||||||
});
|
});
|
||||||
if (license?.IsLicensed === 'true' && license?.LDAPGroups === 'true' && config.EnableConfirmNotificationsToChannel === 'true') {
|
if (license?.IsLicensed === 'true' && license?.LDAPGroups === 'true' && config.EnableConfirmNotificationsToChannel === 'true') {
|
||||||
dispatch(getChannelMemberCountsByGroup(currentChannel.id, isTimezoneEnabled));
|
dispatch(getChannelMemberCountsByGroup(currentChannel.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6949,16 +6949,6 @@ const AdminDefinition = {
|
|||||||
isHidden: it.not(it.licensedForFeature('SAML')),
|
isHidden: it.not(it.licensedForFeature('SAML')),
|
||||||
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: Constants.SettingsTypes.TYPE_BOOL,
|
|
||||||
key: 'DisplaySettings.ExperimentalTimezone',
|
|
||||||
label: t('admin.experimental.experimentalTimezone.title'),
|
|
||||||
label_default: 'Timezone:',
|
|
||||||
help_text: t('admin.experimental.experimentalTimezone.desc'),
|
|
||||||
help_text_default: 'Select the timezone used for timestamps in the user interface and email notifications. When true, the Timezone section is visible in the Settings and a time zone is automatically assigned in the next active session. When false, the Timezone setting is hidden in the Settings.',
|
|
||||||
help_text_markdown: false,
|
|
||||||
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
type: Constants.SettingsTypes.TYPE_BOOL,
|
type: Constants.SettingsTypes.TYPE_BOOL,
|
||||||
key: 'EmailSettings.UseChannelInEmailNotifications',
|
key: 'EmailSettings.UseChannelInEmailNotifications',
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
rhsExpanded: false,
|
rhsExpanded: false,
|
||||||
badConnection: false,
|
badConnection: false,
|
||||||
getChannelTimezones: jest.fn(() => Promise.resolve({data: '', error: ''})),
|
getChannelTimezones: jest.fn(() => Promise.resolve({data: '', error: ''})),
|
||||||
isTimezoneEnabled: false,
|
|
||||||
selectedPostFocussedAt: 0,
|
selectedPostFocussedAt: 0,
|
||||||
canPost: true,
|
canPost: true,
|
||||||
canUploadFiles: true,
|
canUploadFiles: true,
|
||||||
@@ -732,29 +731,6 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should show Confirm Modal for @${mention} mentions when needed`, () => {
|
|
||||||
const props: any = {
|
|
||||||
...baseProps,
|
|
||||||
draft: {
|
|
||||||
message: `Test message @${mention}`,
|
|
||||||
uploadsInProgress: [],
|
|
||||||
fileInfos: [{}, {}, {}],
|
|
||||||
},
|
|
||||||
onSubmit,
|
|
||||||
channelMembersCount: 8,
|
|
||||||
enableConfirmNotificationsToChannel: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = shallow<AdvancedCreateComment>(
|
|
||||||
<AdvancedCreateComment {...props}/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
wrapper.instance().handleSubmit(submitEvent);
|
|
||||||
expect(onSubmit).not.toHaveBeenCalled();
|
|
||||||
expect(preventDefault).toHaveBeenCalled();
|
|
||||||
expect(props.openModal).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should show Confirm Modal for @${mention} mentions when needed and timezone notification`, async () => {
|
it(`should show Confirm Modal for @${mention} mentions when needed and timezone notification`, async () => {
|
||||||
const props: any = {
|
const props: any = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
@@ -764,7 +740,6 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
fileInfos: [{}, {}, {}],
|
fileInfos: [{}, {}, {}],
|
||||||
},
|
},
|
||||||
onSubmit,
|
onSubmit,
|
||||||
isTimezoneEnabled: true,
|
|
||||||
channelMembersCount: 8,
|
channelMembersCount: 8,
|
||||||
enableConfirmNotificationsToChannel: true,
|
enableConfirmNotificationsToChannel: true,
|
||||||
};
|
};
|
||||||
@@ -792,7 +767,6 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
fileInfos: [{}, {}, {}],
|
fileInfos: [{}, {}, {}],
|
||||||
},
|
},
|
||||||
onSubmit,
|
onSubmit,
|
||||||
isTimezoneEnabled: true,
|
|
||||||
channelMembersCount: 8,
|
channelMembersCount: 8,
|
||||||
enableConfirmNotificationsToChannel: true,
|
enableConfirmNotificationsToChannel: true,
|
||||||
};
|
};
|
||||||
@@ -832,7 +806,6 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
channel_member_timezones_count: 0,
|
channel_member_timezones_count: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isTimezoneEnabled: false,
|
|
||||||
channelMembersCount: 8,
|
channelMembersCount: 8,
|
||||||
useChannelMentions: true,
|
useChannelMentions: true,
|
||||||
enableConfirmNotificationsToChannel: true,
|
enableConfirmNotificationsToChannel: true,
|
||||||
@@ -904,7 +877,6 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
channel_member_timezones_count: 0,
|
channel_member_timezones_count: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isTimezoneEnabled: false,
|
|
||||||
channelMembersCount: 8,
|
channelMembersCount: 8,
|
||||||
useChannelMentions: true,
|
useChannelMentions: true,
|
||||||
enableConfirmNotificationsToChannel: true,
|
enableConfirmNotificationsToChannel: true,
|
||||||
@@ -945,7 +917,6 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
channel_member_timezones_count: 5,
|
channel_member_timezones_count: 5,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isTimezoneEnabled: true,
|
|
||||||
channelMembersCount: 8,
|
channelMembersCount: 8,
|
||||||
useChannelMentions: true,
|
useChannelMentions: true,
|
||||||
enableConfirmNotificationsToChannel: true,
|
enableConfirmNotificationsToChannel: true,
|
||||||
|
|||||||
@@ -148,9 +148,6 @@ export type Props = {
|
|||||||
// Determines if the RHS is in expanded state
|
// Determines if the RHS is in expanded state
|
||||||
rhsExpanded: boolean;
|
rhsExpanded: boolean;
|
||||||
|
|
||||||
// Determines if timezones are enabled on the server.
|
|
||||||
isTimezoneEnabled: boolean;
|
|
||||||
|
|
||||||
// The last time, if any, the selected post changed. Will be 0 if no post is selected.
|
// The last time, if any, the selected post changed. Will be 0 if no post is selected.
|
||||||
selectedPostFocussedAt: number;
|
selectedPostFocussedAt: number;
|
||||||
|
|
||||||
@@ -173,7 +170,7 @@ export type Props = {
|
|||||||
scrollToBottom?: () => void;
|
scrollToBottom?: () => void;
|
||||||
|
|
||||||
// Group member mention
|
// Group member mention
|
||||||
getChannelMemberCountsByGroup: (channelID: string, isTimezoneEnabled: boolean) => void;
|
getChannelMemberCountsByGroup: (channelID: string) => void;
|
||||||
groupsWithAllowReference: Map<string, Group> | null;
|
groupsWithAllowReference: Map<string, Group> | null;
|
||||||
channelMemberCountsByGroup: ChannelMemberCountsByGroup;
|
channelMemberCountsByGroup: ChannelMemberCountsByGroup;
|
||||||
focusOnMount?: boolean;
|
focusOnMount?: boolean;
|
||||||
@@ -356,7 +353,7 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getChannelMemberCountsByGroup = () => {
|
getChannelMemberCountsByGroup = () => {
|
||||||
const {useLDAPGroupMentions, useCustomGroupMentions, channelId, isTimezoneEnabled, searchAssociatedGroupsForReference, getChannelMemberCountsByGroup, draft, currentTeamId} = this.props;
|
const {useLDAPGroupMentions, useCustomGroupMentions, channelId, searchAssociatedGroupsForReference, getChannelMemberCountsByGroup, draft, currentTeamId} = this.props;
|
||||||
|
|
||||||
if ((useLDAPGroupMentions || useCustomGroupMentions) && channelId) {
|
if ((useLDAPGroupMentions || useCustomGroupMentions) && channelId) {
|
||||||
const mentions = mentionsMinusSpecialMentionsInText(draft.message);
|
const mentions = mentionsMinusSpecialMentionsInText(draft.message);
|
||||||
@@ -364,7 +361,7 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
|||||||
if (mentions.length === 1) {
|
if (mentions.length === 1) {
|
||||||
searchAssociatedGroupsForReference(mentions[0], currentTeamId, channelId);
|
searchAssociatedGroupsForReference(mentions[0], currentTeamId, channelId);
|
||||||
} else if (mentions.length > 1) {
|
} else if (mentions.length > 1) {
|
||||||
getChannelMemberCountsByGroup(channelId, isTimezoneEnabled);
|
getChannelMemberCountsByGroup(channelId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -551,7 +548,6 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
|||||||
channelMembersCount,
|
channelMembersCount,
|
||||||
enableConfirmNotificationsToChannel,
|
enableConfirmNotificationsToChannel,
|
||||||
useChannelMentions,
|
useChannelMentions,
|
||||||
isTimezoneEnabled,
|
|
||||||
groupsWithAllowReference,
|
groupsWithAllowReference,
|
||||||
channelMemberCountsByGroup,
|
channelMemberCountsByGroup,
|
||||||
useLDAPGroupMentions,
|
useLDAPGroupMentions,
|
||||||
@@ -612,10 +608,8 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTimezoneEnabled) {
|
const {data} = await this.props.getChannelTimezones(this.props.channelId);
|
||||||
const {data} = await this.props.getChannelTimezones(this.props.channelId);
|
channelTimezoneCount = data ? data.length : 0;
|
||||||
channelTimezoneCount = data ? data.length : 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!useChannelMentions && hasSpecialMentions) {
|
if (!useChannelMentions && hasSpecialMentions) {
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ function makeMapStateToProps() {
|
|||||||
const enableEmojiPicker = config.EnableEmojiPicker === 'true';
|
const enableEmojiPicker = config.EnableEmojiPicker === 'true';
|
||||||
const enableGifPicker = config.EnableGifPicker === 'true';
|
const enableGifPicker = config.EnableGifPicker === 'true';
|
||||||
const badConnection = connectionErrorCount(state) > 1;
|
const badConnection = connectionErrorCount(state) > 1;
|
||||||
const isTimezoneEnabled = config.ExperimentalTimezone === 'true';
|
|
||||||
const canPost = haveIChannelPermission(state, channel.team_id, channel.id, Permissions.CREATE_POST);
|
const canPost = haveIChannelPermission(state, channel.team_id, channel.id, Permissions.CREATE_POST);
|
||||||
const useChannelMentions = haveIChannelPermission(state, channel.team_id, channel.id, Permissions.USE_CHANNEL_MENTIONS);
|
const useChannelMentions = haveIChannelPermission(state, channel.team_id, channel.id, Permissions.USE_CHANNEL_MENTIONS);
|
||||||
const isLDAPEnabled = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
|
const isLDAPEnabled = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
|
||||||
@@ -102,7 +101,6 @@ function makeMapStateToProps() {
|
|||||||
maxPostSize: parseInt(config.MaxPostSize || '', 10) || Constants.DEFAULT_CHARACTER_LIMIT,
|
maxPostSize: parseInt(config.MaxPostSize || '', 10) || Constants.DEFAULT_CHARACTER_LIMIT,
|
||||||
rhsExpanded: getIsRhsExpanded(state),
|
rhsExpanded: getIsRhsExpanded(state),
|
||||||
badConnection,
|
badConnection,
|
||||||
isTimezoneEnabled,
|
|
||||||
selectedPostFocussedAt: getSelectedPostFocussedAt(state),
|
selectedPostFocussedAt: getSelectedPostFocussedAt(state),
|
||||||
canPost,
|
canPost,
|
||||||
useChannelMentions,
|
useChannelMentions,
|
||||||
@@ -138,7 +136,7 @@ type Actions = {
|
|||||||
getChannelTimezones: (channelId: string) => Promise<ActionResult>;
|
getChannelTimezones: (channelId: string) => Promise<ActionResult>;
|
||||||
emitShortcutReactToLastPostFrom: (location: string) => void;
|
emitShortcutReactToLastPostFrom: (location: string) => void;
|
||||||
setShowPreview: (showPreview: boolean) => void;
|
setShowPreview: (showPreview: boolean) => void;
|
||||||
getChannelMemberCountsByGroup: (channelID: string, includeTimezones: boolean) => void;
|
getChannelMemberCountsByGroup: (channelID: string) => void;
|
||||||
openModal: <P>(modalData: ModalData<P>) => void;
|
openModal: <P>(modalData: ModalData<P>) => void;
|
||||||
savePreferences: (userId: string, preferences: PreferenceType[]) => ActionResult;
|
savePreferences: (userId: string, preferences: PreferenceType[]) => ActionResult;
|
||||||
searchAssociatedGroupsForReference: (prefix: string, teamId: string, channelId: string | undefined) => Promise<{ data: any }>;
|
searchAssociatedGroupsForReference: (prefix: string, teamId: string, channelId: string | undefined) => Promise<{ data: any }>;
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ const baseProp: Props = {
|
|||||||
executeCommand: () => {
|
executeCommand: () => {
|
||||||
return {data: true};
|
return {data: true};
|
||||||
},
|
},
|
||||||
getChannelTimezones: jest.fn(),
|
getChannelTimezones: jest.fn(() => {
|
||||||
|
return {data: '', error: ''};
|
||||||
|
}),
|
||||||
runMessageWillBePostedHooks: (post: Post) => {
|
runMessageWillBePostedHooks: (post: Post) => {
|
||||||
return {data: post};
|
return {data: post};
|
||||||
},
|
},
|
||||||
@@ -107,7 +109,6 @@ const baseProp: Props = {
|
|||||||
emojiMap: new EmojiMap(new Map()),
|
emojiMap: new EmojiMap(new Map()),
|
||||||
enableEmojiPicker: true,
|
enableEmojiPicker: true,
|
||||||
enableGifPicker: true,
|
enableGifPicker: true,
|
||||||
isTimezoneEnabled: false,
|
|
||||||
useLDAPGroupMentions: true,
|
useLDAPGroupMentions: true,
|
||||||
useCustomGroupMentions: true,
|
useCustomGroupMentions: true,
|
||||||
canPost: true,
|
canPost: true,
|
||||||
@@ -379,18 +380,34 @@ describe('components/advanced_create_post', () => {
|
|||||||
// expect(GlobalActions.emitLocalUserTypingEvent).toHaveBeenCalledWith(currentChannelProp.id, '');
|
// expect(GlobalActions.emitLocalUserTypingEvent).toHaveBeenCalledWith(currentChannelProp.id, '');
|
||||||
// });
|
// });
|
||||||
|
|
||||||
it('onSubmit test for @here', () => {
|
it('onSubmit test for @all', async () => {
|
||||||
const wrapper = shallow(advancedCreatePost());
|
const result: ActionResult = {
|
||||||
|
data: [1, 2, 3, 4],
|
||||||
|
};
|
||||||
|
const wrapper = shallow(
|
||||||
|
advancedCreatePost({
|
||||||
|
actions: {
|
||||||
|
...baseProp.actions,
|
||||||
|
getChannelTimezones: jest.fn(() => result),
|
||||||
|
},
|
||||||
|
currentChannelMembersCount: 9,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
wrapper.setState({
|
wrapper.setState({
|
||||||
message: 'test @here',
|
message: 'test @all',
|
||||||
});
|
});
|
||||||
|
|
||||||
const instance = wrapper.instance() as AdvancedCreatePost;
|
const instance = wrapper.instance() as AdvancedCreatePost;
|
||||||
|
|
||||||
|
const showNotifyAllModal = instance.showNotifyAllModal;
|
||||||
|
instance.showNotifyAllModal = jest.fn((mentions, channelTimezoneCount, memberNotifyCount) => showNotifyAllModal(mentions, channelTimezoneCount, memberNotifyCount));
|
||||||
|
|
||||||
const form = wrapper.find('#create_post');
|
const form = wrapper.find('#create_post');
|
||||||
form.simulate('Submit', {preventDefault: jest.fn()});
|
await form.simulate('Submit', {preventDefault: jest.fn()});
|
||||||
|
|
||||||
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
||||||
|
expect(instance.showNotifyAllModal).toHaveBeenCalledWith(['@all'], 4, 8);
|
||||||
|
|
||||||
wrapper.setProps({
|
wrapper.setProps({
|
||||||
currentChannelMembersCount: 2,
|
currentChannelMembersCount: 2,
|
||||||
@@ -400,18 +417,34 @@ describe('components/advanced_create_post', () => {
|
|||||||
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('onSubmit test for @all', () => {
|
it('onSubmit test for @here', async () => {
|
||||||
const wrapper = shallow(advancedCreatePost());
|
const result: ActionResult = {
|
||||||
|
data: [1, 2, 3, 4],
|
||||||
|
};
|
||||||
|
const wrapper = shallow(
|
||||||
|
advancedCreatePost({
|
||||||
|
actions: {
|
||||||
|
...baseProp.actions,
|
||||||
|
getChannelTimezones: jest.fn(() => result),
|
||||||
|
},
|
||||||
|
currentChannelMembersCount: 9,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
wrapper.setState({
|
wrapper.setState({
|
||||||
message: 'test @all',
|
message: 'test @here',
|
||||||
});
|
});
|
||||||
|
|
||||||
const instance = wrapper.instance() as AdvancedCreatePost;
|
const instance = wrapper.instance() as AdvancedCreatePost;
|
||||||
|
|
||||||
|
const showNotifyAllModal = instance.showNotifyAllModal;
|
||||||
|
instance.showNotifyAllModal = jest.fn((mentions, channelTimezoneCount, memberNotifyCount) => showNotifyAllModal(mentions, channelTimezoneCount, memberNotifyCount));
|
||||||
|
|
||||||
const form = wrapper.find('#create_post');
|
const form = wrapper.find('#create_post');
|
||||||
form.simulate('Submit', {preventDefault: jest.fn()});
|
await form.simulate('Submit', {preventDefault: jest.fn()});
|
||||||
|
|
||||||
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
||||||
|
expect(instance.showNotifyAllModal).toHaveBeenCalledWith(['@here'], 4, 8);
|
||||||
|
|
||||||
wrapper.setProps({
|
wrapper.setProps({
|
||||||
currentChannelMembersCount: 2,
|
currentChannelMembersCount: 2,
|
||||||
@@ -633,76 +666,6 @@ describe('components/advanced_create_post', () => {
|
|||||||
expect(onSubmitPost.mock.calls[0][0]).toEqual(post);
|
expect(onSubmitPost.mock.calls[0][0]).toEqual(post);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('onSubmit test for @all with timezones', async () => {
|
|
||||||
const result: ActionResult = {
|
|
||||||
data: [1, 2, 3, 4],
|
|
||||||
};
|
|
||||||
const wrapper = shallow(
|
|
||||||
advancedCreatePost({
|
|
||||||
actions: {
|
|
||||||
...baseProp.actions,
|
|
||||||
getChannelTimezones: jest.fn(() => result),
|
|
||||||
},
|
|
||||||
isTimezoneEnabled: true,
|
|
||||||
currentChannelMembersCount: 9,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
wrapper.setState({
|
|
||||||
message: 'test @all',
|
|
||||||
});
|
|
||||||
|
|
||||||
const instance = wrapper.instance() as AdvancedCreatePost;
|
|
||||||
|
|
||||||
const showNotifyAllModal = instance.showNotifyAllModal;
|
|
||||||
instance.showNotifyAllModal = jest.fn((mentions, channelTimezoneCount, memberNotifyCount) => showNotifyAllModal(mentions, channelTimezoneCount, memberNotifyCount));
|
|
||||||
|
|
||||||
const form = wrapper.find('#create_post');
|
|
||||||
await form.simulate('Submit', {preventDefault: jest.fn()});
|
|
||||||
|
|
||||||
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
|
||||||
expect(instance.showNotifyAllModal).toHaveBeenCalledWith(['@all'], 4, 8);
|
|
||||||
|
|
||||||
wrapper.setProps({
|
|
||||||
currentChannelMembersCount: 2,
|
|
||||||
});
|
|
||||||
|
|
||||||
form.simulate('Submit', {preventDefault: jest.fn()});
|
|
||||||
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('onSubmit test for @all with timezones disabled', () => {
|
|
||||||
const result: ActionResult = {
|
|
||||||
data: [],
|
|
||||||
};
|
|
||||||
const wrapper = shallow(
|
|
||||||
advancedCreatePost({
|
|
||||||
actions: {
|
|
||||||
...baseProp.actions,
|
|
||||||
getChannelTimezones: jest.fn(() => result),
|
|
||||||
},
|
|
||||||
isTimezoneEnabled: false,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
wrapper.setState({
|
|
||||||
message: 'test @all',
|
|
||||||
});
|
|
||||||
|
|
||||||
const instance = wrapper.instance() as AdvancedCreatePost;
|
|
||||||
|
|
||||||
const form = wrapper.find('#create_post');
|
|
||||||
form.simulate('Submit', {preventDefault: jest.fn()});
|
|
||||||
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
wrapper.setProps({
|
|
||||||
currentChannelMembersCount: 2,
|
|
||||||
});
|
|
||||||
|
|
||||||
form.simulate('Submit', {preventDefault: jest.fn()});
|
|
||||||
expect(instance.props.actions.openModal).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('onSubmit test for "/header" message', () => {
|
it('onSubmit test for "/header" message', () => {
|
||||||
const openModal = jest.fn();
|
const openModal = jest.fn();
|
||||||
|
|
||||||
|
|||||||
@@ -148,9 +148,6 @@ export type Props = {
|
|||||||
//If RHS open
|
//If RHS open
|
||||||
rhsOpen: boolean;
|
rhsOpen: boolean;
|
||||||
|
|
||||||
//To check if the timezones are enable on the server.
|
|
||||||
isTimezoneEnabled: boolean;
|
|
||||||
|
|
||||||
canPost: boolean;
|
canPost: boolean;
|
||||||
|
|
||||||
//To determine if the current user can send special channel mentions
|
//To determine if the current user can send special channel mentions
|
||||||
@@ -216,7 +213,7 @@ export type Props = {
|
|||||||
//Function to set or unset emoji picker for last message
|
//Function to set or unset emoji picker for last message
|
||||||
emitShortcutReactToLastPostFrom: (emittedFrom: string) => void;
|
emitShortcutReactToLastPostFrom: (emittedFrom: string) => void;
|
||||||
|
|
||||||
getChannelMemberCountsByGroup: (channelId: string, includeTimezones: boolean) => void;
|
getChannelMemberCountsByGroup: (channelId: string) => void;
|
||||||
|
|
||||||
//Function used to advance the tutorial forward
|
//Function used to advance the tutorial forward
|
||||||
savePreferences: (userId: string, preferences: PreferenceType[]) => ActionResult;
|
savePreferences: (userId: string, preferences: PreferenceType[]) => ActionResult;
|
||||||
@@ -354,7 +351,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getChannelMemberCountsByGroup = () => {
|
getChannelMemberCountsByGroup = () => {
|
||||||
const {useLDAPGroupMentions, useCustomGroupMentions, currentChannel, isTimezoneEnabled, actions, draft} = this.props;
|
const {useLDAPGroupMentions, useCustomGroupMentions, currentChannel, actions, draft} = this.props;
|
||||||
|
|
||||||
if ((useLDAPGroupMentions || useCustomGroupMentions) && currentChannel.id) {
|
if ((useLDAPGroupMentions || useCustomGroupMentions) && currentChannel.id) {
|
||||||
const mentions = mentionsMinusSpecialMentionsInText(draft.message);
|
const mentions = mentionsMinusSpecialMentionsInText(draft.message);
|
||||||
@@ -362,7 +359,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
if (mentions.length === 1) {
|
if (mentions.length === 1) {
|
||||||
actions.searchAssociatedGroupsForReference(mentions[0], this.props.currentTeamId, currentChannel.id);
|
actions.searchAssociatedGroupsForReference(mentions[0], this.props.currentTeamId, currentChannel.id);
|
||||||
} else if (mentions.length > 1) {
|
} else if (mentions.length > 1) {
|
||||||
actions.getChannelMemberCountsByGroup(currentChannel.id, isTimezoneEnabled);
|
actions.getChannelMemberCountsByGroup(currentChannel.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -672,10 +669,8 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.isTimezoneEnabled) {
|
const {data} = await this.props.actions.getChannelTimezones(this.props.currentChannel.id);
|
||||||
const {data} = await this.props.actions.getChannelTimezones(this.props.currentChannel.id);
|
channelTimezoneCount = data ? data.length : 0;
|
||||||
channelTimezoneCount = data ? data.length : 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDirectOrGroup =
|
const isDirectOrGroup =
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ function makeMapStateToProps() {
|
|||||||
const currentUserId = getCurrentUserId(state);
|
const currentUserId = getCurrentUserId(state);
|
||||||
const userIsOutOfOffice = getStatusForUserId(state, currentUserId) === UserStatuses.OUT_OF_OFFICE;
|
const userIsOutOfOffice = getStatusForUserId(state, currentUserId) === UserStatuses.OUT_OF_OFFICE;
|
||||||
const badConnection = connectionErrorCount(state) > 1;
|
const badConnection = connectionErrorCount(state) > 1;
|
||||||
const isTimezoneEnabled = config.ExperimentalTimezone === 'true';
|
|
||||||
const canPost = haveICurrentChannelPermission(state, Permissions.CREATE_POST);
|
const canPost = haveICurrentChannelPermission(state, Permissions.CREATE_POST);
|
||||||
const useChannelMentions = haveICurrentChannelPermission(state, Permissions.USE_CHANNEL_MENTIONS);
|
const useChannelMentions = haveICurrentChannelPermission(state, Permissions.USE_CHANNEL_MENTIONS);
|
||||||
const isLDAPEnabled = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
|
const isLDAPEnabled = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
|
||||||
@@ -126,7 +125,6 @@ function makeMapStateToProps() {
|
|||||||
rhsOpen: getIsRhsOpen(state),
|
rhsOpen: getIsRhsOpen(state),
|
||||||
emojiMap: getEmojiMap(state),
|
emojiMap: getEmojiMap(state),
|
||||||
badConnection,
|
badConnection,
|
||||||
isTimezoneEnabled,
|
|
||||||
canPost,
|
canPost,
|
||||||
useChannelMentions,
|
useChannelMentions,
|
||||||
shouldShowPreview: showPreviewOnCreatePost(state),
|
shouldShowPreview: showPreviewOnCreatePost(state),
|
||||||
@@ -167,7 +165,7 @@ type Actions = {
|
|||||||
getChannelTimezones: (channelId: string) => ActionResult;
|
getChannelTimezones: (channelId: string) => ActionResult;
|
||||||
scrollPostListToBottom: () => void;
|
scrollPostListToBottom: () => void;
|
||||||
emitShortcutReactToLastPostFrom: (emittedFrom: string) => void;
|
emitShortcutReactToLastPostFrom: (emittedFrom: string) => void;
|
||||||
getChannelMemberCountsByGroup: (channelId: string, includeTimezones: boolean) => void;
|
getChannelMemberCountsByGroup: (channelId: string) => void;
|
||||||
savePreferences: (userId: string, preferences: PreferenceType[]) => ActionResult;
|
savePreferences: (userId: string, preferences: PreferenceType[]) => ActionResult;
|
||||||
searchAssociatedGroupsForReference: (prefix: string, teamId: string, channelId: string | undefined) => Promise<{ data: any }>;
|
searchAssociatedGroupsForReference: (prefix: string, teamId: string, channelId: string | undefined) => Promise<{ data: any }>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ function mapStateToProps(state: GlobalState, ownProps: Props) {
|
|||||||
currentChannelId,
|
currentChannelId,
|
||||||
isCurrentChannelManuallyUnread: isManuallyUnread(state, currentChannelId),
|
isCurrentChannelManuallyUnread: isManuallyUnread(state, currentChannelId),
|
||||||
mfaRequired: checkIfMFARequired(getCurrentUser(state), license, config, ownProps.match.url),
|
mfaRequired: checkIfMFARequired(getCurrentUser(state), license, config, ownProps.match.url),
|
||||||
enableTimezone: config.ExperimentalTimezone === 'true',
|
|
||||||
showTermsOfService,
|
showTermsOfService,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ describe('components/logged_in/LoggedIn', () => {
|
|||||||
const baseProps: Props = {
|
const baseProps: Props = {
|
||||||
currentUser: {} as UserProfile,
|
currentUser: {} as UserProfile,
|
||||||
mfaRequired: false,
|
mfaRequired: false,
|
||||||
enableTimezone: false,
|
|
||||||
actions: {
|
actions: {
|
||||||
autoUpdateTimezone: jest.fn(),
|
autoUpdateTimezone: jest.fn(),
|
||||||
getChannelURLAction: jest.fn(),
|
getChannelURLAction: jest.fn(),
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ export type Props = {
|
|||||||
isCurrentChannelManuallyUnread: boolean;
|
isCurrentChannelManuallyUnread: boolean;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
mfaRequired: boolean;
|
mfaRequired: boolean;
|
||||||
enableTimezone: boolean;
|
|
||||||
actions: {
|
actions: {
|
||||||
autoUpdateTimezone: (deviceTimezone: string) => void;
|
autoUpdateTimezone: (deviceTimezone: string) => void;
|
||||||
getChannelURLAction: (channel: Channel, teamId: string, url: string) => void;
|
getChannelURLAction: (channel: Channel, teamId: string, url: string) => void;
|
||||||
@@ -81,9 +80,7 @@ export default class LoggedIn extends React.PureComponent<Props> {
|
|||||||
// Initialize websocket
|
// Initialize websocket
|
||||||
WebSocketActions.initialize();
|
WebSocketActions.initialize();
|
||||||
|
|
||||||
if (this.props.enableTimezone) {
|
this.props.actions.autoUpdateTimezone(getBrowserTimezone());
|
||||||
this.props.actions.autoUpdateTimezone(getBrowserTimezone());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the websockets close and reset version
|
// Make sure the websockets close and reset version
|
||||||
window.addEventListener('beforeunload', this.handleBeforeUnload);
|
window.addEventListener('beforeunload', this.handleBeforeUnload);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {getCurrentUserId} from 'mattermost-redux/selectors/entities/common';
|
|||||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||||
import {getPost} from 'mattermost-redux/selectors/entities/posts';
|
import {getPost} from 'mattermost-redux/selectors/entities/posts';
|
||||||
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
|
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
|
||||||
|
|
||||||
import {openShowEditHistory} from 'actions/views/rhs';
|
import {openShowEditHistory} from 'actions/views/rhs';
|
||||||
|
|
||||||
@@ -53,11 +53,7 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps): StateProps {
|
|||||||
const config = getConfig(state);
|
const config = getConfig(state);
|
||||||
const channel = getChannel(state, post?.channel_id || '');
|
const channel = getChannel(state, post?.channel_id || '');
|
||||||
|
|
||||||
let timeZone: TimestampProps['timeZone'];
|
const timeZone: TimestampProps['timeZone'] = getCurrentTimezone(state);
|
||||||
|
|
||||||
if (isTimezoneEnabled(state)) {
|
|
||||||
timeZone = getCurrentTimezone(state);
|
|
||||||
}
|
|
||||||
const postOwner = post ? isPostOwner(state, post) : undefined;
|
const postOwner = post ? isPostOwner(state, post) : undefined;
|
||||||
|
|
||||||
const isMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
|
const isMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
|
||||||
|
|||||||
@@ -3421,7 +3421,6 @@ exports[`components/ProfilePopover should show the start call button when isCall
|
|||||||
currentTeamId="team_id"
|
currentTeamId="team_id"
|
||||||
currentUserId=""
|
currentUserId=""
|
||||||
enableLastActiveTime={true}
|
enableLastActiveTime={true}
|
||||||
enableTimezone={false}
|
|
||||||
hide={[MockFunction]}
|
hide={[MockFunction]}
|
||||||
isAnyModalOpen={false}
|
isAnyModalOpen={false}
|
||||||
isCallsCanBeDisabledOnSpecificChannels={false}
|
isCallsCanBeDisabledOnSpecificChannels={false}
|
||||||
@@ -3515,7 +3514,6 @@ exports[`components/ProfilePopover should show the start call button when isCall
|
|||||||
currentUserId=""
|
currentUserId=""
|
||||||
customStatus={null}
|
customStatus={null}
|
||||||
enableLastActiveTime={true}
|
enableLastActiveTime={true}
|
||||||
enableTimezone={false}
|
|
||||||
hasMention={false}
|
hasMention={false}
|
||||||
hide={[MockFunction]}
|
hide={[MockFunction]}
|
||||||
intl={
|
intl={
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
getCurrentRelativeTeamUrl,
|
getCurrentRelativeTeamUrl,
|
||||||
getTeamMember,
|
getTeamMember,
|
||||||
} from 'mattermost-redux/selectors/entities/teams';
|
} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
|
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
|
||||||
import {displayLastActiveLabel, getCurrentUserId, getLastActiveTimestampUnits, getLastActivityForUserId, getStatusForUserId, getUser} from 'mattermost-redux/selectors/entities/users';
|
import {displayLastActiveLabel, getCurrentUserId, getLastActiveTimestampUnits, getLastActivityForUserId, getStatusForUserId, getUser} from 'mattermost-redux/selectors/entities/users';
|
||||||
import type {GenericAction} from 'mattermost-redux/types/actions';
|
import type {GenericAction} from 'mattermost-redux/types/actions';
|
||||||
|
|
||||||
@@ -93,7 +93,6 @@ function makeMapStateToProps() {
|
|||||||
return {
|
return {
|
||||||
currentTeamId: team.id,
|
currentTeamId: team.id,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
enableTimezone: isTimezoneEnabled(state),
|
|
||||||
isTeamAdmin,
|
isTeamAdmin,
|
||||||
isChannelAdmin,
|
isChannelAdmin,
|
||||||
isInCurrentTeam: Boolean(teamMember) && teamMember?.delete_at === 0,
|
isInCurrentTeam: Boolean(teamMember) && teamMember?.delete_at === 0,
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import {TestHelper} from 'utils/test_helper';
|
|||||||
|
|
||||||
describe('components/ProfilePopover', () => {
|
describe('components/ProfilePopover', () => {
|
||||||
const baseProps = {
|
const baseProps = {
|
||||||
enableTimezone: false,
|
|
||||||
userId: '0',
|
userId: '0',
|
||||||
user: TestHelper.getUserMock({
|
user: TestHelper.getUserMock({
|
||||||
username: 'some_username',
|
username: 'some_username',
|
||||||
@@ -67,6 +66,12 @@ describe('components/ProfilePopover', () => {
|
|||||||
},
|
},
|
||||||
users: {
|
users: {
|
||||||
currentUserId: '',
|
currentUserId: '',
|
||||||
|
profiles: {
|
||||||
|
user1: {
|
||||||
|
id: 'user1',
|
||||||
|
roles: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
preferences: {
|
preferences: {
|
||||||
myPreferences: {},
|
myPreferences: {},
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ export interface ProfilePopoverProps extends Omit<React.ComponentProps<typeof Po
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
enableTimezone: boolean;
|
|
||||||
actions: {
|
actions: {
|
||||||
openModal: <P>(modalData: ModalData<P>) => void;
|
openModal: <P>(modalData: ModalData<P>) => void;
|
||||||
closeModal: (modalId: string) => void;
|
closeModal: (modalId: string) => void;
|
||||||
@@ -425,7 +424,7 @@ class ProfilePopover extends React.PureComponent<ProfilePopoverProps, ProfilePop
|
|||||||
}
|
}
|
||||||
|
|
||||||
const keysToBeRemoved: Array<keyof ProfilePopoverProps> = ['user', 'userId', 'channelId', 'src', 'status', 'hideStatus', 'isBusy',
|
const keysToBeRemoved: Array<keyof ProfilePopoverProps> = ['user', 'userId', 'channelId', 'src', 'status', 'hideStatus', 'isBusy',
|
||||||
'hide', 'hasMention', 'enableTimezone', 'currentUserId', 'currentTeamId', 'teamUrl', 'actions', 'isTeamAdmin',
|
'hide', 'hasMention', 'currentUserId', 'currentTeamId', 'teamUrl', 'actions', 'isTeamAdmin',
|
||||||
'isChannelAdmin', 'canManageAnyChannelMembersInCurrentTeam', 'intl'];
|
'isChannelAdmin', 'canManageAnyChannelMembersInCurrentTeam', 'intl'];
|
||||||
const popoverProps: React.ComponentProps<typeof Popover> = Utils.deleteKeysFromObject({...this.props},
|
const popoverProps: React.ComponentProps<typeof Popover> = Utils.deleteKeysFromObject({...this.props},
|
||||||
keysToBeRemoved);
|
keysToBeRemoved);
|
||||||
@@ -566,11 +565,7 @@ class ProfilePopover extends React.PureComponent<ProfilePopoverProps, ProfilePop
|
|||||||
fromWebhook={this.props.fromWebhook}
|
fromWebhook={this.props.fromWebhook}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
if (
|
if (this.props.user.timezone && !haveOverrideProp) {
|
||||||
this.props.enableTimezone &&
|
|
||||||
this.props.user.timezone &&
|
|
||||||
!haveOverrideProp
|
|
||||||
) {
|
|
||||||
dataContent.push(
|
dataContent.push(
|
||||||
<ProfileTimezone
|
<ProfileTimezone
|
||||||
currentUserTimezone={this.props.currentUserTimezone}
|
currentUserTimezone={this.props.currentUserTimezone}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import {Settings} from 'luxon';
|
import {Settings} from 'luxon';
|
||||||
|
|
||||||
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
|
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
|
||||||
|
|
||||||
import {getCurrentLocale} from 'selectors/i18n';
|
import {getCurrentLocale} from 'selectors/i18n';
|
||||||
|
|
||||||
@@ -18,11 +18,9 @@ export function applyLuxonDefaults(state: GlobalState) {
|
|||||||
Settings.defaultLocale = locale;
|
Settings.defaultLocale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTimezoneEnabled(state)) {
|
const tz = getCurrentTimezone(state);
|
||||||
const tz = getCurrentTimezone(state);
|
if (tz !== prevTimezone) {
|
||||||
if (tz !== prevTimezone) {
|
prevTimezone = tz;
|
||||||
prevTimezone = tz;
|
Settings.defaultZone = tz ?? 'system';
|
||||||
Settings.defaultZone = tz ?? 'system';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ describe('components/StatusDropdown', () => {
|
|||||||
manualTimezone: '',
|
manualTimezone: '',
|
||||||
},
|
},
|
||||||
status: 'away',
|
status: 'away',
|
||||||
isTimezoneEnabled: true,
|
|
||||||
isMilitaryTime: false,
|
isMilitaryTime: false,
|
||||||
isCustomStatusEnabled: false,
|
isCustomStatusEnabled: false,
|
||||||
isCustomStatusExpired: false,
|
isCustomStatusExpired: false,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
|
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
|
||||||
|
|
||||||
import {getCurrentLocale} from 'selectors/i18n';
|
import {getCurrentLocale} from 'selectors/i18n';
|
||||||
|
|
||||||
@@ -16,13 +16,7 @@ import SearchDateSuggestion from './search_date_suggestion';
|
|||||||
function mapStateToProps(state: GlobalState) {
|
function mapStateToProps(state: GlobalState) {
|
||||||
const timezone = getCurrentTimezone(state);
|
const timezone = getCurrentTimezone(state);
|
||||||
const locale = getCurrentLocale(state);
|
const locale = getCurrentLocale(state);
|
||||||
|
const currentDate = getCurrentDateForTimezone(timezone);
|
||||||
const enableTimezone = isTimezoneEnabled(state);
|
|
||||||
|
|
||||||
let currentDate;
|
|
||||||
if (enableTimezone) {
|
|
||||||
currentDate = getCurrentDateForTimezone(timezone);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentDate,
|
currentDate,
|
||||||
|
|||||||
@@ -18,11 +18,6 @@ describe('mapStateToProps', () => {
|
|||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
entities: {
|
entities: {
|
||||||
general: {
|
|
||||||
config: {
|
|
||||||
ExperimentalTimezone: 'true',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
preferences: {
|
preferences: {
|
||||||
myPreferences: {},
|
myPreferences: {},
|
||||||
},
|
},
|
||||||
@@ -124,14 +119,6 @@ describe('mapStateToProps', () => {
|
|||||||
const props = mapStateToProps(testState, {timeZone: 'America/Phoenix'});
|
const props = mapStateToProps(testState, {timeZone: 'America/Phoenix'});
|
||||||
expect(props.timeZone).toBe('America/Phoenix');
|
expect(props.timeZone).toBe('America/Phoenix');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('timeZone should be the value of prop.timeZone when given, even when timezone are disabled', () => {
|
|
||||||
const testState = {...initialState};
|
|
||||||
testState.entities.general.config.ExperimentalTimezone = 'false';
|
|
||||||
|
|
||||||
const props = mapStateToProps(testState, {timeZone: 'America/Chicago'});
|
|
||||||
expect(props.timeZone).toBe('America/Chicago');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hour12, hourCycle unsupported', () => {
|
describe('hour12, hourCycle unsupported', () => {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {connect} from 'react-redux';
|
|||||||
import type {UserTimezone} from '@mattermost/types/users';
|
import type {UserTimezone} from '@mattermost/types/users';
|
||||||
|
|
||||||
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {getCurrentTimezoneFull, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
|
import {getCurrentTimezoneFull} from 'mattermost-redux/selectors/entities/timezone';
|
||||||
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
|
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
|
||||||
|
|
||||||
import {Preferences} from 'utils/constants';
|
import {Preferences} from 'utils/constants';
|
||||||
@@ -25,14 +25,10 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function mapStateToProps(state: GlobalState, ownProps: Props) {
|
export function mapStateToProps(state: GlobalState, ownProps: Props) {
|
||||||
let timeZone: TimestampProps['timeZone'];
|
const timeZone: TimestampProps['timeZone'] = getUserCurrentTimezone(ownProps.userTimezone ?? getCurrentTimezoneFull(state)) || undefined;
|
||||||
let hourCycle: TimestampProps['hourCycle'];
|
let hourCycle: TimestampProps['hourCycle'];
|
||||||
let hour12: TimestampProps['hour12'];
|
let hour12: TimestampProps['hour12'];
|
||||||
|
|
||||||
if (isTimezoneEnabled(state)) {
|
|
||||||
timeZone = getUserCurrentTimezone(ownProps.userTimezone ?? getCurrentTimezoneFull(state)) ?? undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const useMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
|
const useMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
|
||||||
|
|
||||||
if (supportsHourCycle) {
|
if (supportsHourCycle) {
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ export function makeMapStateToProps() {
|
|||||||
const enableLinkPreviews = config.EnableLinkPreviews === 'true';
|
const enableLinkPreviews = config.EnableLinkPreviews === 'true';
|
||||||
const defaultClientLocale = config.DefaultClientLocale as string;
|
const defaultClientLocale = config.DefaultClientLocale as string;
|
||||||
const enableThemeSelection = config.EnableThemeSelection === 'true';
|
const enableThemeSelection = config.EnableThemeSelection === 'true';
|
||||||
const enableTimezone = config.ExperimentalTimezone === 'true';
|
|
||||||
const lockTeammateNameDisplay = getLicense(state).LockTeammateNameDisplay === 'true' && config.LockTeammateNameDisplay === 'true';
|
const lockTeammateNameDisplay = getLicense(state).LockTeammateNameDisplay === 'true' && config.LockTeammateNameDisplay === 'true';
|
||||||
const configTeammateNameDisplay = config.TeammateNameDisplay as string;
|
const configTeammateNameDisplay = config.TeammateNameDisplay as string;
|
||||||
const emojiPickerEnabled = config.EnableEmojiPicker === 'true';
|
const emojiPickerEnabled = config.EnableEmojiPicker === 'true';
|
||||||
@@ -62,7 +61,6 @@ export function makeMapStateToProps() {
|
|||||||
enableLinkPreviews,
|
enableLinkPreviews,
|
||||||
defaultClientLocale,
|
defaultClientLocale,
|
||||||
enableThemeSelection,
|
enableThemeSelection,
|
||||||
enableTimezone,
|
|
||||||
timezones,
|
timezones,
|
||||||
timezoneLabel,
|
timezoneLabel,
|
||||||
userTimezone,
|
userTimezone,
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
|
|||||||
|
|
||||||
configTeammateNameDisplay: '',
|
configTeammateNameDisplay: '',
|
||||||
currentUserTimezone: 'America/New_York',
|
currentUserTimezone: 'America/New_York',
|
||||||
enableTimezone: true,
|
|
||||||
shouldAutoUpdateTimezone: true,
|
shouldAutoUpdateTimezone: true,
|
||||||
lockTeammateNameDisplay: false,
|
lockTeammateNameDisplay: false,
|
||||||
collapsedReplyThreads: '',
|
collapsedReplyThreads: '',
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ type Props = {
|
|||||||
enableThemeSelection: boolean;
|
enableThemeSelection: boolean;
|
||||||
configTeammateNameDisplay: string;
|
configTeammateNameDisplay: string;
|
||||||
currentUserTimezone: string;
|
currentUserTimezone: string;
|
||||||
enableTimezone: boolean;
|
|
||||||
shouldAutoUpdateTimezone: boolean | string;
|
shouldAutoUpdateTimezone: boolean | string;
|
||||||
lockTeammateNameDisplay: boolean;
|
lockTeammateNameDisplay: boolean;
|
||||||
militaryTime: string;
|
militaryTime: string;
|
||||||
@@ -181,9 +180,9 @@ export default class UserSettingsDisplay extends React.PureComponent<Props, Stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const {actions, enableTimezone, shouldAutoUpdateTimezone} = this.props;
|
const {actions, shouldAutoUpdateTimezone} = this.props;
|
||||||
|
|
||||||
if (enableTimezone && shouldAutoUpdateTimezone) {
|
if (shouldAutoUpdateTimezone) {
|
||||||
actions.autoUpdateTimezone(getBrowserTimezone());
|
actions.autoUpdateTimezone(getBrowserTimezone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -845,7 +844,7 @@ export default class UserSettingsDisplay extends React.PureComponent<Props, Stat
|
|||||||
});
|
});
|
||||||
|
|
||||||
let timezoneSelection;
|
let timezoneSelection;
|
||||||
if (this.props.enableTimezone && !this.props.shouldAutoUpdateTimezone) {
|
if (!this.props.shouldAutoUpdateTimezone) {
|
||||||
const userTimezone = this.props.userTimezone;
|
const userTimezone = this.props.userTimezone;
|
||||||
const active = this.props.activeSection === 'timezone';
|
const active = this.props.activeSection === 'timezone';
|
||||||
let max = null;
|
let max = null;
|
||||||
|
|||||||
@@ -933,8 +933,6 @@
|
|||||||
"admin.experimental.experimentalPrimaryTeam.desc": "The primary team of which users on the server are members. When a primary team is set, the options to join other teams or leave the primary team are disabled.",
|
"admin.experimental.experimentalPrimaryTeam.desc": "The primary team of which users on the server are members. When a primary team is set, the options to join other teams or leave the primary team are disabled.",
|
||||||
"admin.experimental.experimentalPrimaryTeam.example": "E.g.: \"teamname\"",
|
"admin.experimental.experimentalPrimaryTeam.example": "E.g.: \"teamname\"",
|
||||||
"admin.experimental.experimentalPrimaryTeam.title": "Primary Team:",
|
"admin.experimental.experimentalPrimaryTeam.title": "Primary Team:",
|
||||||
"admin.experimental.experimentalTimezone.desc": "Select the timezone used for timestamps in the user interface and email notifications. When true, the Timezone section is visible in the Settings and a time zone is automatically assigned in the next active session. When false, the Timezone setting is hidden in the Settings.",
|
|
||||||
"admin.experimental.experimentalTimezone.title": "Timezone:",
|
|
||||||
"admin.experimental.experimentalUseNewSAMLLibrary.desc": "Enable an updated SAML Library, which does not require the XML Security Library (xmlsec1) to be installed. Warning: Not all providers have been tested. If you experience issues, please contact support: <linkSupport>https://mattermost.com/support/</linkSupport>. Changing this setting requires a server restart before taking effect.",
|
"admin.experimental.experimentalUseNewSAMLLibrary.desc": "Enable an updated SAML Library, which does not require the XML Security Library (xmlsec1) to be installed. Warning: Not all providers have been tested. If you experience issues, please contact support: <linkSupport>https://mattermost.com/support/</linkSupport>. Changing this setting requires a server restart before taking effect.",
|
||||||
"admin.experimental.experimentalUseNewSAMLLibrary.title": "Use Improved SAML Library (Beta):",
|
"admin.experimental.experimentalUseNewSAMLLibrary.title": "Use Improved SAML Library (Beta):",
|
||||||
"admin.experimental.ldapSettingsLoginButtonBorderColor.desc": "Specify the color of the AD/LDAP login button border for white labeling purposes. Use a hex code with a #-sign before the code. This setting only applies to the mobile apps.",
|
"admin.experimental.ldapSettingsLoginButtonBorderColor.desc": "Specify the color of the AD/LDAP login button border for white labeling purposes. Use a hex code with a #-sign before the code. This setting only applies to the mobile apps.",
|
||||||
|
|||||||
@@ -2095,7 +2095,7 @@ describe('Actions.Channels', () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await store.dispatch(Actions.getChannelMemberCountsByGroup(channelID, true));
|
await store.dispatch(Actions.getChannelMemberCountsByGroup(channelID));
|
||||||
|
|
||||||
const channelMemberCounts = store.getState().entities.channels.channelMemberCountsByGroup[channelID];
|
const channelMemberCounts = store.getState().entities.channels.channelMemberCountsByGroup[channelID];
|
||||||
expect(channelMemberCounts['group-1'].group_id).toEqual('group-1');
|
expect(channelMemberCounts['group-1'].group_id).toEqual('group-1');
|
||||||
|
|||||||
@@ -1482,10 +1482,10 @@ export function patchChannelModerations(channelId: string, patch: ChannelModerat
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getChannelMemberCountsByGroup(channelId: string, includeTimezones: boolean): ActionFunc {
|
export function getChannelMemberCountsByGroup(channelId: string): ActionFunc {
|
||||||
return bindClientFunc({
|
return bindClientFunc({
|
||||||
clientFunc: async () => {
|
clientFunc: async () => {
|
||||||
const channelMemberCountsByGroup = await Client4.getChannelMemberCountsByGroup(channelId, includeTimezones);
|
const channelMemberCountsByGroup = await Client4.getChannelMemberCountsByGroup(channelId, true);
|
||||||
return {channelId, memberCounts: channelMemberCountsByGroup};
|
return {channelId, memberCounts: channelMemberCountsByGroup};
|
||||||
},
|
},
|
||||||
onSuccess: ChannelTypes.RECEIVED_CHANNEL_MEMBER_COUNTS_BY_GROUP,
|
onSuccess: ChannelTypes.RECEIVED_CHANNEL_MEMBER_COUNTS_BY_GROUP,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import timezones from 'timezones.json';
|
import timezones from 'timezones.json';
|
||||||
|
|
||||||
import type {GlobalState} from '@mattermost/types/store';
|
|
||||||
import type {UserProfile} from '@mattermost/types/users';
|
import type {UserProfile} from '@mattermost/types/users';
|
||||||
|
|
||||||
import {createSelector} from 'mattermost-redux/selectors/create_selector';
|
import {createSelector} from 'mattermost-redux/selectors/create_selector';
|
||||||
@@ -26,11 +25,6 @@ function getTimezoneForUserProfile(profile: UserProfile) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTimezoneEnabled(state: GlobalState) {
|
|
||||||
const {config} = state.entities.general;
|
|
||||||
return config.ExperimentalTimezone === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getCurrentTimezoneFull = createSelector(
|
export const getCurrentTimezoneFull = createSelector(
|
||||||
'getCurrentTimezoneFull',
|
'getCurrentTimezoneFull',
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
|||||||
import {makeGetPostsForIds} from 'mattermost-redux/selectors/entities/posts';
|
import {makeGetPostsForIds} from 'mattermost-redux/selectors/entities/posts';
|
||||||
import type {UserActivityPost} from 'mattermost-redux/selectors/entities/posts';
|
import type {UserActivityPost} from 'mattermost-redux/selectors/entities/posts';
|
||||||
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
|
|
||||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||||
import {createIdsSelector, memoizeResult} from 'mattermost-redux/utils/helpers';
|
import {createIdsSelector, memoizeResult} from 'mattermost-redux/utils/helpers';
|
||||||
import {isUserActivityPost, shouldFilterJoinLeavePost, isFromWebhook} from 'mattermost-redux/utils/post_utils';
|
import {isUserActivityPost, shouldFilterJoinLeavePost, isFromWebhook} from 'mattermost-redux/utils/post_utils';
|
||||||
@@ -62,8 +61,7 @@ export function makeFilterPostsAndAddSeparators() {
|
|||||||
(state) => state.entities.posts.selectedPostId,
|
(state) => state.entities.posts.selectedPostId,
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
shouldShowJoinLeaveMessages,
|
shouldShowJoinLeaveMessages,
|
||||||
isTimezoneEnabled,
|
(posts, lastViewedAt, indicateNewMessages, selectedPostId, currentUser, showJoinLeave) => {
|
||||||
(posts, lastViewedAt, indicateNewMessages, selectedPostId, currentUser, showJoinLeave, timeZoneEnabled) => {
|
|
||||||
if (posts.length === 0 || !currentUser) {
|
if (posts.length === 0 || !currentUser) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -90,15 +88,13 @@ export function makeFilterPostsAndAddSeparators() {
|
|||||||
|
|
||||||
// Push on a date header if the last post was on a different day than the current one
|
// Push on a date header if the last post was on a different day than the current one
|
||||||
const postDate = new Date(post.create_at);
|
const postDate = new Date(post.create_at);
|
||||||
if (timeZoneEnabled) {
|
const currentOffset = postDate.getTimezoneOffset() * 60 * 1000;
|
||||||
const currentOffset = postDate.getTimezoneOffset() * 60 * 1000;
|
const timezone = getUserCurrentTimezone(currentUser.timezone);
|
||||||
const timezone = getUserCurrentTimezone(currentUser.timezone);
|
if (timezone) {
|
||||||
if (timezone) {
|
const zone = moment.tz.zone(timezone);
|
||||||
const zone = moment.tz.zone(timezone);
|
if (zone) {
|
||||||
if (zone) {
|
const timezoneOffset = zone.utcOffset(postDate.getTime()) * 60 * 1000;
|
||||||
const timezoneOffset = zone.utcOffset(post.create_at) * 60 * 1000;
|
postDate.setTime(postDate.getTime() + (currentOffset - timezoneOffset));
|
||||||
postDate.setTime(post.create_at + (currentOffset - timezoneOffset));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {getCurrentUser} from 'mattermost-redux/selectors/entities/common';
|
|||||||
import {makeGetPostsForIds} from 'mattermost-redux/selectors/entities/posts';
|
import {makeGetPostsForIds} from 'mattermost-redux/selectors/entities/posts';
|
||||||
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {getThreads} from 'mattermost-redux/selectors/entities/threads';
|
import {getThreads} from 'mattermost-redux/selectors/entities/threads';
|
||||||
import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
|
|
||||||
import {createIdsSelector} from 'mattermost-redux/utils/helpers';
|
import {createIdsSelector} from 'mattermost-redux/utils/helpers';
|
||||||
import {DATE_LINE, makeCombineUserActivityPosts, START_OF_NEW_MESSAGES, CREATE_COMMENT} from 'mattermost-redux/utils/post_list';
|
import {DATE_LINE, makeCombineUserActivityPosts, START_OF_NEW_MESSAGES, CREATE_COMMENT} from 'mattermost-redux/utils/post_list';
|
||||||
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
|
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
|
||||||
@@ -100,8 +99,7 @@ export function makeFilterRepliesAndAddSeparators() {
|
|||||||
(_state: GlobalState, {lastViewedAt}: PostFilterOptions) => lastViewedAt,
|
(_state: GlobalState, {lastViewedAt}: PostFilterOptions) => lastViewedAt,
|
||||||
(_state: GlobalState, {showDate}: PostFilterOptions) => showDate,
|
(_state: GlobalState, {showDate}: PostFilterOptions) => showDate,
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
isTimezoneEnabled,
|
(posts, lastViewedAt, showDate, currentUser) => {
|
||||||
(posts, lastViewedAt, showDate, currentUser, timeZoneEnabled) => {
|
|
||||||
if (posts.length === 0 || !currentUser) {
|
if (posts.length === 0 || !currentUser) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -121,15 +119,13 @@ export function makeFilterRepliesAndAddSeparators() {
|
|||||||
if (showDate) {
|
if (showDate) {
|
||||||
// Push on a date header if the last post was on a different day than the current one
|
// Push on a date header if the last post was on a different day than the current one
|
||||||
const postDate = new Date(post.create_at);
|
const postDate = new Date(post.create_at);
|
||||||
if (timeZoneEnabled) {
|
const currentOffset = postDate.getTimezoneOffset() * 60 * 1000;
|
||||||
const currentOffset = postDate.getTimezoneOffset() * 60 * 1000;
|
const timezone = getUserCurrentTimezone(currentUser.timezone);
|
||||||
const timezone = getUserCurrentTimezone(currentUser.timezone);
|
if (timezone) {
|
||||||
if (timezone) {
|
const zone = moment.tz.zone(timezone);
|
||||||
const zone = moment.tz.zone(timezone);
|
if (zone) {
|
||||||
if (zone) {
|
const timezoneOffset = zone.utcOffset(post.create_at) * 60 * 1000;
|
||||||
const timezoneOffset = zone.utcOffset(post.create_at) * 60 * 1000;
|
postDate.setTime(post.create_at + (currentOffset - timezoneOffset));
|
||||||
postDate.setTime(post.create_at + (currentOffset - timezoneOffset));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ export type ClientConfig = {
|
|||||||
ExperimentalEnablePostMetadata: string;
|
ExperimentalEnablePostMetadata: string;
|
||||||
ExperimentalGroupUnreadChannels: string;
|
ExperimentalGroupUnreadChannels: string;
|
||||||
ExperimentalPrimaryTeam: string;
|
ExperimentalPrimaryTeam: string;
|
||||||
ExperimentalTimezone: string;
|
|
||||||
ExperimentalViewArchivedChannels: string;
|
ExperimentalViewArchivedChannels: string;
|
||||||
FileLevel: string;
|
FileLevel: string;
|
||||||
FeatureFlagAppsEnabled: string;
|
FeatureFlagAppsEnabled: string;
|
||||||
@@ -864,7 +863,6 @@ export type PluginSettings = {
|
|||||||
|
|
||||||
export type DisplaySettings = {
|
export type DisplaySettings = {
|
||||||
CustomURLSchemes: string[];
|
CustomURLSchemes: string[];
|
||||||
ExperimentalTimezone: boolean;
|
|
||||||
MaxMarkdownNodes: number;
|
MaxMarkdownNodes: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user