Apply data retention policy (#1122)
This commit is contained in:
parent
380f5d884a
commit
b7fe369fab
4 changed files with 101 additions and 30 deletions
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {PostTypes} from 'mattermost-redux/action_types';
|
||||
import {GeneralTypes, PostTypes} from 'mattermost-redux/action_types';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
|
||||
import {getClientConfig, getDataRetentionPolicy, getLicenseConfig} from 'mattermost-redux/actions/general';
|
||||
import {getPosts} from 'mattermost-redux/actions/posts';
|
||||
import {getMyTeams, getMyTeamMembers, selectTeam} from 'mattermost-redux/actions/teams';
|
||||
|
||||
|
|
@ -16,11 +16,21 @@ import {
|
|||
|
||||
export function loadConfigAndLicense() {
|
||||
return async (dispatch, getState) => {
|
||||
const [config, license] = await Promise.all([
|
||||
const [configData, licenseData] = await Promise.all([
|
||||
getClientConfig()(dispatch, getState),
|
||||
getLicenseConfig()(dispatch, getState)
|
||||
]);
|
||||
|
||||
const config = configData.data || {};
|
||||
const license = licenseData.data || {};
|
||||
|
||||
if (config.DataRetentionEnableMessageDeletion && config.DataRetentionEnableMessageDeletion === 'true' &&
|
||||
license.IsLicensed === 'true' && license.DataRetention === 'true') {
|
||||
getDataRetentionPolicy()(dispatch, getState);
|
||||
} else {
|
||||
dispatch({type: GeneralTypes.RECEIVED_DATA_RETENTION_POLICY, data: {}});
|
||||
}
|
||||
|
||||
return {config, license};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const state = {
|
|||
appState: false,
|
||||
credentials: {},
|
||||
config: {},
|
||||
dataRetentionPolicy: {},
|
||||
deviceToken: '',
|
||||
license: {},
|
||||
serverVersion: ''
|
||||
|
|
@ -45,6 +46,9 @@ const state = {
|
|||
preferences: {
|
||||
myPreferences: {}
|
||||
},
|
||||
search: {
|
||||
recent: []
|
||||
},
|
||||
typing: {}
|
||||
},
|
||||
errors: [],
|
||||
|
|
@ -108,6 +112,10 @@ const state = {
|
|||
status: 'not_started',
|
||||
error: null
|
||||
},
|
||||
dataRetentionPolicy: {
|
||||
status: 'not_started',
|
||||
error: null
|
||||
},
|
||||
license: {
|
||||
status: 'not_started',
|
||||
error: null
|
||||
|
|
@ -252,8 +260,7 @@ const state = {
|
|||
navigation: '',
|
||||
views: {
|
||||
channel: {
|
||||
drafts: {},
|
||||
loading: false
|
||||
drafts: {}
|
||||
},
|
||||
fetchCache: {},
|
||||
i18n: {
|
||||
|
|
@ -270,7 +277,9 @@ const state = {
|
|||
selectServer: {
|
||||
serverUrl: Config.DefaultServerUrl
|
||||
},
|
||||
team: {},
|
||||
team: {
|
||||
lastTeamId: ''
|
||||
},
|
||||
thread: {
|
||||
drafts: {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import DeviceInfo from 'react-native-device-info';
|
||||
|
||||
import {ViewTypes} from 'app/constants';
|
||||
import Config from 'assets/config';
|
||||
import initialState from 'app/initial_state';
|
||||
|
||||
export function messageRetention() {
|
||||
return (next) => (action) => {
|
||||
|
|
@ -23,6 +23,7 @@ export function messageRetention() {
|
|||
|
||||
// Keep only the last 60 messages for the last 5 viewed channels in each team
|
||||
// and apply data retention on those posts if applies
|
||||
|
||||
return next(cleanupState(action));
|
||||
} else if (action.type === ViewTypes.DATA_CLEANUP) {
|
||||
const nextAction = cleanupState(action, true);
|
||||
|
|
@ -36,8 +37,22 @@ export function messageRetention() {
|
|||
function resetStateForNewVersion(action) {
|
||||
const {payload} = action;
|
||||
const lastChannelForTeam = getLastChannelForTeam(payload);
|
||||
let users = {};
|
||||
|
||||
let general = initialState.entities.general;
|
||||
if (payload.entities.general) {
|
||||
general = payload.entities.general;
|
||||
}
|
||||
|
||||
let teams = initialState.entities.teams;
|
||||
if (payload.entities.teams) {
|
||||
teams = {
|
||||
currentTeamId: payload.entities.teams.currentTeamId,
|
||||
teams: payload.entities.teams.teams,
|
||||
myMembers: payload.entities.teams.myMembers
|
||||
};
|
||||
}
|
||||
|
||||
let users = initialState.entities.users;
|
||||
if (payload.entities.users) {
|
||||
const currentUserId = payload.entities.users.currentUserId;
|
||||
if (currentUserId) {
|
||||
|
|
@ -50,38 +65,74 @@ function resetStateForNewVersion(action) {
|
|||
}
|
||||
}
|
||||
|
||||
let preferences = initialState.entities.preferences;
|
||||
if (payload.entities.preferences) {
|
||||
preferences = payload.entities.preferences;
|
||||
}
|
||||
|
||||
let search = initialState.entities.search;
|
||||
if (payload.entities.search && payload.entities.search.recent) {
|
||||
search = {
|
||||
recent: payload.entities.search.recent
|
||||
};
|
||||
}
|
||||
|
||||
let channelDrafts = initialState.views.channel.drafts;
|
||||
if (payload.views.channel && payload.views.channel.drafts) {
|
||||
channelDrafts = payload.views.channel.drafts;
|
||||
}
|
||||
|
||||
let i18n = initialState.views.i18n;
|
||||
if (payload.views.i18n) {
|
||||
i18n = payload.views.i18n;
|
||||
}
|
||||
|
||||
let fetchCache = initialState.views.fetchCache;
|
||||
if (payload.views.fetchCache) {
|
||||
fetchCache = payload.views.fetchCache;
|
||||
}
|
||||
|
||||
let lastTeamId = initialState.views.team.lastTeamId;
|
||||
if (payload.views.team && payload.views.team.lastTeamId) {
|
||||
lastTeamId = payload.views.team.lastTeamId;
|
||||
}
|
||||
|
||||
let threadDrafts = initialState.views.thread.drafts;
|
||||
if (payload.views.thread && payload.views.thread.drafts) {
|
||||
threadDrafts = payload.views.thread.drafts;
|
||||
}
|
||||
|
||||
let selectServer = initialState.views.selectServer;
|
||||
if (payload.views.selectServer) {
|
||||
selectServer = payload.views.selectServer;
|
||||
}
|
||||
|
||||
const nextState = {
|
||||
app: {
|
||||
build: DeviceInfo.getBuildNumber(),
|
||||
version: DeviceInfo.getVersion()
|
||||
},
|
||||
entities: {
|
||||
general: payload.entities.general,
|
||||
teams: {
|
||||
currentTeamId: payload.entities.teams.currentTeamId,
|
||||
teams: payload.entities.teams.teams,
|
||||
myMembers: payload.entities.teams.myMembers
|
||||
},
|
||||
general,
|
||||
teams,
|
||||
users,
|
||||
preferences: payload.entities.preferences,
|
||||
search: {
|
||||
recent: payload.entities.search ? payload.entities.search.recent : {}
|
||||
}
|
||||
preferences,
|
||||
search
|
||||
},
|
||||
views: {
|
||||
channel: {
|
||||
drafts: payload.views.channel.drafts
|
||||
drafts: channelDrafts
|
||||
},
|
||||
i18n: payload.views.i18n,
|
||||
fetchCache: payload.views.fetchCache,
|
||||
i18n,
|
||||
fetchCache,
|
||||
team: {
|
||||
lastTeamId: payload.views.team.lastTeamId,
|
||||
lastTeamId,
|
||||
lastChannelForTeam
|
||||
},
|
||||
thread: {
|
||||
drafts: payload.views.thread.drafts
|
||||
drafts: threadDrafts
|
||||
},
|
||||
selectServer: payload.views.selectServer
|
||||
selectServer
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -126,7 +177,12 @@ function cleanupState(action, keepCurrent = false) {
|
|||
}
|
||||
};
|
||||
|
||||
const retentionPeriod = Config.EnableMessageRetention ? Config.MessageRetentionPeriod + 1 : 0;
|
||||
let retentionPeriod = 0;
|
||||
if (resetPayload.entities.general && resetPayload.entities.general.dataRetentionPolicy &&
|
||||
resetPayload.entities.general.dataRetentionPolicy.message_deletion_enabled) {
|
||||
retentionPeriod = resetPayload.entities.general.dataRetentionPolicy.message_retention_cutoff;
|
||||
}
|
||||
|
||||
const postIdsToKeep = Object.values(lastChannelForTeam).reduce((array, channelIds) => {
|
||||
const ids = channelIds.reduce((result, id) => {
|
||||
// we need to check that the channel id is not already included
|
||||
|
|
@ -152,9 +208,7 @@ function cleanupState(action, keepCurrent = false) {
|
|||
const post = payload.entities.posts.posts[postId];
|
||||
|
||||
if (post) {
|
||||
const skip = keepCurrent && currentChannelId === post.channel_id;
|
||||
|
||||
if (!skip && retentionPeriod && (Date.now() - post.create_at) / (1000 * 3600 * 24) > retentionPeriod) {
|
||||
if (retentionPeriod && post.create_at < retentionPeriod) {
|
||||
const postsInChannel = nextEntitites.posts.postsInChannel[post.channel_id] || [];
|
||||
const index = postsInChannel.indexOf(postId);
|
||||
if (index !== -1) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
{
|
||||
"DefaultServerUrl": "",
|
||||
"EnableMessageRetention": false,
|
||||
"MessageRetentionPeriod": 30,
|
||||
"TestServerUrl": "http://localhost:8065",
|
||||
"DefaultTheme": "default",
|
||||
"ShowErrorsList": false,
|
||||
|
|
|
|||
Loading…
Reference in a new issue