Revert "Migrating the admin_definition.jsx file to typescript (#24658)" (#24869)

This reverts commit a1bf8504a8.
Этот коммит содержится в:
Jesús Espino
2023-10-10 22:33:24 +02:00
коммит произвёл GitHub
родитель 88954c651a
Коммит 6274faeda8
18 изменённых файлов: 7470 добавлений и 7331 удалений

Просмотреть файл

@@ -178,7 +178,8 @@
"stylelint-scss": "3.19.0",
"webpack-bundle-analyzer": "4.7.0",
"webpack-pwa-manifest": "4.3.0",
"yargs": "16.2.0"
"yargs": "16.2.0",
"yup": "0.32.11"
},
"scripts": {
"check": "eslint --ext .js,.jsx,.tsx,.ts ./src --quiet --cache && stylelint \"**/*.{css,scss}\" --cache",

Просмотреть файл

@@ -4,8 +4,8 @@
import React from 'react';
import {Route, Switch, Redirect} from 'react-router-dom';
import type {CloudState} from '@mattermost/types/cloud';
import type {AdminConfig, EnvironmentConfig} from '@mattermost/types/config';
import type {CloudState, Product} from '@mattermost/types/cloud';
import type {AdminConfig, EnvironmentConfig, ClientLicense} from '@mattermost/types/config';
import type {Role} from '@mattermost/types/roles';
import type {DeepPartial} from '@mattermost/types/utilities';
@@ -26,7 +26,6 @@ import {LhsItemType} from 'types/store/lhs';
import AdminSidebar from './admin_sidebar';
import Highlight from './highlight';
import type {AdminDefinitionSubSection, AdminDefinitionSection} from './types';
import type {PropsFromRedux} from './index';
@@ -53,6 +52,22 @@ type ExtraProps = {
isCurrentUserSystemAdmin: boolean;
}
type ConsoleAccess = {
read: Record<string, boolean>;
write: Record<string, boolean>;
}
type Item = {
isHidden?: (config?: Record<string, any>, state?: Record<string, any>, license?: Record<string, any>, buildEnterpriseReady?: boolean, consoleAccess?: ConsoleAccess, cloud?: CloudState, isCurrentUserSystemAdmin?: boolean) => boolean;
isDisabled?: (config?: Record<string, any>, state?: Record<string, any>, license?: Record<string, any>, buildEnterpriseReady?: boolean, consoleAccess?: ConsoleAccess, cloud?: CloudState, isCurrentUserSystemAdmin?: boolean) => boolean;
schema: Record<string, any>;
url: string;
restrictedIndicator?: {
value: (cloud: CloudState) => React.ReactNode;
shouldDisplay: (license: ClientLicense, subscriptionProduct?: Product) => boolean;
};
}
export default class AdminConsole extends React.PureComponent<Props, State> {
public constructor(props: Props) {
super(props);
@@ -101,22 +116,30 @@ export default class AdminConsole extends React.PureComponent<Props, State> {
private renderRoutes = (extraProps: ExtraProps) => {
const {adminDefinition, config, license, buildEnterpriseReady, consoleAccess, cloud, isCurrentUserSystemAdmin} = this.props;
const schemas: AdminDefinitionSubSection[] = Object.values(adminDefinition).flatMap((section: AdminDefinitionSection) => {
const schemas: Item[] = Object.values(adminDefinition).reduce((acc, section) => {
let items: Item[] = [];
let isSectionHidden = false;
if (typeof section.isHidden === 'function') {
isSectionHidden = section.isHidden(config, this.state, license, buildEnterpriseReady, consoleAccess, cloud, isCurrentUserSystemAdmin);
} else {
isSectionHidden = Boolean(section.isHidden);
Object.entries(section).find(([key, value]) => {
if (key === 'isHidden') {
if (typeof value === 'function') {
isSectionHidden = value(config, this.state, license, buildEnterpriseReady, consoleAccess, cloud, isCurrentUserSystemAdmin);
} else {
isSectionHidden = Boolean(value);
}
}
return null;
});
if (!isSectionHidden) {
items = Object.values(section).filter((item: Item) => Boolean(item.schema));
}
if (isSectionHidden) {
return [];
}
return Object.values(section.subsections);
});
return acc.concat(items);
}, [] as Item[]);
let defaultUrl = '';
const schemaRoutes = schemas.map((item: AdminDefinitionSubSection, index: number) => {
const schemaRoutes = schemas.map((item: Item, index: number) => {
if (typeof item.isHidden !== 'undefined') {
const isHidden = (typeof item.isHidden === 'function') ? item.isHidden(config, this.state, license, buildEnterpriseReady, consoleAccess, cloud, isCurrentUserSystemAdmin) : Boolean(item.isHidden);
if (isHidden) {

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@@ -0,0 +1,211 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import * as yup from 'yup';
import adminDefinition from 'components/admin_console/admin_definition.jsx';
import {Constants} from 'utils/constants';
const baseShape = {
label: yup.string().required(),
label_default: yup.string().required(),
needs_no_license: yup.boolean(),
needs_license: yup.boolean(),
needs: yup.array().of(yup.array().of(yup.string())),
needs_or: yup.array().of(yup.array().of(yup.string())),
};
const fieldShape = {
...baseShape,
key: yup.string().required(),
// help_text: yup.string(), // Commented out since this doesn't work when help_text is a ReactNode
help_text_default: yup.string(),
help_text_html: yup.boolean(),
help_text_values: yup.object(),
};
const option = yup.object().shape({
value: yup.string(),
display_name: yup.string().required(),
display_name_default: yup.string().required(),
});
const settingBanner = yup.object().shape({
...baseShape,
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_BANNER]),
banner_type: yup.mixed().oneOf(['info', 'warning']),
});
const settingBool = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_BOOL]),
...fieldShape,
});
const settingNumber = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_NUMBER]),
...fieldShape,
});
const settingColor = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_COLOR]),
...fieldShape,
});
const settingText = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_TEXT]),
...fieldShape,
placeholder: yup.string(),
placeholder_default: yup.string(),
});
const settingButton = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_BUTTON]),
...fieldShape,
action: yup.object(),
error_message: yup.string().required(),
error_message_default: yup.string().required(),
});
const settingLanguage = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_LANGUAGE]),
...fieldShape,
});
const settingMultiLanguage = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_LANGUAGE]),
...fieldShape,
multiple: yup.boolean(),
no_result: yup.string().required(),
no_result_default: yup.string().required(),
not_present: yup.string().required(),
not_present_default: yup.string().required(),
});
const settingDropdown = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_DROPDOWN]),
...fieldShape,
options: yup.array().of(option),
});
const settingCustom = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_CUSTOM]),
...baseShape,
component: yup.object().required(),
});
const settingPermission = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_PERMISSION]),
...fieldShape,
permissions_mapping_name: yup.string().required(),
});
const settingJobsTable = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_JOBSTABLE]),
...baseShape,
job_type: yup.string().required(),
render_job: yup.object().required(),
});
const settingFileUploadButton = yup.object().shape({
type: yup.mixed().oneOf([Constants.SettingsTypes.TYPE_FILE_UPLOAD]),
...fieldShape,
action: yup.object(),
remove_help_text: yup.string().required(),
remove_help_text_default: yup.string().required(),
remove_button_text: yup.string().required(),
remove_button_text_default: yup.string().required(),
removing_text: yup.string().required(),
removing_text_default: yup.string().required(),
uploading_text: yup.string().required(),
uploading_text_default: yup.string().required(),
upload_action: yup.object().required(),
remove_action: yup.object().required(),
fileType: yup.string().required(),
});
// eslint-disable-next-line no-template-curly-in-string
const setting = yup.mixed().test('is-setting', 'not a valid setting: ${path}', (value) => {
let valid = false;
valid = valid || settingBanner.isValidSync(value);
valid = valid || settingBool.isValidSync(value);
valid = valid || settingNumber.isValidSync(value);
valid = valid || settingColor.isValidSync(value);
valid = valid || settingText.isValidSync(value);
valid = valid || settingButton.isValidSync(value);
valid = valid || settingLanguage.isValidSync(value);
valid = valid || settingMultiLanguage.isValidSync(value);
valid = valid || settingDropdown.isValidSync(value);
valid = valid || settingCustom.isValidSync(value);
valid = valid || settingJobsTable.isValidSync(value);
valid = valid || settingPermission.isValidSync(value);
valid = valid || settingFileUploadButton.isValidSync(value);
return valid;
});
var baseSchema = {
id: yup.string().required(),
name: yup.string().required(),
name_default: yup.string().required(),
};
var schema = yup.object(baseSchema).shape({
settings: yup.array().of(setting).required(),
});
var sectionSchema = yup.object(baseSchema).shape({
sections: yup.array().of(schema).required(),
});
var customComponentSchema = yup.object().shape({
id: yup.string().required(),
component: yup.object().required(),
});
var definition = yup.object().shape({
reporting: yup.object().shape({
system_analytics: yup.object().shape({schema: customComponentSchema}),
team_analytics: yup.object().shape({schema: customComponentSchema}),
system_users: yup.object().shape({schema: customComponentSchema}),
server_logs: yup.object().shape({schema: customComponentSchema}),
}),
authentication: yup.object().shape({
email: yup.object().shape({schema}),
ldap: yup.object().shape({sectionSchema}),
mfa: yup.object().shape({schema}),
saml: yup.object().shape({schema}),
}),
settings: yup.object().shape({
general: yup.object().shape({
configuration: yup.object().shape({schema}),
localization: yup.object().shape({schema}),
users_and_teams: yup.object().shape({schema}),
privacy: yup.object().shape({schema}),
compliance: yup.object().shape({schema}),
}),
security: yup.object().shape({}),
notifications: yup.object().shape({}),
integrations: yup.object().shape({
custom: yup.object().shape({schema}),
}),
plugins: yup.object().shape({}),
files: yup.object().shape({}),
customization: yup.object().shape({
announcement: yup.object().shape({schema}),
}),
compliance: yup.object().shape({}),
advanced: yup.object().shape({}),
}),
other: yup.object().shape({
license: yup.object().shape({schema: customComponentSchema}),
audits: yup.object().shape({schema: customComponentSchema}),
}),
});
describe('components/admin_console/admin_definition', () => {
it('should pass all validations checks', () => {
definition.strict().validateSync(adminDefinition);
});
});

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@@ -53,6 +53,7 @@ exports[`components/AdminSidebar Plugins should filter plugins 1`] = `
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -133,6 +134,7 @@ exports[`components/AdminSidebar Plugins should match snapshot 1`] = `
definitionKey="user_management"
icon={
<AccountMultipleOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -200,6 +202,7 @@ exports[`components/AdminSidebar Plugins should match snapshot 1`] = `
definitionKey="site"
icon={
<CogOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -243,6 +246,7 @@ exports[`components/AdminSidebar Plugins should match snapshot 1`] = `
definitionKey="authentication"
icon={
<ShieldOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -358,6 +362,7 @@ exports[`components/AdminSidebar Plugins should match snapshot 1`] = `
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -393,6 +398,7 @@ exports[`components/AdminSidebar Plugins should match snapshot 1`] = `
definitionKey="compliance"
icon={
<FormatListBulletedIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -540,6 +546,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="about"
icon={
<InformationOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -570,6 +577,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="reporting"
icon={
<ChartBarIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -633,6 +641,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="user_management"
icon={
<AccountMultipleOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -696,6 +705,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="environment"
icon={
<ServerVariantIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -836,6 +846,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="site"
icon={
<CogOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -954,6 +965,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="authentication"
icon={
<ShieldOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1028,6 +1040,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1063,6 +1076,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="integrations"
icon={
<SitemapIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1126,6 +1140,7 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
definitionKey="experimental"
icon={
<FlaskOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1234,6 +1249,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="about"
icon={
<InformationOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1264,6 +1280,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="reporting"
icon={
<ChartBarIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1327,6 +1344,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="user_management"
icon={
<AccountMultipleOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1390,6 +1408,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="environment"
icon={
<ServerVariantIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1530,6 +1549,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="site"
icon={
<CogOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1648,6 +1668,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="authentication"
icon={
<ShieldOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1722,6 +1743,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1757,6 +1779,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="integrations"
icon={
<SitemapIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1820,6 +1843,7 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
definitionKey="experimental"
icon={
<FlaskOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -1983,6 +2007,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="about"
icon={
<InformationOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2013,6 +2038,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="reporting"
icon={
<ChartBarIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2076,6 +2102,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="user_management"
icon={
<AccountMultipleOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2139,6 +2166,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="environment"
icon={
<ServerVariantIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2279,6 +2307,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="site"
icon={
<CogOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2397,6 +2426,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="authentication"
icon={
<ShieldOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2471,6 +2501,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2506,6 +2537,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="integrations"
icon={
<SitemapIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2569,6 +2601,7 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
definitionKey="experimental"
icon={
<FlaskOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2677,6 +2710,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="about"
icon={
<InformationOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2707,6 +2741,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="reporting"
icon={
<ChartBarIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2770,6 +2805,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="user_management"
icon={
<AccountMultipleOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2833,6 +2869,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="environment"
icon={
<ServerVariantIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -2973,6 +3010,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="site"
icon={
<CogOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3091,6 +3129,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="authentication"
icon={
<ShieldOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3165,6 +3204,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3200,6 +3240,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="integrations"
icon={
<SitemapIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3263,6 +3304,7 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
definitionKey="experimental"
icon={
<FlaskOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3371,6 +3413,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="about"
icon={
<InformationOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3401,6 +3444,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="reporting"
icon={
<ChartBarIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3464,6 +3508,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="user_management"
icon={
<AccountMultipleOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3549,6 +3594,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="environment"
icon={
<ServerVariantIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3711,6 +3757,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="site"
icon={
<CogOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3840,6 +3887,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="authentication"
icon={
<ShieldOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3958,6 +4006,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -3993,6 +4042,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="integrations"
icon={
<SitemapIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4056,6 +4106,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="compliance"
icon={
<FormatListBulletedIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4119,6 +4170,7 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
definitionKey="experimental"
icon={
<FlaskOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4227,6 +4279,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="about"
icon={
<InformationOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4257,6 +4310,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="reporting"
icon={
<ChartBarIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4320,6 +4374,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="user_management"
icon={
<AccountMultipleOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4431,6 +4486,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="environment"
icon={
<ServerVariantIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4571,6 +4627,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="site"
icon={
<CogOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4713,6 +4770,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="authentication"
icon={
<ShieldOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4883,6 +4941,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="plugins"
icon={
<PowerPlugOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4918,6 +4977,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="integrations"
icon={
<SitemapIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -4981,6 +5041,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="compliance"
icon={
<FormatListBulletedIcon
className="category-icon fa"
color="currentColor"
size={16}
/>
@@ -5072,6 +5133,7 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
definitionKey="experimental"
icon={
<FlaskOutlineIcon
className="category-icon fa"
color="currentColor"
size={16}
/>

Просмотреть файл

@@ -161,7 +161,7 @@ class AdminSidebar extends React.PureComponent<Props, State> {
};
const result = new Set();
for (const section of Object.values(adminDefinition)) {
for (const item of Object.values(section.subsections)) {
for (const item of Object.values(section)) {
if (isVisible(item)) {
result.add(item.url);
}
@@ -180,7 +180,7 @@ class AdminSidebar extends React.PureComponent<Props, State> {
}
if (!isSectionHidden) {
const sidebarItems: JSX.Element[] = [];
Object.entries(section.subsections).forEach(([subKey, item]) => {
Object.entries(section).forEach(([subKey, item]) => {
if (!item.title) {
return;
}

Просмотреть файл

@@ -20,7 +20,7 @@ const AdminSidebarCategory = ({icon, title, action, children, definitionKey, nam
let link = parentLink;
let titleDiv = (
<div className='category-title category-title--active'>
<span className='category-icon'>{icon}</span>
{icon}
<span className='category-title__text'>
{title}
</span>

Просмотреть файл

@@ -1,19 +1,29 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import type {PluginRedux, PluginSetting} from '@mattermost/types/plugins';
import type {PluginRedux} from '@mattermost/types/plugins';
import {Constants} from 'utils/constants';
import {t} from 'utils/i18n';
import SchemaAdminSettings from '../schema_admin_settings';
import type {AdminDefinitionSetting} from '../types';
export default function getEnablePluginSetting(plugin: PluginRedux): Partial<AdminDefinitionSetting & PluginSetting> {
export type EnabledPluginSetting = {
type: string;
key: string;
label: string;
label_default: string;
help_text: string;
help_text_default: string;
isDisabled?: () => boolean;
}
export default function getEnablePluginSetting(plugin: PluginRedux): EnabledPluginSetting {
const escapedPluginId = SchemaAdminSettings.escapePathPart(plugin.id);
const pluginEnabledConfigKey = 'PluginSettings.PluginStates.' + escapedPluginId + '.Enable';
return {
type: 'bool',
type: Constants.SettingsTypes.TYPE_BOOL,
key: pluginEnabledConfigKey,
label: t('admin.plugin.enable_plugin'),
label_default: 'Enable Plugin: ',

Просмотреть файл

@@ -3,7 +3,7 @@
import {connect} from 'react-redux';
import type {PluginRedux, PluginSetting} from '@mattermost/types/plugins';
import type {PluginRedux} from '@mattermost/types/plugins';
import type {GlobalState} from '@mattermost/types/store';
import {createSelector} from 'mattermost-redux/selectors/create_selector';
@@ -24,7 +24,6 @@ import getEnablePluginSetting from './enable_plugin_setting';
import {it} from '../admin_definition';
import SchemaAdminSettings from '../schema_admin_settings';
import type {AdminDefinitionSetting} from '../types';
type OwnProps = { match: { params: { plugin_id: string } } }
@@ -43,7 +42,7 @@ function makeGetPluginSchema() {
const escapedPluginId = SchemaAdminSettings.escapePathPart(plugin.id);
const pluginEnabledConfigKey = 'PluginSettings.PluginStates.' + escapedPluginId + '.Enable';
let settings: Array<Partial<AdminDefinitionSetting & PluginSetting>> = [];
let settings: Array<Partial<SchemaAdminSettings>> = [];
if (plugin.settings_schema && plugin.settings_schema.settings) {
settings = plugin.settings_schema.settings.map((setting) => {
const key = setting.key.toLowerCase();
@@ -82,25 +81,17 @@ function makeGetPluginSchema() {
component,
showTitle: customComponents[key] ? customComponents[key].options.showTitle : false,
};
}) as Array<Partial<AdminDefinitionSetting & PluginSetting>>;
});
}
if (plugin.id !== appsPluginID || appsFeatureFlagIsEnabled) {
const pluginEnableSetting = getEnablePluginSetting(plugin);
if (pluginEnableSetting.isDisabled) {
pluginEnableSetting.isDisabled = it.any(pluginEnableSetting.isDisabled, it.not(it.userHasWritePermissionOnResource('plugins')));
} else {
pluginEnableSetting.isDisabled = it.not(it.userHasWritePermissionOnResource('plugins'));
}
pluginEnableSetting.isDisabled = it.any(pluginEnableSetting.isDisabled, it.not(it.userHasWritePermissionOnResource('plugins')));
settings.unshift(pluginEnableSetting);
}
settings.forEach((s) => {
if (s.isDisabled) {
s.isDisabled = it.any(s.isDisabled, it.not(it.userHasWritePermissionOnResource('plugins')));
} else {
s.isDisabled = it.not(it.userHasWritePermissionOnResource('plugins'));
}
s.isDisabled = it.any(s.isDisabled, it.not(it.userHasWritePermissionOnResource('plugins')));
});
return {

Просмотреть файл

@@ -1,205 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import type {CloudState, Product} from '@mattermost/types/cloud';
import type {AdminConfig, ClientLicense} from '@mattermost/types/config';
import type {DeepPartial} from '@mattermost/types/utilities';
import type ValidationResult from './validation';
type Component = any
type AdminDefinitionConfigSchemaComponent = {
id: string;
component: Component;
}
export type ConsoleAccess = {read: {[key: string]: boolean}; write: {[key: string]: boolean}}
type Validator = (value: any) => ValidationResult
type AdminDefinitionSettingCustom = {
type: 'custom';
label?: string;
label_default?: string;
component: Component;
key: string;
isDisabled?: Check;
isHidden?: Check;
}
type AdminDefinitionSettingBase = {
key?: string;
label: string;
label_default: string;
onConfigLoad?: (configVal: any, config: any) => any;
onConfigSave?: (displayVal: any, previousVal?: any) => any;
isHidden?: Check;
isDisabled?: Check;
}
type AdminDefinitionSettingBanner = AdminDefinitionSettingBase & {
type: 'banner';
label_markdown?: boolean;
label_values?: {[key: string]: any};
banner_type: 'info' | 'warning';
}
type AdminDefinitionSettingInput = AdminDefinitionSettingBase & {
type: 'text' | 'bool' | 'longtext' | 'number' | 'color';
help_text?: string | JSX.Element;
help_text_default?: string | JSX.Element;
help_text_markdown?: boolean;
help_text_values?: {[key: string]: any};
disabled_help_text?: string;
disabled_help_text_default?: string;
disabled_help_text_markdown?: boolean;
placeholder?: string;
placeholder_default?: string;
validate?: Validator;
setFromMetadataField?: string;
dynamic_value?: (value: any, config: DeepPartial<AdminConfig>, state: any) => string;
max_length?: number;
}
type AdminDefinitionSettingGenerated = AdminDefinitionSettingBase & {
type: 'generated';
help_text: string | JSX.Element;
help_text_default: string | JSX.Element;
isDisabled: Check;
}
type AdminDefinitionSettingDropdownOption = {
value: string;
display_name: string;
display_name_default: string;
help_text?: string;
help_text_default?: string;
help_text_markdown?: boolean;
help_text_values?: {[key: string]: any};
isHidden?: Check;
}
type AdminDefinitionSettingDropdown = AdminDefinitionSettingBase & {
type: 'dropdown';
help_text?: string | JSX.Element;
help_text_default?: string | JSX.Element;
help_text_markdown?: boolean;
help_text_values?: {[key: string]: any};
disabled_help_text?: string;
disabled_help_text_default?: string;
disabled_help_text_markdown?: boolean;
options: AdminDefinitionSettingDropdownOption[];
isHelpHidden?: Check;
}
type AdminDefinitionSettingFileUpload = AdminDefinitionSettingBase & {
type: 'fileupload';
help_text: string;
help_text_default: string;
remove_help_text: string;
remove_help_text_default: string;
remove_button_text: string;
remove_button_text_default: string;
removing_text: string;
removing_text_default: string;
uploading_text: string;
uploading_text_default: string;
fileType: string;
upload_action: () => void;
set_action?: () => void;
setFromMetadataField?: string;
remove_action: () => void;
}
type AdminDefinitionSettingJobsTable = AdminDefinitionSettingBase & {
type: 'jobstable';
job_type: string;
help_text: string;
help_text_markdown: boolean;
help_text_default: string;
help_text_values?: {[key: string]: any};
render_job: Component;
};
type AdminDefinitionSettingLanguage = AdminDefinitionSettingBase & {
type: 'language';
help_text?: string;
help_text_markdown?: boolean;
help_text_default?: string;
help_text_values?: {[key: string]: any};
multiple?: boolean;
no_result?: string;
no_result_default?: string;
not_present?: string;
not_present_default?: string;
}
type AdminDefinitionSettingButton = AdminDefinitionSettingBase & {
type: 'button';
action: () => void;
loading?: string;
loading_default?: string;
help_text?: string | JSX.Element;
help_text_default?: string | JSX.Element;
help_text_markdown?: boolean;
help_text_values?: {[key: string]: any};
error_message: string;
error_message_default: string;
success_message?: string;
success_message_default?: string;
sourceUrlKey?: string;
}
export type AdminDefinitionSetting = AdminDefinitionSettingCustom |
AdminDefinitionSettingInput | AdminDefinitionSettingGenerated |
AdminDefinitionSettingBanner | AdminDefinitionSettingDropdown |
AdminDefinitionSettingButton | AdminDefinitionSettingFileUpload |
AdminDefinitionSettingJobsTable | AdminDefinitionSettingLanguage;
type AdminDefinitionConfigSchemaSettings = {
id: string;
name: string;
name_default: string;
isHidden?: Check;
onConfigLoad?: (configVal: any, config: any) => any;
onConfigSave?: (displayVal: any) => any;
settings?: AdminDefinitionSetting[];
sections?: AdminDefinitionConfigSchemaSection[];
}
type AdminDefinitionConfigSchemaSection = {
title: string;
subtitle?: string;
settings: AdminDefinitionSetting[];
}
type RestrictedIndicatorType = {
value: (cloud: CloudState) => JSX.Element;
shouldDisplay: (license: ClientLicense, subscriptionProduct: Product|undefined) => boolean;
}
export type AdminDefinitionSubSection = {
url: string;
title?: string;
title_default?: string;
searchableStrings?: Array<string|[string, {[key: string]: any}]>;
isHidden?: Check;
isDiscovery?: boolean;
isDisabled?: Check;
schema: AdminDefinitionConfigSchemaComponent | AdminDefinitionConfigSchemaSettings;
restrictedIndicator?: RestrictedIndicatorType;
}
export type AdminDefinitionSection = {
icon: JSX.Element;
sectionTitle: string;
sectionTitleDefault: string;
isHidden: Check;
id?: string;
subsections: {[key: string]: AdminDefinitionSubSection};
}
export type AdminDefinition = {[key: string]: AdminDefinitionSection}
export type Check = boolean | ((config: DeepPartial<AdminConfig>, state: any, license?: ClientLicense, enterpriseReady?: boolean, consoleAccess?: ConsoleAccess, cloud?: CloudState, isSystemAdmin?: boolean) => boolean)

Просмотреть файл

@@ -690,10 +690,6 @@
&.fa-users {
font-size: 13px;
}
>svg {
vertical-align: bottom;
}
}
}

Просмотреть файл

@@ -7,7 +7,7 @@ import {ResourceToSysConsolePermissionsTable, RESOURCE_KEYS} from 'mattermost-re
import {createSelector} from 'mattermost-redux/selectors/create_selector';
import {getMySystemPermissions} from 'mattermost-redux/selectors/entities/roles_helpers';
import AdminDefinition from 'components/admin_console/admin_definition';
import AdminDefinition from 'components/admin_console/admin_definition.jsx';
export const getAdminDefinition = createSelector(
'getAdminDefinition',

Просмотреть файл

@@ -3,7 +3,7 @@
import {getAdminDefinition} from 'selectors/admin_console.jsx';
import AdminDefinition from 'components/admin_console/admin_definition';
import AdminDefinition from 'components/admin_console/admin_definition.jsx';
describe('Selectors.AdminConsole', () => {
describe('get admin definitions', () => {

Просмотреть файл

@@ -3,7 +3,7 @@
import {createIntl} from 'react-intl';
import AdminDefinition from 'components/admin_console/admin_definition';
import AdminDefinition from 'components/admin_console/admin_definition.jsx';
import {samplePlugin1, samplePlugin2} from 'tests/helpers/admin_console_plugin_index_sample_pluings';

Просмотреть файл

@@ -96,7 +96,7 @@ export function adminDefinitionsToUrlsAndTexts(adminDefinition: typeof AdminDefi
adminDefinition.billing,
];
for (const section of sections) {
for (const item of Object.values(section.subsections)) {
for (const item of Object.values(section)) {
if (!item.isDiscovery) {
entries[item.url] = extractTextsFromSection(item, intl);
}

Просмотреть файл

@@ -4,7 +4,7 @@
import type {PluginRedux, PluginSetting} from '@mattermost/types/plugins';
import getEnablePluginSetting from 'components/admin_console/custom_plugin_settings/enable_plugin_setting';
import type {AdminDefinitionSetting} from 'components/admin_console/types';
import type {EnabledPluginSetting} from 'components/admin_console/custom_plugin_settings/enable_plugin_setting';
import {stripMarkdown} from 'utils/markdown';
@@ -28,7 +28,7 @@ function extractTextsFromPlugin(plugin: PluginRedux) {
const settings = Object.values(plugin.settings_schema.settings);
for (const setting of settings) {
const settingsTexts = extractTextFromSetting(setting as Partial<AdminDefinitionSetting & PluginSetting>);
const settingsTexts = extractTextFromSetting(setting);
texts.push(...settingsTexts);
}
}
@@ -36,7 +36,7 @@ function extractTextsFromPlugin(plugin: PluginRedux) {
return texts;
}
function extractTextFromSetting(setting: Partial<AdminDefinitionSetting & PluginSetting>) {
function extractTextFromSetting(setting: Partial<EnabledPluginSetting & PluginSetting>) {
const texts = [];
if (setting.label) {
texts.push(setting.label);

73
webapp/package-lock.json сгенерированный
Просмотреть файл

@@ -225,7 +225,8 @@
"stylelint-scss": "3.19.0",
"webpack-bundle-analyzer": "4.7.0",
"webpack-pwa-manifest": "4.3.0",
"yargs": "16.2.0"
"yargs": "16.2.0",
"yup": "0.32.11"
}
},
"channels/node_modules/@mattermost/compass-icons": {
@@ -16513,6 +16514,12 @@
"react-dom": "*"
}
},
"node_modules/nanoclone": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
"integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==",
"dev": true
},
"node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
@@ -18375,6 +18382,12 @@
"retry": "^0.10.0"
}
},
"node_modules/property-expr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
"integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==",
"dev": true
},
"node_modules/proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@@ -21881,6 +21894,12 @@
"node": ">=0.6"
}
},
"node_modules/toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
"dev": true
},
"node_modules/totalist": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz",
@@ -23480,6 +23499,24 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/yup": {
"version": "0.32.11",
"resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz",
"integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.15.4",
"@types/lodash": "^4.14.175",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"nanoclone": "^0.2.1",
"property-expr": "^2.0.4",
"toposort": "^2.0.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/zen-observable": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.9.0.tgz",
@@ -35723,6 +35760,7 @@
"webpack-bundle-analyzer": "4.7.0",
"webpack-pwa-manifest": "4.3.0",
"yargs": "16.2.0",
"yup": "0.32.11",
"zen-observable": "0.9.0"
},
"dependencies": {
@@ -36494,6 +36532,12 @@
"stylis": "^4.0.6"
}
},
"nanoclone": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
"integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==",
"dev": true
},
"nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
@@ -37910,6 +37954,12 @@
"retry": "^0.10.0"
}
},
"property-expr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
"integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==",
"dev": true
},
"proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@@ -40637,6 +40687,12 @@
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"dev": true
},
"toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
"dev": true
},
"totalist": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz",
@@ -41780,6 +41836,21 @@
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
},
"yup": {
"version": "0.32.11",
"resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz",
"integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==",
"dev": true,
"requires": {
"@babel/runtime": "^7.15.4",
"@types/lodash": "^4.14.175",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"nanoclone": "^0.2.1",
"property-expr": "^2.0.4",
"toposort": "^2.0.2"
}
},
"zen-observable": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.9.0.tgz",