PLT-4332 Position field for Users (#4632)
* Add User.Position field to store & model. * GOFMT * Add Position to user settings. * Unit tests. * Add position to profile popup. * i18n * Fix log message for invalid position. * Add Position field attribute to LDAP config. * Add Position field attribute to SAML config. * Reword empty position message. * Change Position Max Length to 35. * Better invalid position error message. * Add new fields to config.json. * Ensure position is never longer than max when displayed. * Hard limit of 64 chars with soft limit still 35 * Put field with other attributes.
Этот коммит содержится в:
коммит произвёл
enahum
родитель
9735854503
Коммит
8406e854aa
@@ -69,6 +69,10 @@ const holders = defineMessages({
|
||||
close: {
|
||||
id: 'user.settings.general.close',
|
||||
defaultMessage: 'Close'
|
||||
},
|
||||
position: {
|
||||
id: 'user.settings.general.position',
|
||||
defaultMessage: 'Position'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -85,6 +89,7 @@ class UserSettingsGeneralTab extends React.Component {
|
||||
this.submitEmail = this.submitEmail.bind(this);
|
||||
this.submitUser = this.submitUser.bind(this);
|
||||
this.submitPicture = this.submitPicture.bind(this);
|
||||
this.submitPosition = this.submitPosition.bind(this);
|
||||
|
||||
this.updateUsername = this.updateUsername.bind(this);
|
||||
this.updateFirstName = this.updateFirstName.bind(this);
|
||||
@@ -94,6 +99,7 @@ class UserSettingsGeneralTab extends React.Component {
|
||||
this.updateConfirmEmail = this.updateConfirmEmail.bind(this);
|
||||
this.updatePicture = this.updatePicture.bind(this);
|
||||
this.updateSection = this.updateSection.bind(this);
|
||||
this.updatePosition = this.updatePosition.bind(this);
|
||||
|
||||
this.state = this.setupInitialState(props);
|
||||
}
|
||||
@@ -249,6 +255,22 @@ class UserSettingsGeneralTab extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
submitPosition(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const user = Object.assign({}, this.props.user);
|
||||
const position = this.state.position.trim();
|
||||
|
||||
if (user.position === position) {
|
||||
this.updateSection('');
|
||||
return;
|
||||
}
|
||||
|
||||
user.position = position;
|
||||
|
||||
this.submitUser(user, Constants.UserUpdateEvents.Position, false);
|
||||
}
|
||||
|
||||
updateUsername(e) {
|
||||
this.setState({username: e.target.value});
|
||||
}
|
||||
@@ -265,6 +287,10 @@ class UserSettingsGeneralTab extends React.Component {
|
||||
this.setState({nickname: e.target.value});
|
||||
}
|
||||
|
||||
updatePosition(e) {
|
||||
this.setState({position: e.target.value});
|
||||
}
|
||||
|
||||
updateEmail(e) {
|
||||
this.setState({email: e.target.value});
|
||||
}
|
||||
@@ -302,6 +328,7 @@ class UserSettingsGeneralTab extends React.Component {
|
||||
firstName: user.first_name,
|
||||
lastName: user.last_name,
|
||||
nickname: user.nickname,
|
||||
position: user.position,
|
||||
email: user.email,
|
||||
confirmEmail: '',
|
||||
picture: null,
|
||||
@@ -936,6 +963,99 @@ class UserSettingsGeneralTab extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let positionSection;
|
||||
if (this.props.activeSection === 'position') {
|
||||
let extraInfo;
|
||||
let submit = null;
|
||||
if ((this.props.user.auth_service === 'ldap' || this.props.user.auth_service === Constants.SAML_SERVICE) && global.window.mm_config.PositionAttributeSet === 'true') {
|
||||
extraInfo = (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.field_handled_externally'
|
||||
defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so though your login provider.'
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
let positionLabel = (
|
||||
<FormattedMessage
|
||||
id='user.settings.general.position'
|
||||
defaultMessage='Position'
|
||||
/>
|
||||
);
|
||||
if (Utils.isMobile()) {
|
||||
positionLabel = '';
|
||||
}
|
||||
|
||||
inputs.push(
|
||||
<div
|
||||
key='positionSetting'
|
||||
className='form-group'
|
||||
>
|
||||
<label className='col-sm-5 control-label'>{positionLabel}</label>
|
||||
<div className='col-sm-7'>
|
||||
<input
|
||||
className='form-control'
|
||||
type='text'
|
||||
onChange={this.updatePosition}
|
||||
value={this.state.position}
|
||||
maxLength={Constants.MAX_POSITION_LENGTH}
|
||||
autoCapitalize='off'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
extraInfo = (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='user.settings.general.positionExtra'
|
||||
defaultMessage='Tell your teammates what you do.'
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
|
||||
submit = this.submitPosition;
|
||||
}
|
||||
|
||||
positionSection = (
|
||||
<SettingItemMax
|
||||
title={formatMessage(holders.position)}
|
||||
inputs={inputs}
|
||||
submit={submit}
|
||||
server_error={serverError}
|
||||
client_error={clientError}
|
||||
updateSection={(e) => {
|
||||
this.updateSection('');
|
||||
e.preventDefault();
|
||||
}}
|
||||
extraInfo={extraInfo}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
let describe = '';
|
||||
if (user.position) {
|
||||
describe = user.position;
|
||||
} else {
|
||||
describe = (
|
||||
<FormattedMessage
|
||||
id='user.settings.general.emptyPosition'
|
||||
defaultMessage="Click 'Edit' to add your job title / position"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
positionSection = (
|
||||
<SettingItemMin
|
||||
title={formatMessage(holders.position)}
|
||||
describe={describe}
|
||||
updateSection={() => {
|
||||
this.updateSection('position');
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const emailSection = this.createEmailSection();
|
||||
|
||||
let pictureSection;
|
||||
@@ -1030,6 +1150,8 @@ class UserSettingsGeneralTab extends React.Component {
|
||||
<div className='divider-light'/>
|
||||
{nicknameSection}
|
||||
<div className='divider-light'/>
|
||||
{positionSection}
|
||||
<div className='divider-light'/>
|
||||
{emailSection}
|
||||
<div className='divider-light'/>
|
||||
{pictureSection}
|
||||
|
||||
Ссылка в новой задаче
Block a user