MM-62046 Associate most labels with controls and enable label-has-associated-control ESLint rule (#29510)
* Remove label from add_user_to_channel_modal.tsx The label isn't needed here because it was incorrectly used for error text. I had to add the display: block to the .modal__error class to ensure the top margin was the same as before, but I could remove the font-weight from that class since it was only needed to counteract the weight that Bootstrap adds for labels. : * Remove label from bleve_settings.tsx and replace with SettingSet It doesn't seem correct to use a label here because it isn't tied to a single form field. Since this component is a set of fields (a fieldset, if you will) that looks like a setting, it seemed like a good place to use SettingSet. * Remove label from brand_image_setting.tsx, replace with SettingSet, and improve a11y of upload button Like the last commit for BleveSettings, this setting is multiple inputs, so it makes more sense as a fieldset/SettingSet. While doing that, I also changed how the file upload button in BrandImageSetting works because the new HTML broke how it worked before. Previously, we overlayed an transparent file input over the button for it, but the sizing for that got messed up, and that causes some weird accessibility and breaks some things like hover effects. Instead, the file input is now fully hidden, and clicking on the button triggers the file input programatically. The behaviour is otherwise the same, but the button now shows the hover style and there's only one keyboard focus for the button. * Remove some more labels from PluginManagement and use SettingSet there * Add for attribute to labels in compliance_reports.tsx * Use SettingSet and add the for attribute to another label in DatabaseSettings * Use SettingSet in ElasticsearchSettings * Add for attribute to label in GroupProfile * Don't use label for help text in TeamEditionRightPanel For this, I had to add a new CSS class to make the element appear as if it was a label element as affected by Bootstrap. There's likely some cases that this won't work, but it applies the same margin and font-weight. * Don't use label for help text in TrialBanner * Don't use label for a heading in PasswordSettings * Don't use label element in table in ChannelModeration This text is more like a legend element in SettingSet, but I didn't use that because it's in a table. This could possibly be given its own CSS class. * Don't use label element for error text in AdvancedTextEditor and MessageSubmitError * Don't use label for help text and add for attribute in RenameChannelModal * Don't use label for error text in SelectTeam * Add for attribute to labels in various components * Turn jsx-a11y/label-has-associated-control to an error * Fix E2E test
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
0e4e7ca0b9
Коммит
f11ed97a5c
@@ -36,7 +36,7 @@ describe('Customization', () => {
|
||||
|
||||
cy.findByTestId('CustomBrandImage').should('be.visible').within(() => {
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.get('label').should('be.visible').and('have.text', 'Custom Brand Image:');
|
||||
cy.get('legend').should('be.visible').and('have.text', 'Custom Brand Image:');
|
||||
|
||||
// * Verify that help setting is visible and matches text content
|
||||
const contents = 'Customize your user experience by adding a custom image to your login screen. Recommended maximum image size is less than 2 MB.';
|
||||
|
||||
@@ -95,9 +95,7 @@ exports[`components/AddUserToChannelModal should match snapshot 1`] = `
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<br />
|
||||
</div>
|
||||
<div />
|
||||
</ModalBody>
|
||||
<ModalFooter
|
||||
bsClass="modal-footer"
|
||||
|
||||
@@ -224,16 +224,16 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
if (!this.state.saving) {
|
||||
if (this.state.submitError) {
|
||||
errorMsg = (
|
||||
<label
|
||||
<span
|
||||
id='add-user-to-channel-modal__invite-error'
|
||||
className='modal__error has-error control-label'
|
||||
>
|
||||
{this.state.submitError}
|
||||
</label>
|
||||
</span>
|
||||
);
|
||||
} else if (targetUserIsMemberOfSelectedChannel) {
|
||||
errorMsg = (
|
||||
<label
|
||||
<span
|
||||
id='add-user-to-channel-modal__user-is-member'
|
||||
className='modal__error has-error control-label'
|
||||
>
|
||||
@@ -244,7 +244,7 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
name,
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,6 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
</div>
|
||||
<div>
|
||||
{errorMsg}
|
||||
<br/>
|
||||
</div>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
|
||||
@@ -57,43 +57,36 @@ exports[`components/BleveSettings should match snapshot, disabled 1`] = `
|
||||
setByEnv={false}
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
<SettingSet
|
||||
label={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Bulk Indexing:"
|
||||
id="admin.bleve.bulkIndexingTitle"
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="col-sm-8"
|
||||
className="job-table-setting"
|
||||
>
|
||||
<div
|
||||
className="job-table-setting"
|
||||
>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.bleve.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Bleve is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.bleve.createJob.help"
|
||||
/>
|
||||
}
|
||||
disabled={true}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="bleve_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.bleve.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Bleve is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.bleve.createJob.help"
|
||||
/>
|
||||
}
|
||||
disabled={true}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="bleve_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<RequestButton
|
||||
buttonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
@@ -260,43 +253,36 @@ exports[`components/BleveSettings should match snapshot, enabled 1`] = `
|
||||
setByEnv={false}
|
||||
value="bleve.idx"
|
||||
/>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
<SettingSet
|
||||
label={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Bulk Indexing:"
|
||||
id="admin.bleve.bulkIndexingTitle"
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="col-sm-8"
|
||||
className="job-table-setting"
|
||||
>
|
||||
<div
|
||||
className="job-table-setting"
|
||||
>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.bleve.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Bleve is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.bleve.createJob.help"
|
||||
/>
|
||||
}
|
||||
disabled={false}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="bleve_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.bleve.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Bleve is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.bleve.createJob.help"
|
||||
/>
|
||||
}
|
||||
disabled={false}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="bleve_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<RequestButton
|
||||
buttonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
|
||||
@@ -340,39 +340,33 @@ exports[`components/DatabaseSettings should match snapshot 1`] = `
|
||||
setByEnv={false}
|
||||
value={true}
|
||||
/>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
<SettingSet
|
||||
label={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Schema Migrations:"
|
||||
id="admin.database.migrations_table.title"
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="col-sm-8"
|
||||
className="migrations-table-setting"
|
||||
>
|
||||
<div
|
||||
className="migrations-table-setting"
|
||||
>
|
||||
<Connect(Component)
|
||||
createHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All applied migrations."
|
||||
id="admin.database.migrations_table.help_text"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Connect(Component)
|
||||
createHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All applied migrations."
|
||||
id="admin.database.migrations_table.help_text"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="activeSearchBackend"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Active Search Backend:"
|
||||
@@ -385,6 +379,7 @@ exports[`components/DatabaseSettings should match snapshot 1`] = `
|
||||
<input
|
||||
className="form-control"
|
||||
disabled={true}
|
||||
id="activeSearchBackend"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
|
||||
@@ -288,43 +288,36 @@ exports[`components/ElasticSearchSettings should match snapshot, disabled 1`] =
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
<SettingSet
|
||||
label={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Bulk Indexing:"
|
||||
id="admin.elasticsearch.bulkIndexingTitle"
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="col-sm-8"
|
||||
className="job-table-setting"
|
||||
>
|
||||
<div
|
||||
className="job-table-setting"
|
||||
>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.elasticsearch.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Elasticsearch is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.elasticsearch.createJob.help"
|
||||
/>
|
||||
}
|
||||
disabled={true}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="elasticsearch_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.elasticsearch.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Elasticsearch is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.elasticsearch.createJob.help"
|
||||
/>
|
||||
}
|
||||
disabled={true}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="elasticsearch_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<RequestButton
|
||||
buttonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
@@ -790,42 +783,35 @@ exports[`components/ElasticSearchSettings should match snapshot, enabled 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
<SettingSet
|
||||
label={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Bulk Indexing:"
|
||||
id="admin.elasticsearch.bulkIndexingTitle"
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="col-sm-8"
|
||||
className="job-table-setting"
|
||||
>
|
||||
<div
|
||||
className="job-table-setting"
|
||||
>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.elasticsearch.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Elasticsearch is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.elasticsearch.createJob.help"
|
||||
/>
|
||||
}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="elasticsearch_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
<Connect(JobTable)
|
||||
createJobButtonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Index Now"
|
||||
id="admin.elasticsearch.createJob.title"
|
||||
/>
|
||||
}
|
||||
createJobHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All users, channels and posts in the database will be indexed from oldest to newest. Elasticsearch is available during indexing but search results may be incomplete until the indexing job is complete."
|
||||
id="admin.elasticsearch.createJob.help"
|
||||
/>
|
||||
}
|
||||
getExtraInfoText={[Function]}
|
||||
jobType="elasticsearch_post_indexing"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<RequestButton
|
||||
buttonText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
|
||||
@@ -18,6 +18,7 @@ import JobsTable from './jobs';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import RequestButton from './request_button/request_button';
|
||||
import SettingSet from './setting_set';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
||||
@@ -174,27 +175,24 @@ export default class BleveSettings extends OLDAdminSettings<Props, State> {
|
||||
setByEnv={this.isSetByEnv('BleveSettings.IndexDir')}
|
||||
disabled={this.props.isDisabled}
|
||||
/>
|
||||
<div className='form-group'>
|
||||
<label className='control-label col-sm-4'>
|
||||
<FormattedMessage {...messages.bulkIndexingTitle}/>
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<div className='job-table-setting'>
|
||||
<JobsTable
|
||||
jobType={JobTypes.BLEVE_POST_INDEXING}
|
||||
disabled={!this.state.canPurgeAndIndex || Boolean(this.props.isDisabled)}
|
||||
createJobButtonText={
|
||||
<FormattedMessage
|
||||
id='admin.bleve.createJob.title'
|
||||
defaultMessage='Index Now'
|
||||
/>
|
||||
}
|
||||
createJobHelpText={<FormattedMessage {...messages.createJob_help}/>}
|
||||
getExtraInfoText={this.getExtraInfo}
|
||||
/>
|
||||
</div>
|
||||
<SettingSet
|
||||
label={<FormattedMessage {...messages.bulkIndexingTitle}/>}
|
||||
>
|
||||
<div className='job-table-setting'>
|
||||
<JobsTable
|
||||
jobType={JobTypes.BLEVE_POST_INDEXING}
|
||||
disabled={!this.state.canPurgeAndIndex || Boolean(this.props.isDisabled)}
|
||||
createJobButtonText={
|
||||
<FormattedMessage
|
||||
id='admin.bleve.createJob.title'
|
||||
defaultMessage='Index Now'
|
||||
/>
|
||||
}
|
||||
createJobHelpText={<FormattedMessage {...messages.createJob_help}/>}
|
||||
getExtraInfoText={this.getExtraInfo}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<RequestButton
|
||||
id='purgeIndexesSection'
|
||||
requestAction={blevePurgeIndexes}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {uploadBrandImage, deleteBrandImage} from 'actions/admin_actions.jsx';
|
||||
|
||||
import SettingSet from 'components/admin_console/setting_set';
|
||||
import FormError from 'components/form_error';
|
||||
import WithTooltip from 'components/with_tooltip';
|
||||
|
||||
@@ -110,6 +111,10 @@ export default class BrandImageSetting extends React.PureComponent<Props, State>
|
||||
}
|
||||
}
|
||||
|
||||
handleSelectClick = () => {
|
||||
this.fileInputRef.current?.click();
|
||||
};
|
||||
|
||||
handleImageChange = () => {
|
||||
if (!this.fileInputRef.current) {
|
||||
return;
|
||||
@@ -234,50 +239,47 @@ export default class BrandImageSetting extends React.PureComponent<Props, State>
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
data-testid={this.props.id}
|
||||
className='form-group'
|
||||
>
|
||||
<label className='control-label col-sm-4'>
|
||||
<SettingSet
|
||||
inputId={this.props.id}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id='admin.team.uploadDesc'
|
||||
defaultMessage='Customize your user experience by adding a custom image to your login screen. Recommended maximum image size is less than 2 MB.'
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='admin.team.brandImageTitle'
|
||||
defaultMessage='Custom Brand Image:'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
}
|
||||
setByEnv={false}
|
||||
>
|
||||
<div>
|
||||
<div className='remove-image'>{img}</div>
|
||||
</div>
|
||||
<div className='col-sm-4'/>
|
||||
<div className='col-sm-8'>
|
||||
<div className='file__upload mt-5'>
|
||||
<button
|
||||
type='button'
|
||||
className='btn btn-tertiary'
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.team.chooseImage'
|
||||
defaultMessage='Select Image'
|
||||
/>
|
||||
</button>
|
||||
<input
|
||||
ref={this.fileInputRef}
|
||||
type='file'
|
||||
accept={Constants.ACCEPT_STATIC_IMAGE}
|
||||
disabled={this.props.disabled}
|
||||
onChange={this.handleImageChange}
|
||||
/>
|
||||
</div>
|
||||
<br/>
|
||||
<FormError error={this.state.error}/>
|
||||
<p className='help-text m-0'>
|
||||
<div className='file__upload mt-5'>
|
||||
<button
|
||||
type='button'
|
||||
className='btn btn-tertiary'
|
||||
disabled={this.props.disabled}
|
||||
onClick={this.handleSelectClick}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.team.uploadDesc'
|
||||
defaultMessage='Customize your user experience by adding a custom image to your login screen. Recommended maximum image size is less than 2 MB.'
|
||||
id='admin.team.chooseImage'
|
||||
defaultMessage='Select Image'
|
||||
/>
|
||||
</p>
|
||||
</button>
|
||||
<input
|
||||
ref={this.fileInputRef}
|
||||
type='file'
|
||||
accept={Constants.ACCEPT_STATIC_IMAGE}
|
||||
disabled={this.props.disabled}
|
||||
onChange={this.handleImageChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<FormError error={this.state.error}/>
|
||||
</SettingSet>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ export default class ComplianceReports extends React.PureComponent<Props, State>
|
||||
</h4>
|
||||
<div className='row'>
|
||||
<div className='col-sm-6 col-md-4 form-group'>
|
||||
<label>
|
||||
<label htmlFor='desc'>
|
||||
<FormattedMessage
|
||||
id='admin.compliance_reports.desc'
|
||||
defaultMessage='Job Name:'
|
||||
@@ -354,7 +354,7 @@ export default class ComplianceReports extends React.PureComponent<Props, State>
|
||||
/>
|
||||
</div>
|
||||
<div className='col-sm-3 col-md-2 form-group'>
|
||||
<label>
|
||||
<label htmlFor='from'>
|
||||
<FormattedMessage
|
||||
id='admin.compliance_reports.from'
|
||||
defaultMessage='From:'
|
||||
@@ -370,7 +370,7 @@ export default class ComplianceReports extends React.PureComponent<Props, State>
|
||||
/>
|
||||
</div>
|
||||
<div className='col-sm-3 col-md-2 form-group'>
|
||||
<label>
|
||||
<label htmlFor='to'>
|
||||
<FormattedMessage
|
||||
id='admin.compliance_reports.to'
|
||||
defaultMessage='To:'
|
||||
@@ -388,7 +388,7 @@ export default class ComplianceReports extends React.PureComponent<Props, State>
|
||||
</div>
|
||||
<div className='row'>
|
||||
<div className='col-sm-6 col-md-4 form-group'>
|
||||
<label>
|
||||
<label htmlFor='emails'>
|
||||
<FormattedMessage
|
||||
id='admin.compliance_reports.emails'
|
||||
defaultMessage='Emails:'
|
||||
@@ -404,7 +404,7 @@ export default class ComplianceReports extends React.PureComponent<Props, State>
|
||||
/>
|
||||
</div>
|
||||
<div className='col-sm-6 col-md-4 form-group'>
|
||||
<label>
|
||||
<label htmlFor='keywords'>
|
||||
<FormattedMessage
|
||||
id='admin.compliance_reports.keywords'
|
||||
defaultMessage='Keywords:'
|
||||
|
||||
@@ -18,6 +18,7 @@ import MigrationsTable from './database';
|
||||
import type {BaseState} from './old_admin_settings';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import RequestButton from './request_button/request_button';
|
||||
import SettingSet from './setting_set';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
||||
@@ -378,31 +379,29 @@ export default class DatabaseSettings extends OLDAdminSettings<Props, State> {
|
||||
setByEnv={this.isSetByEnv('SqlSettings.DisableDatabaseSearch')}
|
||||
disabled={this.props.isDisabled}
|
||||
/>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-4'
|
||||
>
|
||||
<SettingSet
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.title'
|
||||
defaultMessage='Schema Migrations:'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<div className='migrations-table-setting'>
|
||||
<MigrationsTable
|
||||
createHelpText={
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.help_text'
|
||||
defaultMessage='All applied migrations.'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className='migrations-table-setting'>
|
||||
<MigrationsTable
|
||||
createHelpText={
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.help_text'
|
||||
defaultMessage='All applied migrations.'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-4'
|
||||
htmlFor='activeSearchBackend'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.database.search_backend.title'
|
||||
@@ -411,6 +410,7 @@ export default class DatabaseSettings extends OLDAdminSettings<Props, State> {
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<input
|
||||
id='activeSearchBackend'
|
||||
type='text'
|
||||
className='form-control'
|
||||
value={this.state.searchBackend}
|
||||
|
||||
@@ -19,6 +19,7 @@ import JobsTable from './jobs';
|
||||
import OLDAdminSettings from './old_admin_settings';
|
||||
import type {BaseProps, BaseState} from './old_admin_settings';
|
||||
import RequestButton from './request_button/request_button';
|
||||
import SettingSet from './setting_set';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
|
||||
@@ -419,27 +420,24 @@ export default class ElasticsearchSettings extends OLDAdminSettings<Props, State
|
||||
})}
|
||||
disabled={!this.state.enableIndexing}
|
||||
/>
|
||||
<div className='form-group'>
|
||||
<label className='control-label col-sm-4'>
|
||||
<FormattedMessage {...messages.bulkIndexingTitle}/>
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<div className='job-table-setting'>
|
||||
<JobsTable
|
||||
jobType={JobTypes.ELASTICSEARCH_POST_INDEXING as JobType}
|
||||
disabled={!this.state.canPurgeAndIndex || this.props.isDisabled!}
|
||||
createJobButtonText={
|
||||
<FormattedMessage
|
||||
id='admin.elasticsearch.createJob.title'
|
||||
defaultMessage='Index Now'
|
||||
/>
|
||||
}
|
||||
createJobHelpText={<FormattedMessage {...messages.help}/>}
|
||||
getExtraInfoText={this.getExtraInfo}
|
||||
/>
|
||||
</div>
|
||||
<SettingSet
|
||||
label={<FormattedMessage {...messages.bulkIndexingTitle}/>}
|
||||
>
|
||||
<div className='job-table-setting'>
|
||||
<JobsTable
|
||||
jobType={JobTypes.ELASTICSEARCH_POST_INDEXING as JobType}
|
||||
disabled={!this.state.canPurgeAndIndex || this.props.isDisabled!}
|
||||
createJobButtonText={
|
||||
<FormattedMessage
|
||||
id='admin.elasticsearch.createJob.title'
|
||||
defaultMessage='Index Now'
|
||||
/>
|
||||
}
|
||||
createJobHelpText={<FormattedMessage {...messages.help}/>}
|
||||
getExtraInfoText={this.getExtraInfo}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingSet>
|
||||
<RequestButton
|
||||
id='rebuildChannelsIndexButton'
|
||||
requestAction={rebuildChannelsIndex}
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
exports[`components/admin_console/group_settings/group_details/GroupProfile should match snapshot 1`] = `
|
||||
<div
|
||||
className="group-profile form-horizontal"
|
||||
id="test"
|
||||
>
|
||||
<div
|
||||
className="group-profile-field form-group mb-0"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="testInput"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Name:"
|
||||
@@ -29,6 +31,7 @@ exports[`components/admin_console/group_settings/group_details/GroupProfile shou
|
||||
<input
|
||||
className="form-control group-at-mention-input"
|
||||
disabled={false}
|
||||
id="testInput"
|
||||
type="text"
|
||||
value="Test"
|
||||
/>
|
||||
|
||||
@@ -10,6 +10,7 @@ describe('components/admin_console/group_settings/group_details/GroupProfile', (
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
<GroupProfile
|
||||
customID='test'
|
||||
isDisabled={false}
|
||||
name='Test'
|
||||
showAtMention={true}
|
||||
|
||||
@@ -10,7 +10,7 @@ import MentionsIcon from 'components/widgets/icons/mentions_icon';
|
||||
type Props = {
|
||||
name?: string;
|
||||
title: MessageDescriptor;
|
||||
customID?: string;
|
||||
customID: string;
|
||||
isDisabled?: boolean;
|
||||
showAtMention: boolean;
|
||||
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
||||
@@ -29,7 +29,10 @@ const GroupProfile = ({
|
||||
id={customID}
|
||||
>
|
||||
<div className='group-profile-field form-group mb-0'>
|
||||
<label className='control-label col-sm-4'>
|
||||
<label
|
||||
className='control-label col-sm-4'
|
||||
htmlFor={customID + 'Input'}
|
||||
>
|
||||
<FormattedMessage {...title}/>
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
@@ -42,6 +45,7 @@ const GroupProfile = ({
|
||||
)}
|
||||
</div>
|
||||
<input
|
||||
id={customID + 'Input'}
|
||||
type='text'
|
||||
className='form-control group-at-mention-input'
|
||||
value={name}
|
||||
|
||||
@@ -101,13 +101,12 @@ const TeamEditionRightPanel: React.FC<TeamEditionRightPanelProps> = ({
|
||||
{upgradeError && (
|
||||
<div className='upgrade-error'>
|
||||
<div className='form-group has-error'>
|
||||
<label className='control-label'>
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: format(upgradeError),
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className='as-bs-label control-label'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: format(upgradeError),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -140,17 +139,17 @@ const TeamEditionRightPanel: React.FC<TeamEditionRightPanelProps> = ({
|
||||
defaultMessage='Restart Server'
|
||||
/>
|
||||
</LoadingWrapper>
|
||||
{restartError && (
|
||||
<div className='col-sm-12'>
|
||||
<div className='form-group has-error'>
|
||||
<label className='control-label'>
|
||||
{restartError}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
</p>
|
||||
{restartError && (
|
||||
<div className='upgrade-error'>
|
||||
<div className='form-group has-error'>
|
||||
<div className='as-bs-label control-label'>
|
||||
{restartError}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -340,22 +340,21 @@ const TrialBanner = ({
|
||||
{upgradeError && (
|
||||
<div className='upgrade-error'>
|
||||
<div className='form-group has-error'>
|
||||
<label className='control-label'>
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: format(upgradeError),
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className='as-bs-label control-label'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: format(upgradeError),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{restartError && (
|
||||
<div className='col-sm-12'>
|
||||
<div className='upgrade-error'>
|
||||
<div className='form-group has-error'>
|
||||
<label className='control-label'>
|
||||
<div className='as-bs-label control-label'>
|
||||
{restartError}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -254,10 +254,9 @@ export default class PasswordSettings extends OLDAdminSettings<Props, State> {
|
||||
</ul>
|
||||
<div>
|
||||
<br/>
|
||||
<label>
|
||||
<div className='password-settings__preview-heading'>
|
||||
<FormattedMessage {...messages.preview}/>
|
||||
</label>
|
||||
<br/>
|
||||
</div>
|
||||
{this.getSampleErrorMsg()}
|
||||
</div>
|
||||
</SettingSet>
|
||||
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -24,6 +24,7 @@ import * as Utils from 'utils/utils';
|
||||
import BooleanSetting from '../boolean_setting';
|
||||
import OLDAdminSettings from '../old_admin_settings';
|
||||
import type {BaseProps, BaseState} from '../old_admin_settings';
|
||||
import SettingSet from '../setting_set';
|
||||
import SettingsGroup from '../settings_group';
|
||||
import TextSetting from '../text_setting';
|
||||
|
||||
@@ -556,6 +557,10 @@ class PluginManagement extends OLDAdminSettings<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
handleChooseFileClick = () => {
|
||||
this.fileInput.current?.click();
|
||||
};
|
||||
|
||||
handleUpload = () => {
|
||||
this.setState({lastMessage: null, serverError: null});
|
||||
const element = this.fileInput.current as HTMLInputElement;
|
||||
@@ -1018,18 +1023,15 @@ class PluginManagement extends OLDAdminSettings<Props, State> {
|
||||
|
||||
if (enable) {
|
||||
pluginsContainer = (
|
||||
<div className='form-group'>
|
||||
<label className='control-label col-sm-4'>
|
||||
<FormattedMessage {...messages.installedTitle}/>
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<p className='help-text'>
|
||||
<FormattedMessage {...messages.installedDesc}/>
|
||||
</p>
|
||||
<br/>
|
||||
{pluginsListContainer}
|
||||
</div>
|
||||
</div>
|
||||
<SettingSet
|
||||
label={<FormattedMessage {...messages.installedTitle}/>}
|
||||
>
|
||||
<p className='help-text'>
|
||||
<FormattedMessage {...messages.installedDesc}/>
|
||||
</p>
|
||||
<br/>
|
||||
{pluginsListContainer}
|
||||
</SettingSet>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1147,48 +1149,44 @@ class PluginManagement extends OLDAdminSettings<Props, State> {
|
||||
onChange={this.handleChange}
|
||||
setByEnv={this.isSetByEnv('PluginSettings.AutomaticPrepackagedPlugins')}
|
||||
/>
|
||||
<div className='form-group'>
|
||||
<label className='control-label col-sm-4'>
|
||||
<FormattedMessage {...messages.uploadTitle}/>
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<div className='file__upload'>
|
||||
<button
|
||||
type='button'
|
||||
className={classNames(['btn', {'btn-tertiary': enableUploads}])}
|
||||
disabled={!enableUploadButton || this.props.isDisabled}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.plugin.choose'
|
||||
defaultMessage='Choose File'
|
||||
/>
|
||||
</button>
|
||||
<input
|
||||
ref={this.fileInput}
|
||||
type='file'
|
||||
accept='.gz'
|
||||
onChange={this.handleUpload}
|
||||
disabled={!enableUploadButton || this.props.isDisabled}
|
||||
/>
|
||||
</div>
|
||||
<SettingSet
|
||||
helpText={uploadHelpText}
|
||||
label={<FormattedMessage {...messages.uploadTitle}/>}
|
||||
>
|
||||
<div className='file__upload'>
|
||||
<button
|
||||
className={btnClass}
|
||||
id='uploadPlugin'
|
||||
disabled={!this.state.fileSelected}
|
||||
onClick={this.handleSubmitUpload}
|
||||
type='button'
|
||||
className={classNames(['btn', {'btn-tertiary': enableUploads}])}
|
||||
onClick={this.handleChooseFileClick}
|
||||
disabled={!enableUploadButton || this.props.isDisabled}
|
||||
>
|
||||
{uploadButtonText}
|
||||
<FormattedMessage
|
||||
id='admin.plugin.choose'
|
||||
defaultMessage='Choose File'
|
||||
/>
|
||||
</button>
|
||||
<div className='help-text m-0'>
|
||||
{fileName}
|
||||
</div>
|
||||
{serverError}
|
||||
{lastMessage}
|
||||
<p className='help-text'>
|
||||
{uploadHelpText}
|
||||
</p>
|
||||
<input
|
||||
ref={this.fileInput}
|
||||
type='file'
|
||||
accept='.gz'
|
||||
onChange={this.handleUpload}
|
||||
disabled={!enableUploadButton || this.props.isDisabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className={btnClass}
|
||||
id='uploadPlugin'
|
||||
disabled={!this.state.fileSelected}
|
||||
onClick={this.handleSubmitUpload}
|
||||
>
|
||||
{uploadButtonText}
|
||||
</button>
|
||||
<div className='help-text m-0'>
|
||||
{fileName}
|
||||
</div>
|
||||
{serverError}
|
||||
{lastMessage}
|
||||
</SettingSet>
|
||||
<BooleanSetting
|
||||
id='enableMarketplace'
|
||||
label={<FormattedMessage {...messages.enableMarketplace}/>}
|
||||
|
||||
@@ -259,14 +259,15 @@ exports[`admin_console/team_channel_settings/channel/ChannelModeration Should ma
|
||||
exports[`admin_console/team_channel_settings/channel/ChannelModeration Should match second Snapshot 1`] = `
|
||||
<tr>
|
||||
<td>
|
||||
<label
|
||||
<div
|
||||
className="as-bs-label"
|
||||
data-testid="admin-channel_settings-channel_moderation-createPosts"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Create Posts"
|
||||
id="admin.channel_settings.channel_moderation.createPosts"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
data-testid="admin-channel_settings-channel_moderation-createPostsDesc"
|
||||
>
|
||||
@@ -303,14 +304,15 @@ exports[`admin_console/team_channel_settings/channel/ChannelModeration Should ma
|
||||
exports[`admin_console/team_channel_settings/channel/ChannelModeration Should match seventh Snapshot 1`] = `
|
||||
<tr>
|
||||
<td>
|
||||
<label
|
||||
<div
|
||||
className="as-bs-label"
|
||||
data-testid="admin-channel_settings-channel_moderation-createPosts"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Create Posts"
|
||||
id="admin.channel_settings.channel_moderation.createPosts"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
data-testid="admin-channel_settings-channel_moderation-createPostsDesc"
|
||||
>
|
||||
|
||||
@@ -275,14 +275,15 @@ export const ChannelModerationTableRow = (props: ChannelModerationTableRow) => {
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
<label
|
||||
<div
|
||||
className='as-bs-label'
|
||||
data-testid={channelModerationPermissionMessages?.title?.id?.replace(PERIOD_TO_SLASH_REGEX, '-')}
|
||||
>
|
||||
<FormattedMessage
|
||||
id={channelModerationPermissionMessages?.title?.id}
|
||||
defaultMessage={channelModerationPermissionMessages?.title?.defaultMessage}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
data-testid={channelModerationPermissionMessages?.description?.id?.replace(PERIOD_TO_SLASH_REGEX, '-')}
|
||||
>
|
||||
|
||||
@@ -196,11 +196,6 @@
|
||||
.post-error {
|
||||
margin: 4px 0 0 0;
|
||||
color: var(--error-text);
|
||||
|
||||
label {
|
||||
margin: 0;
|
||||
color: var(--error-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -699,9 +699,9 @@ const AdvancedTextEditor = ({
|
||||
className='AdvancedTextEditor__footer'
|
||||
>
|
||||
{postError && (
|
||||
<label className={classNames('post-error', {errorClass})}>
|
||||
<div className={classNames('post-error', {errorClass})}>
|
||||
{postError}
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
{serverError && (
|
||||
<MessageSubmitError
|
||||
|
||||
@@ -366,7 +366,10 @@ export default class Bot extends React.PureComponent<Props, State> {
|
||||
onSubmit={this.handleCreateToken}
|
||||
>
|
||||
<div className='row'>
|
||||
<label className='col-sm-auto control-label'>
|
||||
<label
|
||||
className='col-sm-auto control-label'
|
||||
htmlFor='botToken'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.tokens.name'
|
||||
defaultMessage='Token Description: '
|
||||
@@ -374,6 +377,7 @@ export default class Bot extends React.PureComponent<Props, State> {
|
||||
</label>
|
||||
<div className='col-sm-4'>
|
||||
<input
|
||||
id='botToken'
|
||||
autoFocus={true}
|
||||
className='form-control form-sm'
|
||||
type='text'
|
||||
|
||||
@@ -21,7 +21,7 @@ function MessageSubmitError(props: Props) {
|
||||
|
||||
return (
|
||||
<div className='has-error'>
|
||||
<label className='control-label'>
|
||||
<div className='control-label'>
|
||||
<FormattedMessage
|
||||
id='message_submit_error.invalidCommand'
|
||||
defaultMessage="Command with a trigger of ''{slashCommand}'' not found. "
|
||||
@@ -31,6 +31,7 @@ function MessageSubmitError(props: Props) {
|
||||
/>
|
||||
<a
|
||||
href='#'
|
||||
role='button'
|
||||
onClick={props.handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
@@ -38,7 +39,7 @@ function MessageSubmitError(props: Props) {
|
||||
defaultMessage='Click here to send as a message.'
|
||||
/>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ exports[`components/RenameChannelModal should match snapshot 1`] = `
|
||||
>
|
||||
<label
|
||||
className="control-label"
|
||||
htmlFor="display_name"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Display Name"
|
||||
@@ -81,6 +82,7 @@ exports[`components/RenameChannelModal should match snapshot 1`] = `
|
||||
>
|
||||
<label
|
||||
className="control-label"
|
||||
htmlFor="channel_name"
|
||||
>
|
||||
URL
|
||||
</label>
|
||||
|
||||
@@ -241,7 +241,7 @@ export class RenameChannelModal extends React.PureComponent<Props, State> {
|
||||
|
||||
let serverError = null;
|
||||
if (this.state.serverError) {
|
||||
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
|
||||
serverError = <div className='form-group has-error'><div className='as-bs-label control-label'>{this.state.serverError}</div></div>;
|
||||
}
|
||||
|
||||
const {formatMessage} = this.props.intl;
|
||||
@@ -280,7 +280,10 @@ export class RenameChannelModal extends React.PureComponent<Props, State> {
|
||||
<form role='form'>
|
||||
<Modal.Body>
|
||||
<div className='form-group'>
|
||||
<label className='control-label'>
|
||||
<label
|
||||
className='control-label'
|
||||
htmlFor='display_name'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='rename_channel.displayName'
|
||||
defaultMessage='Display Name'
|
||||
@@ -303,7 +306,12 @@ export class RenameChannelModal extends React.PureComponent<Props, State> {
|
||||
{displayNameError}
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label className='control-label'>{urlInputLabel}</label>
|
||||
<label
|
||||
className='control-label'
|
||||
htmlFor='channel_name'
|
||||
>
|
||||
{urlInputLabel}
|
||||
</label>
|
||||
|
||||
<div className={urlInputClass}>
|
||||
<WithTooltip
|
||||
|
||||
@@ -233,11 +233,11 @@ exports[`components/select_team/SelectTeam should match snapshot, on error 1`] =
|
||||
<div
|
||||
className="form-group has-error"
|
||||
>
|
||||
<label
|
||||
<div
|
||||
className="control-label"
|
||||
>
|
||||
<Component />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Memo(SystemPermissionGate)
|
||||
@@ -535,14 +535,14 @@ exports[`components/select_team/SelectTeam should match snapshot, on no joinable
|
||||
<div
|
||||
className="form-group has-error"
|
||||
>
|
||||
<label
|
||||
<div
|
||||
className="control-label"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Your guest account has no channels assigned. Please contact an administrator."
|
||||
id="signup_team.guest_without_channels"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Memo(SystemPermissionGate)
|
||||
|
||||
@@ -201,7 +201,7 @@ export default class SelectTeam extends React.PureComponent<Props, State> {
|
||||
openContent = (
|
||||
<div className='signup__content'>
|
||||
<div className={'form-group has-error'}>
|
||||
<label className='control-label'>{this.state.error}</label>
|
||||
<div className='control-label'>{this.state.error}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -209,12 +209,12 @@ export default class SelectTeam extends React.PureComponent<Props, State> {
|
||||
openContent = (
|
||||
<div className='signup__content'>
|
||||
<div className={'form-group has-error'}>
|
||||
<label className='control-label'>
|
||||
<div className='control-label'>
|
||||
<FormattedMessage
|
||||
id='signup_team.guest_without_channels'
|
||||
defaultMessage='Your guest account has no channels assigned. Please contact an administrator.'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -198,6 +198,7 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
|
||||
aria-label={interfaceLanguageLabelAria}
|
||||
className='control-label'
|
||||
id='changeInterfaceLanguageLabel'
|
||||
htmlFor='displayLanguage'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.languages.change'
|
||||
|
||||
@@ -385,6 +385,7 @@ exports[`components/user_settings/display/CustomThemeChooser should match, init
|
||||
>
|
||||
<label
|
||||
className="custom-label"
|
||||
htmlFor="codeThemeSelect"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Code Theme"
|
||||
@@ -538,6 +539,7 @@ exports[`components/user_settings/display/CustomThemeChooser should match, init
|
||||
>
|
||||
<label
|
||||
className="custom-label"
|
||||
htmlFor="pasteBox"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Copy to share or paste theme colors here:"
|
||||
|
||||
@@ -312,7 +312,10 @@ export class CustomThemeChooser extends React.PureComponent<Props, State> {
|
||||
className='col-sm-6 form-group'
|
||||
key={'custom-theme-key' + index}
|
||||
>
|
||||
<label className='custom-label'>
|
||||
<label
|
||||
className='custom-label'
|
||||
htmlFor='codeThemeSelect'
|
||||
>
|
||||
<FormattedMessage {...messages[element.id]}/>
|
||||
</label>
|
||||
<div
|
||||
@@ -403,7 +406,10 @@ export class CustomThemeChooser extends React.PureComponent<Props, State> {
|
||||
|
||||
const pasteBox = (
|
||||
<div className='col-sm-12'>
|
||||
<label className='custom-label'>
|
||||
<label
|
||||
className='custom-label'
|
||||
htmlFor='pasteBox'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.custom_theme.copyPaste'
|
||||
defaultMessage='Copy to share or paste theme colors here:'
|
||||
|
||||
@@ -494,14 +494,14 @@ export class UserSettingsGeneralTab extends PureComponent<Props, State> {
|
||||
inputs.push(
|
||||
<div key='currentEmailSetting'>
|
||||
<div className='form-group'>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<span className='as-bs-label col-sm-5 control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.currentEmail'
|
||||
defaultMessage='Current Email'
|
||||
/>
|
||||
</label>
|
||||
</span>
|
||||
<div className='col-sm-7'>
|
||||
<label className='control-label word-break--all text-left'>{this.state.originalEmail}</label>
|
||||
<span className='as-bs-label control-label word-break--all text-left'>{this.state.originalEmail}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
@@ -510,7 +510,10 @@ export class UserSettingsGeneralTab extends PureComponent<Props, State> {
|
||||
inputs.push(
|
||||
<div key='emailSetting'>
|
||||
<div className='form-group'>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='primaryEmail'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.newEmail'
|
||||
defaultMessage='New Email'
|
||||
@@ -535,7 +538,10 @@ export class UserSettingsGeneralTab extends PureComponent<Props, State> {
|
||||
inputs.push(
|
||||
<div key='confirmEmailSetting'>
|
||||
<div className='form-group'>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='confirmEmail'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.confirmEmail'
|
||||
defaultMessage='Confirm Email'
|
||||
@@ -559,7 +565,10 @@ export class UserSettingsGeneralTab extends PureComponent<Props, State> {
|
||||
inputs.push(
|
||||
<div key='currentPassword'>
|
||||
<div className='form-group'>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='currentPassword'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.currentPassword'
|
||||
defaultMessage='Current Password'
|
||||
@@ -813,7 +822,10 @@ export class UserSettingsGeneralTab extends PureComponent<Props, State> {
|
||||
key='firstNameSetting'
|
||||
className='form-group'
|
||||
>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='firstName'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.firstName'
|
||||
defaultMessage='First Name'
|
||||
@@ -840,7 +852,10 @@ export class UserSettingsGeneralTab extends PureComponent<Props, State> {
|
||||
key='lastNameSetting'
|
||||
className='form-group'
|
||||
>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='lastName'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.lastName'
|
||||
defaultMessage='Last Name'
|
||||
|
||||
@@ -518,7 +518,10 @@ export default class UserAccessTokenSection extends React.PureComponent<Props, S
|
||||
newTokenSection = (
|
||||
<div className='pl-3'>
|
||||
<div className='row'>
|
||||
<label className='col-sm-auto control-label pr-3'>
|
||||
<label
|
||||
className='col-sm-auto control-label pr-3'
|
||||
htmlFor='newTokenDescription'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.tokens.name'
|
||||
defaultMessage='Token Description: '
|
||||
@@ -526,6 +529,7 @@ export default class UserAccessTokenSection extends React.PureComponent<Props, S
|
||||
</label>
|
||||
<div className='col-sm-5'>
|
||||
<input
|
||||
id='newTokenDescription'
|
||||
autoFocus={true}
|
||||
ref={this.newtokendescriptionRef}
|
||||
className='form-control'
|
||||
|
||||
@@ -258,7 +258,10 @@ export class SecurityTab extends React.PureComponent<Props, State> {
|
||||
key='currentPasswordUpdateForm'
|
||||
className='form-group'
|
||||
>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='currentPassword'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.security.currentPassword'
|
||||
defaultMessage='Current Password'
|
||||
@@ -285,7 +288,10 @@ export class SecurityTab extends React.PureComponent<Props, State> {
|
||||
key='newPasswordUpdateForm'
|
||||
className='form-group'
|
||||
>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='newPassword'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.security.newPassword'
|
||||
defaultMessage='New Password'
|
||||
@@ -311,7 +317,10 @@ export class SecurityTab extends React.PureComponent<Props, State> {
|
||||
key='retypeNewPasswordUpdateForm'
|
||||
className='form-group'
|
||||
>
|
||||
<label className='col-sm-5 control-label'>
|
||||
<label
|
||||
className='col-sm-5 control-label'
|
||||
htmlFor='confirmPassword'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.security.retypePassword'
|
||||
defaultMessage='Retype New Password'
|
||||
|
||||
@@ -117,11 +117,10 @@
|
||||
}
|
||||
|
||||
.modal__error {
|
||||
display: inline-block;
|
||||
margin-top: 6px;
|
||||
color: variables.$red;
|
||||
float: left;
|
||||
font-size: 0.95em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.more-table {
|
||||
|
||||
@@ -239,24 +239,12 @@
|
||||
}
|
||||
|
||||
.file__upload {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: fit-content;
|
||||
margin: 0 10px 10px 0;
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-left: 100%;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
|
||||
&[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1089,6 +1077,12 @@
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.password-settings__preview-heading {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#error-tooltip {
|
||||
.tooltip-inner {
|
||||
max-width: none;
|
||||
|
||||
@@ -813,3 +813,10 @@
|
||||
color: rgba(var(--center-channel-color-rgb), 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.as-bs-label {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -283,6 +283,7 @@ body {
|
||||
}
|
||||
|
||||
.control-label {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7em 1em;
|
||||
border-radius: 3px;
|
||||
@@ -290,7 +291,6 @@ body {
|
||||
background: #f2f2f2;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
|
||||
&::before {
|
||||
@extend %font-awesome;
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"jsx-a11y/iframe-has-title": "warn",
|
||||
"jsx-a11y/img-redundant-alt": "warn",
|
||||
"jsx-a11y/interactive-supports-focus": "warn",
|
||||
"jsx-a11y/label-has-associated-control": "warn",
|
||||
"jsx-a11y/label-has-associated-control": "error",
|
||||
"jsx-a11y/media-has-caption": "warn",
|
||||
"jsx-a11y/mouse-events-have-key-events": "warn",
|
||||
"jsx-a11y/no-access-key": "error",
|
||||
|
||||
Ссылка в новой задаче
Block a user