[MM-62066] Allow using plugin settings defined in manifest as fallback when using custom sections and plugin is disabled (#29500)
* Allow using plugin settings defined in manifest as fallback when using custom sections and plugin is disabled * Update server/public/model/manifest.go Co-authored-by: Christopher Poile <cpoile@gmail.com> * Add custom setting case --------- Co-authored-by: Christopher Poile <cpoile@gmail.com> Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e1a582395f
Коммит
086e6d9df6
@@ -116,6 +116,9 @@ type PluginSettingsSection struct {
|
||||
|
||||
// If true, the section will load the custom component registered using `registry.registerAdminConsoleCustomSection`
|
||||
Custom bool `json:"custom" yaml:"custom"`
|
||||
|
||||
// If true and Custom = true, the settings defined under this section will still render as fallback (unless the individual setting is type 'custom') when the plugin is disabled.
|
||||
Fallback bool `json:"fallback" yaml:"fallback"`
|
||||
}
|
||||
|
||||
type PluginSettingsSchema struct {
|
||||
|
||||
@@ -95,6 +95,18 @@ func TestIsValid(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Key: "section3",
|
||||
Custom: true,
|
||||
Fallback: true,
|
||||
Settings: []*PluginSetting{
|
||||
{
|
||||
Key: "section3setting1",
|
||||
DisplayName: "thedisplayname",
|
||||
Type: "custom",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, false},
|
||||
|
||||
@@ -167,6 +167,89 @@ describe('custom plugin sections and settings', () => {
|
||||
expect(screen.queryByText('Custom Section 2')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('all custom sections with plugin disabled and fallback enabled should render available settings', () => {
|
||||
const state = {
|
||||
...baseState,
|
||||
entities: {
|
||||
admin: {
|
||||
plugins: {
|
||||
testplugin: {
|
||||
...plugin,
|
||||
settings_schema: {
|
||||
...plugin.settings_schema,
|
||||
sections: [
|
||||
{
|
||||
key: 'section1',
|
||||
title: 'Custom Section 1',
|
||||
settings: [
|
||||
{
|
||||
key: 'customsection1numbersetting',
|
||||
label: 'Custom Section Number Setting',
|
||||
type: 'number' as const,
|
||||
help_text: 'Custom Section Number Setting Help Text',
|
||||
},
|
||||
],
|
||||
custom: true,
|
||||
fallback: true,
|
||||
},
|
||||
{
|
||||
key: 'section2',
|
||||
title: 'Custom Section 2',
|
||||
settings: [
|
||||
{
|
||||
key: 'customsection2numbersetting',
|
||||
label: 'Custom Section Bool Setting',
|
||||
type: 'bool' as const,
|
||||
help_text: 'Custom Section Bool Setting Help Text',
|
||||
},
|
||||
{
|
||||
key: 'customsection2customsetting',
|
||||
label: 'Custom Section Custom Setting',
|
||||
type: 'custom' as const,
|
||||
help_text: 'Custom Section Custom Setting Help Text',
|
||||
},
|
||||
],
|
||||
custom: true,
|
||||
fallback: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const props = {
|
||||
...baseProps,
|
||||
config: {
|
||||
...baseProps.config,
|
||||
PluginStates: {
|
||||
testplugin: {
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
renderWithContext(
|
||||
<CustomPluginSettings
|
||||
{...props}
|
||||
patchConfig={jest.fn()}
|
||||
/>
|
||||
, {...state});
|
||||
|
||||
expect(screen.getByText('testplugin')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('PluginSettings.PluginStates.testplugin.Enable')).toBeInTheDocument();
|
||||
expect(screen.queryByText('In order to view and configure plugin settings, enable the plugin and click Save.')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Custom Section 1')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Custom Section 2')).toBeInTheDocument();
|
||||
expect(screen.getByText('Custom Section Number Setting Help Text')).toBeInTheDocument();
|
||||
expect(screen.getByText('Custom Section Bool Setting Help Text')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Custom Section Custom Setting Help Text')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('In order to view this setting, enable the plugin and click Save.')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('custom sections with plugin enabled should render as expected', () => {
|
||||
const CustomSection1 = () => {
|
||||
return (
|
||||
|
||||
@@ -95,8 +95,10 @@ function makeGetPluginSchema() {
|
||||
if (customSections[key]) {
|
||||
component = customSections[key]?.component;
|
||||
settings = parsePluginSettings(section.settings);
|
||||
} else if (section.fallback) {
|
||||
settings = parsePluginSettings(section.settings);
|
||||
} else {
|
||||
// Show warning banner for custom sections when the plugin is disabled.
|
||||
// Show warning banner for custom sections when the plugin is disabled and there's no fallback.
|
||||
settings = [{
|
||||
key: key + 'disabledWarning',
|
||||
type: Constants.SettingsTypes.TYPE_BANNER,
|
||||
@@ -134,8 +136,11 @@ function makeGetPluginSchema() {
|
||||
if (plugin.id !== appsPluginID || appsFeatureFlagIsEnabled) {
|
||||
const pluginEnableSetting = getEnablePluginSetting(plugin) as AdminDefinitionSetting;
|
||||
|
||||
if (plugin.settings_schema && plugin.settings_schema.sections?.every((s) => s.custom && !customSections[s.key.toLowerCase()])) {
|
||||
// If the plugin is composed of purely custom sections (e.g. Calls) and it's disabled (custom components are not found), we show a single warning.
|
||||
const hasAllCustomSectionsDisabled = plugin.settings_schema?.sections?.every((s) => s.custom && !customSections[s.key.toLowerCase()]);
|
||||
const allCustomSectionsAllowFallback = plugin.settings_schema?.sections?.every((s) => s.custom && s.fallback);
|
||||
|
||||
if (plugin.settings_schema && hasAllCustomSectionsDisabled && !allCustomSectionsAllowFallback) {
|
||||
// If the plugin is composed of purely custom sections (e.g. Calls), it's disabled (custom components are not found), and they don't allow a fallback, we show a single warning.
|
||||
const warningBanner = {
|
||||
key: 'admin.plugin.customSections.pluginDisabledWarning',
|
||||
type: Constants.SettingsTypes.TYPE_BANNER,
|
||||
|
||||
@@ -55,6 +55,7 @@ export type PluginSettingSection = {
|
||||
header?: string;
|
||||
footer?: string;
|
||||
custom?: boolean;
|
||||
fallback?: boolean;
|
||||
};
|
||||
|
||||
export type PluginSetting = {
|
||||
|
||||
Ссылка в новой задаче
Block a user