PLT-1125: allow to toggle features in frontend
Этот коммит содержится в:
6
config/pre_release_features.json
Обычный файл
6
config/pre_release_features.json
Обычный файл
@@ -0,0 +1,6 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"label": "#1389",
|
||||||
|
"description": "Show markdown preview option in message input box"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -13,21 +13,38 @@ export default class AdvancedSettingsDisplay extends React.Component {
|
|||||||
|
|
||||||
this.updateSection = this.updateSection.bind(this);
|
this.updateSection = this.updateSection.bind(this);
|
||||||
this.updateSetting = this.updateSetting.bind(this);
|
this.updateSetting = this.updateSetting.bind(this);
|
||||||
|
this.toggleFeature = this.toggleFeature.bind(this);
|
||||||
|
this.saveEnabledFeatures = this.saveEnabledFeatures.bind(this);
|
||||||
this.setupInitialState = this.setupInitialState.bind(this);
|
this.setupInitialState = this.setupInitialState.bind(this);
|
||||||
|
|
||||||
this.state = this.setupInitialState();
|
this.state = {settings: {}, preReleaseFeatures: []};
|
||||||
|
this.setupInitialState();
|
||||||
}
|
}
|
||||||
|
|
||||||
setupInitialState() {
|
setupInitialState() {
|
||||||
const sendOnCtrlEnter = PreferenceStore.getPreference(
|
const settings = {
|
||||||
Constants.Preferences.CATEGORY_ADVANCED_SETTINGS,
|
send_on_ctrl_enter: PreferenceStore.getPreference(
|
||||||
'send_on_ctrl_enter',
|
Constants.Preferences.CATEGORY_ADVANCED_SETTINGS,
|
||||||
{value: 'false'}
|
'send_on_ctrl_enter',
|
||||||
).value;
|
{value: 'false'}
|
||||||
|
).value
|
||||||
return {
|
|
||||||
settings: {send_on_ctrl_enter: sendOnCtrlEnter}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let enabledFeatures = 0;
|
||||||
|
PreferenceStore.getPreferences(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS).forEach((setting) => {
|
||||||
|
if (setting.name.lastIndexOf('feature_enabled_') === 0) {
|
||||||
|
settings[setting.name] = setting.value;
|
||||||
|
if (setting.value === 'true') {
|
||||||
|
enabledFeatures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Client.getAvailablePreReleaseFeatures((data) => {
|
||||||
|
this.setState({settings, preReleaseFeatures: data || [], enabledFeatures});
|
||||||
|
}, () => {
|
||||||
|
this.setState({settings, preReleaseFeatures: [], enabledFeatures});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSetting(setting, value) {
|
updateSetting(setting, value) {
|
||||||
@@ -36,14 +53,45 @@ export default class AdvancedSettingsDisplay extends React.Component {
|
|||||||
this.setState(settings);
|
this.setState(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit(setting) {
|
toggleFeature(feature, checked) {
|
||||||
const preference = PreferenceStore.setPreference(
|
const settings = this.state.settings;
|
||||||
Constants.Preferences.CATEGORY_ADVANCED_SETTINGS,
|
settings['feature_enabled_' + feature] = String(checked);
|
||||||
setting,
|
|
||||||
this.state.settings[setting]
|
|
||||||
);
|
|
||||||
|
|
||||||
Client.savePreferences([preference],
|
let enabledFeatures = 0;
|
||||||
|
Object.keys(this.state.settings).forEach((setting) => {
|
||||||
|
if (setting.lastIndexOf('feature_enabled_') === 0 && this.state.settings[setting] === 'true') {
|
||||||
|
enabledFeatures++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({settings, enabledFeatures});
|
||||||
|
}
|
||||||
|
|
||||||
|
saveEnabledFeatures() {
|
||||||
|
const features = [];
|
||||||
|
Object.keys(this.state.settings).forEach((setting) => {
|
||||||
|
if (setting.lastIndexOf('feature_enabled_') === 0) {
|
||||||
|
features.push(setting);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.handleSubmit(features);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit(settings) {
|
||||||
|
const preferences = [];
|
||||||
|
|
||||||
|
(Array.isArray(settings) ? settings : [settings]).forEach((setting) => {
|
||||||
|
preferences.push(
|
||||||
|
PreferenceStore.setPreference(
|
||||||
|
Constants.Preferences.CATEGORY_ADVANCED_SETTINGS,
|
||||||
|
setting,
|
||||||
|
String(this.state.settings[setting])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Client.savePreferences(preferences,
|
||||||
() => {
|
() => {
|
||||||
PreferenceStore.emitChange();
|
PreferenceStore.emitChange();
|
||||||
this.updateSection('');
|
this.updateSection('');
|
||||||
@@ -118,6 +166,58 @@ export default class AdvancedSettingsDisplay extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previewFeaturesSection;
|
||||||
|
if (this.props.activeSection === 'advancedPreviewFeatures') {
|
||||||
|
const inputs = [];
|
||||||
|
|
||||||
|
this.state.preReleaseFeatures.forEach((feature) => {
|
||||||
|
inputs.push(
|
||||||
|
<div key={'advancedPreviewFeatures_' + feature.label}>
|
||||||
|
<div className='checkbox'>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type='checkbox'
|
||||||
|
checked={this.state.settings['feature_enabled_' + feature.label] === 'true'}
|
||||||
|
onChange={(e) => {
|
||||||
|
this.toggleFeature(feature.label, e.target.checked);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{feature.description}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
inputs.push(
|
||||||
|
<div key='advancedPreviewFeatures_helptext'>
|
||||||
|
<br/>
|
||||||
|
{'Check any pre-released features you\'d like to preview.'}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
previewFeaturesSection = (
|
||||||
|
<SettingItemMax
|
||||||
|
title='Preview pre-release features'
|
||||||
|
inputs={inputs}
|
||||||
|
submit={this.saveEnabledFeatures}
|
||||||
|
server_error={serverError}
|
||||||
|
updateSection={(e) => {
|
||||||
|
this.updateSection('');
|
||||||
|
e.preventDefault();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
previewFeaturesSection = (
|
||||||
|
<SettingItemMin
|
||||||
|
title='Preview pre-release features'
|
||||||
|
describe={this.state.enabledFeatures + (this.state.enabledFeatures === 1 ? ' Feature ' : ' Features ') + 'enabled'}
|
||||||
|
updateSection={() => this.props.updateSection('advancedPreviewFeatures')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='modal-header'>
|
<div className='modal-header'>
|
||||||
@@ -145,6 +245,8 @@ export default class AdvancedSettingsDisplay extends React.Component {
|
|||||||
<h3 className='tab-header'>{'Advanced Settings'}</h3>
|
<h3 className='tab-header'>{'Advanced Settings'}</h3>
|
||||||
<div className='divider-dark first'/>
|
<div className='divider-dark first'/>
|
||||||
{ctrlSendSection}
|
{ctrlSendSection}
|
||||||
|
<div className='divider-light'/>
|
||||||
|
{previewFeaturesSection}
|
||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1320,3 +1320,16 @@ export function regenOutgoingHookToken(data, success, error) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAvailablePreReleaseFeatures(success, error) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/static/config/pre_release_features.json',
|
||||||
|
dataType: 'json',
|
||||||
|
type: 'GET',
|
||||||
|
success,
|
||||||
|
error: (xhr, status, err) => {
|
||||||
|
var e = handleError('getAvailablePreReleaseFeatures', xhr, status, err);
|
||||||
|
error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1221,3 +1221,7 @@ export function getPostTerm(post) {
|
|||||||
|
|
||||||
return postTerm;
|
return postTerm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function featureToggle(feature) {
|
||||||
|
return PreferenceStore.getPreference(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'feature_enabled_' + feature, {value: 'false'}).value === 'true';
|
||||||
|
}
|
||||||
|
|||||||
1
web/static/config/pre_release_features.json
Символическая ссылка
1
web/static/config/pre_release_features.json
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
../../../config/pre_release_features.json
|
||||||
Ссылка в новой задаче
Block a user