Skip to content

Commit

Permalink
generated texts from the plugin settings and passed the same to gener… (
Browse files Browse the repository at this point in the history
mattermost#3619)

* generated texts from the plugin settings and passed the same to generate index

* show the plugin section in the sidebar when its filtered by the search

* refreshed plugin cache on new plugin or admin definition

* removed the unnecessary code

* changed to strict not equals

* fixed lint issues

* fix review comments

* fix review comments, changed the method signature.

* fix lint error

* ignored the markdown link text using strip markdown util

* test label field text extraction

* removed stripmarkdown from label and display_name. added stripmarkdown to header and footer

* changed the require to import for consistency

* added the enable plugin setting by default

* renamed EnablePluginSrtting to snake case

* index the enable plugin setting by default

* updated snapshot after merge
  • Loading branch information
pradeepmurugesan authored and jespino committed Nov 2, 2019
1 parent 949fb24 commit 8d18a02
Show file tree
Hide file tree
Showing 11 changed files with 1,202 additions and 26 deletions.

Large diffs are not rendered by default.

29 changes: 21 additions & 8 deletions components/admin_console/admin_sidebar/admin_sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React from 'react';
import {FormattedMessage, intlShape} from 'react-intl';
import {Tooltip, OverlayTrigger} from 'react-bootstrap';
import Scrollbars from 'react-custom-scrollbars';
import isEqual from 'lodash/isEqual';

import * as Utils from 'utils/utils.jsx';
import Constants from 'utils/constants';
Expand Down Expand Up @@ -90,6 +91,14 @@ export default class AdminSidebar extends React.Component {
this.updateTitle();
}

componentDidUpdate(prevProps) {
if (this.idx !== null &&
(!isEqual(this.props.plugins, prevProps.plugins) ||
!isEqual(this.props.adminDefinition, prevProps.adminDefinition))) {
this.idx = generateIndex(this.props.adminDefinition, this.props.plugins, this.context.intl);
}
}

onFilterChange = (e) => {
const filter = e.target.value;
if (filter === '') {
Expand All @@ -99,7 +108,7 @@ export default class AdminSidebar extends React.Component {
}

if (this.idx === null) {
this.idx = generateIndex(this.props.adminDefinition, this.context.intl);
this.idx = generateIndex(this.props.adminDefinition, this.props.plugins, this.context.intl);
}
let query = '';
for (const term of filter.split(' ')) {
Expand Down Expand Up @@ -203,18 +212,18 @@ export default class AdminSidebar extends React.Component {
));
});

// If no visible items, don't display this section
if (sidebarItems.length === 0) {
return null;
}

// Special case for plugins entries
let moreSidebarItems;
let moreSidebarItems = [];
if (section.id === 'plugins') {
moreSidebarItems = this.renderPluginsMenu();
}

if (sidebarItems.length) {
// If no visible items, don't display this section
if (sidebarItems.length === 0 && moreSidebarItems.length === 0) {
return null;
}

if (sidebarItems.length || moreSidebarItems.length) {
sidebarSections.push((
<AdminSidebarCategory
key={sectionIndex}
Expand Down Expand Up @@ -262,6 +271,9 @@ export default class AdminSidebar extends React.Component {
}
}

if (this.state.sections !== null && this.state.sections.indexOf(`plugin_${p.id}`) === -1) {
return;
}
customPlugins.push(
<AdminSidebarSection
key={'customplugin' + p.id}
Expand Down Expand Up @@ -315,6 +327,7 @@ export default class AdminSidebar extends React.Component {
value={this.state.filter}
placeholder={Utils.localizeMessage('admin.sidebar.filter', 'Find settings')}
ref={this.searchRef}
id='adminSidebarFilter'
/>
{this.state.filter &&
<div
Expand Down
147 changes: 146 additions & 1 deletion components/admin_console/admin_sidebar/admin_sidebar.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import React from 'react';
import {IntlProvider} from 'react-intl';
import {shallow} from 'enzyme';

import enMessages from 'i18n/en.json';

import {samplePlugin1} from 'tests/helpers/admin_console_plugin_index_sample_pluings';

import AdminSidebar from 'components/admin_console/admin_sidebar/admin_sidebar.jsx';
import AdminDefinition from 'components/admin_console/admin_definition';
import {generateIndex} from 'utils/admin_console_index';

jest.mock('utils/utils', () => {
const original = require.requireActual('utils/utils');
Expand All @@ -16,8 +21,10 @@ jest.mock('utils/utils', () => {
};
});

jest.mock('utils/admin_console_index');

describe('components/AdminSidebar', () => {
const intlProvider = new IntlProvider({locale: 'en', defaultLocale: 'en'}, {});
const intlProvider = new IntlProvider({locale: 'en', messages: enMessages, defaultLocale: 'en'}, {});
const {intl} = intlProvider.getChildContext();
const defaultProps = {
license: {},
Expand Down Expand Up @@ -240,4 +247,142 @@ describe('components/AdminSidebar', () => {
const wrapper = shallow(<AdminSidebar {...props}/>, {context});
expect(wrapper).toMatchSnapshot();
});

describe('generateIndex', () => {
const props = {
license: {},
config: {
ServiceSettings: {
ExperimentalLdapGroupSync: true,
},
ExperimentalSettings: {
RestrictSystemAdmin: false,
},
PluginSettings: {
Enable: true,
EnableUploads: true,
},
},
adminDefinition: AdminDefinition,
buildEnterpriseReady: true,
navigationBlocked: false,
siteName: 'test snap',
plugins: {
'mattermost-autolink': samplePlugin1,
},
onFilterChange: jest.fn(),
actions: {
getPlugins: jest.fn(),
},
};

beforeEach(() => {
generateIndex.mockReset();
});

test('should refresh the index in case idx is already present and there is a change in plugins or adminDefinition prop', () => {
generateIndex.mockReturnValue(['mocked-index']);
const context = {router: {}, intl};
const wrapper = shallow(<AdminSidebar {...props}/>, {context, lifecycleExperimental: true});
wrapper.instance().idx = ['some value'];

expect(generateIndex).toHaveBeenCalledTimes(0);

wrapper.setProps({plugins: {}});
expect(generateIndex).toHaveBeenCalledTimes(1);

wrapper.setProps({adminDefinition: {}});
expect(generateIndex).toHaveBeenCalledTimes(2);
});

test('should not call the generate index in case of idx is not already present', () => {
generateIndex.mockReturnValue(['mocked-index']);
const context = {router: {}, intl};
const wrapper = shallow(<AdminSidebar {...props}/>, {context, lifecycleExperimental: true});

expect(generateIndex).toHaveBeenCalledTimes(0);

wrapper.setProps({plugins: {}});
expect(generateIndex).toHaveBeenCalledTimes(0);

wrapper.setProps({adminDefinition: {}});
expect(generateIndex).toHaveBeenCalledTimes(0);
});

test('should not generate index in case of same props', () => {
generateIndex.mockReturnValue(['mocked-index']);
const context = {router: {}, intl};
const wrapper = shallow(<AdminSidebar {...props}/>, {context, lifecycleExperimental: true});
wrapper.instance().idx = ['some value'];

expect(generateIndex).toHaveBeenCalledTimes(0);

wrapper.setProps({plugins: {
'mattermost-autolink': samplePlugin1,
}});
expect(generateIndex).toHaveBeenCalledTimes(0);

wrapper.setProps({adminDefinition: AdminDefinition});
expect(generateIndex).toHaveBeenCalledTimes(0);
});
});

describe('Plugins', () => {
const idx = {search: jest.fn()};

beforeEach(() => {
idx.search.mockReset();
generateIndex.mockReturnValue(idx);
});

const props = {
license: {},
config: {
ServiceSettings: {
ExperimentalLdapGroupSync: true,
},
ExperimentalSettings: {
RestrictSystemAdmin: false,
},
PluginSettings: {
Enable: true,
EnableUploads: true,
},
},
adminDefinition: AdminDefinition,
buildEnterpriseReady: true,
navigationBlocked: false,
siteName: 'test snap',
plugins: {
'mattermost-autolink': samplePlugin1,
},
onFilterChange: jest.fn(),
actions: {
getPlugins: jest.fn(),
},
};

test('should match snapshot', () => {
const context = {router: {}, intl};

const wrapper = shallow(<AdminSidebar {...props}/>, {context});

expect(wrapper).toMatchSnapshot();
});

test('should filter plugins', () => {
const context = {router: {}, intl};
const wrapper = shallow(<AdminSidebar {...props}/>, {context});

idx.search.mockReturnValue(['plugin_mattermost-autolink']);
wrapper.find('#adminSidebarFilter').simulate('change', {target: {value: 'autolink'}});

expect(wrapper.instance().state.sections).toEqual(['plugin_mattermost-autolink']);
expect(wrapper).toMatchSnapshot();
expect(wrapper.find('AdminSidebarCategory')).toHaveLength(1);
expect(wrapper.find('AdminSidebarSection')).toHaveLength(1);
const autoLinkPluginSection = wrapper.find('AdminSidebarSection').at(0);
expect(autoLinkPluginSection.prop('name')).toBe('plugins/plugin_mattermost-autolink');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Constants} from '../../../utils/constants';
import {t} from '../../../utils/i18n';
import SchemaAdminSettings from '../schema_admin_settings';

export default function getEnablePluginSetting(plugin) {
const escapedPluginId = SchemaAdminSettings.escapePathPart(plugin.id);
const pluginEnabledConfigKey = 'PluginSettings.PluginStates.' + escapedPluginId + '.Enable';

return {
type: Constants.SettingsTypes.TYPE_BOOL,
key: pluginEnabledConfigKey,
label: t('admin.plugin.enable_plugin'),
label_default: 'Enable Plugin: ',
help_text: t('admin.plugin.enable_plugin.help'),
help_text_default: 'When true, this plugin is enabled.',
};
}
12 changes: 2 additions & 10 deletions components/admin_console/custom_plugin_settings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import {createSelector} from 'reselect';

import {getRoles} from 'mattermost-redux/selectors/entities/roles';

import {Constants} from 'utils/constants';
import {t} from 'utils/i18n';
import SchemaAdminSettings from '../schema_admin_settings';
import {it} from '../admin_definition';

import CustomPluginSettings from './custom_plugin_settings.jsx';
import getEnablePluginSetting from './enable_plugin_setting';

function makeGetPluginSchema() {
return createSelector(
Expand All @@ -38,14 +37,7 @@ function makeGetPluginSchema() {
});
}

settings.unshift({
type: Constants.SettingsTypes.TYPE_BOOL,
key: pluginEnabledConfigKey,
label: t('admin.plugin.enable_plugin'),
label_default: 'Enable Plugin: ',
help_text: t('admin.plugin.enable_plugin.help'),
help_text_default: 'When true, this plugin is enabled.',
});
settings.unshift(getEnablePluginSetting(plugin));

return {
...plugin.settings_schema,
Expand Down
73 changes: 73 additions & 0 deletions tests/helpers/admin_console_plugin_index_sample_pluings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export const samplePlugin1 = {
id: 'mattermost-autolink',
name: 'Autolink',
description: 'Automatically rewrite text matching a regular expression into a Markdown link.',
version: '1.1.0',
settings_schema: {
header: 'Configure this plugin directly in the config.json file. Learn more [in our documentation](https://github.com/mattermost/mattermost-plugin-autolink/blob/master/README.md).\n\nTo report an issue, make a suggestion or a contribution, [check the plugin repository](https://github.com/mattermost/mattermost-plugin-autolink).',
footer: '',
settings: [
{
key: 'EnableAdminCommand',
display_name: 'Enable administration with /autolink command',
type: 'bool',
help_text: '',
placeholder: '',
default: false,
},
],
},
active: true,
};

export const samplePlugin2 = {
id: 'Some-random-plugin',
name: 'Random',
description: 'Automatically generate random numbers',
version: '1.1.0',
settings_schema: {
footer: 'random plugin footer',
settings: [
{
key: 'GenerateRandomNumber',
display_name: 'Generate with /generateRand command',
type: 'bool',
help_text: '/generateRand 10',
placeholder: '',
default: false,
},
{
key: 'setRange',
display_name: 'set range with /setRange command',
type: 'bool',
help_text: '',
placeholder: '',
default: false,
},
],
},
active: true,
};

export const samplePlugin3 = {
id: 'plugin-with-markdown',
name: 'markdown',
description: 'click [here](http:https://localhost:8080)',
version: '1.1.0',
settings_schema: {
settings: [
{
label: 'Markdown plugin label',
key: 'Markdown plugin',
display_name: 'Markdown',
type: 'bool',
help_text: 'click [here](http:https://localhost:8080)',
placeholder: '',
default: false,
},
],
},
active: true,
};
Loading

0 comments on commit 8d18a02

Please sign in to comment.