update console feature support checks (#2202)

This commit is contained in:
Rikin Kachhia 2019-05-28 13:41:08 +05:30 committed by GitHub
parent 0957a43563
commit f65a2b59b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 125 deletions

View File

@ -10,7 +10,7 @@ import {
ADMIN_SECRET_ERROR,
UPDATE_DATA_HEADERS,
} from '../Services/Data/DataActions';
import semverCheck, { componentsSemver } from '../../helpers/semver';
import { getFeaturesCompatibility } from '../../helpers/versionUtils';
import { changeRequestHeader } from '../Services/ApiExplorer/Actions';
const SET_MIGRATION_STATUS_SUCCESS = 'Main/SET_MIGRATION_STATUS_SUCCESS';
@ -31,23 +31,22 @@ const UPDATE_ADMIN_SECRET_INPUT = 'Main/UPDATE_ADMIN_SECRET_INPUT';
const LOGIN_IN_PROGRESS = 'Main/LOGIN_IN_PROGRESS';
const LOGIN_ERROR = 'Main/LOGIN_ERROR';
const SET_SEMVER = 'Main/SET_SEMVER';
const setSemverBulk = data => ({
type: SET_SEMVER,
const SET_FEATURES_COMPATIBILITY = 'Main/SET_FEATURES_COMPATIBILITY';
const setFeaturesCompatibility = data => ({
type: SET_FEATURES_COMPATIBILITY,
data,
});
const semverInit = () => {
const featureCompatibilityInit = () => {
return (dispatch, getState) => {
const { serverVersion } = getState().main;
if (!serverVersion) {
return;
}
const semverObj = {};
Object.keys(componentsSemver).forEach(feature => {
semverObj[feature] = semverCheck(feature, serverVersion);
});
return dispatch(setSemverBulk(semverObj));
const featuresCompatibility = getFeaturesCompatibility(serverVersion);
return dispatch(setFeaturesCompatibility(featuresCompatibility));
};
};
@ -95,7 +94,7 @@ const loadServerVersion = () => dispatch => {
);
};
const checkServerUpdates = () => (dispatch, getState) => {
const loadLatestServerVersion = () => (dispatch, getState) => {
const url =
Endpoints.updateCheck +
'?agent=console&version=' +
@ -305,10 +304,10 @@ const mainReducer = (state = defaultState, action) => {
return { ...state, loginInProgress: action.data };
case LOGIN_ERROR:
return { ...state, loginError: action.data };
case SET_SEMVER:
case SET_FEATURES_COMPATIBILITY:
return {
...state,
semver: { ...action.data },
featuresCompatibility: { ...action.data },
};
default:
return state;
@ -328,6 +327,6 @@ export {
LOGIN_ERROR,
validateLogin,
loadServerVersion,
checkServerUpdates,
semverInit,
loadLatestServerVersion,
featureCompatibilityInit,
};

View File

@ -6,7 +6,11 @@ import globals from '../../Globals';
import * as tooltip from './Tooltips';
import 'react-toggle/style.css';
import Spinner from '../Common/Spinner/Spinner';
import { loadServerVersion, checkServerUpdates, semverInit } from './Actions';
import {
loadServerVersion,
loadLatestServerVersion,
featureCompatibilityInit,
} from './Actions';
import { loadConsoleOpts } from '../../telemetry/Actions.js';
import './NotificationOverrides.css';
import {
@ -14,21 +18,22 @@ import {
redirectToMetadataStatus,
} from '../Services/Metadata/Actions';
const semver = require('semver');
import {
getLoveConsentState,
setLoveConsentState,
} from './loveConsentLocalStorage';
import { versionGT } from '../../helpers/versionUtils';
class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
showBannerNotification: false,
showUpdateNotification: false,
loveConsentState: getLoveConsentState(),
};
this.state.loveConsentState = getLoveConsentState();
this.handleBodyClick = this.handleBodyClick.bind(this);
}
@ -40,7 +45,7 @@ class Main extends React.Component {
.addEventListener('click', this.handleBodyClick);
dispatch(loadServerVersion()).then(() => {
dispatch(semverInit());
dispatch(featureCompatibilityInit());
dispatch(loadInconsistentObjects()).then(() => {
this.handleMetadataRedirect();
@ -48,23 +53,23 @@ class Main extends React.Component {
dispatch(loadConsoleOpts());
dispatch(checkServerUpdates()).then(() => {
let isUpdateAvailable = false;
dispatch(loadLatestServerVersion()).then(() => {
try {
isUpdateAvailable = semver.gt(
this.props.latestServerVersion,
this.props.serverVersion
);
const isClosedBefore = window.localStorage.getItem(
this.props.latestServerVersion + '_BANNER_NOTIFICATION_CLOSED'
);
if (isClosedBefore === 'true') {
isUpdateAvailable = false;
this.setState({ showBannerNotification: false });
} else {
this.setState({
showBannerNotification: isUpdateAvailable,
});
if (isClosedBefore !== 'true') {
const isUpdateAvailable = versionGT(
this.props.latestServerVersion,
this.props.serverVersion
);
if (isUpdateAvailable) {
this.setState({
showUpdateNotification: true,
});
}
}
} catch (e) {
console.error(e);
@ -111,7 +116,7 @@ class Main extends React.Component {
latestServerVersion + '_BANNER_NOTIFICATION_CLOSED',
'true'
);
this.setState({ showBannerNotification: false });
this.setState({ showUpdateNotification: false });
}
render() {
@ -207,11 +212,11 @@ class Main extends React.Component {
return adminSecretHtml;
};
const getBannerNotification = () => {
let bannerNotificationHtml = null;
const getUpdateNotification = () => {
let updateNotificationHtml = null;
if (this.state.showBannerNotification) {
bannerNotificationHtml = (
if (this.state.showUpdateNotification) {
updateNotificationHtml = (
<div>
<div className={styles.phantom} />{' '}
{/* phantom div to prevent overlapping of banner with content. */}
@ -254,7 +259,7 @@ class Main extends React.Component {
</div>
);
}
return bannerNotificationHtml;
return updateNotificationHtml;
};
const getLoveSection = () => {
@ -587,7 +592,7 @@ class Main extends React.Component {
{getMainContent()}
</div>
{getBannerNotification()}
{getUpdateNotification()}
</div>
</div>
);

View File

@ -10,6 +10,7 @@ const defaultState = {
serverVersion: null,
latestServerVersion: null,
telemetryEnabled: true,
featuresCompatibility: {},
};
export default defaultState;

View File

@ -1,84 +0,0 @@
const semver = require('semver');
// list of feature launch versions
const componentsSemver = {
// feature: '1.0.1'
};
const getPreRelease = version => {
const prerelease = semver.prerelease(version);
if (!prerelease) {
return '';
}
// TODO: fix beta parsing
if (prerelease.length === 1) {
const regex = /(alpha|beta)(\d+)/gm;
const str = prerelease[0];
const m = regex.exec(str);
if (m.length < 3) {
return '';
}
return m.slice(1, 3);
}
return prerelease.slice(0, 2);
};
const semverCheck = (component, serverVersion) => {
if (component in componentsSemver) {
const componentCoerce = semver.valid(componentsSemver[component]);
if (componentCoerce == null) {
return false;
}
const serverCoerce = semver.valid(serverVersion);
if (serverCoerce == null) {
return true;
}
switch (semver.compare(serverCoerce, componentCoerce)) {
case 0:
// check for prerelease tags
const componentPrerelease = getPreRelease(componentsSemver[component]);
const serverPrerelease = getPreRelease(serverVersion);
// If both component and server doesn't have a prerelease, return true
if (componentPrerelease.length === 0 && serverPrerelease.length === 0) {
return true;
}
// If component does't have a prerelease tag and server has a p rerelease
// tag, return false
if (componentPrerelease.length === 0 && serverPrerelease.length !== 0) {
return false;
}
// If server does't have a prerelease tag and component has a prerelease
// tag, return true
if (componentPrerelease.length !== 0 && serverPrerelease.length === 0) {
return true;
}
if (
componentPrerelease[0] === 'beta' &&
serverPrerelease[0] !== 'beta'
) {
return false;
}
if (
parseInt(serverPrerelease[1], 10) >=
parseInt(componentPrerelease[1], 10)
) {
return true;
}
return false;
case 1:
return true;
case -1:
return false;
default:
return false;
}
}
return false;
};
export { componentsSemver };
export default semverCheck;

View File

@ -0,0 +1,32 @@
const semver = require('semver');
// list of feature launch versions
const featureLaunchVersions = {
// feature: 'v1.0.0'
};
export const getFeaturesCompatibility = serverVersion => {
const featuresCompatibility = {};
const isPullRequest = serverVersion.startsWith('pull');
try {
Object.keys(featureLaunchVersions).forEach(feature => {
featuresCompatibility[feature] =
isPullRequest ||
semver.satisfies(featureLaunchVersions[feature], '>=' + serverVersion);
});
} catch (e) {
console.error(e);
}
return featuresCompatibility;
};
export const versionGT = (version1, version2) => {
try {
return semver.gt(version1, version2);
} catch (e) {
console.error(e);
}
};