diff options
Diffstat (limited to 'server/sonar-web/src/main/js/apps/organizationMembers/MembersPageHeader.tsx')
-rw-r--r-- | server/sonar-web/src/main/js/apps/organizationMembers/MembersPageHeader.tsx | 121 |
1 files changed, 98 insertions, 23 deletions
diff --git a/server/sonar-web/src/main/js/apps/organizationMembers/MembersPageHeader.tsx b/server/sonar-web/src/main/js/apps/organizationMembers/MembersPageHeader.tsx index ec540fed313..82c68eba3d6 100644 --- a/server/sonar-web/src/main/js/apps/organizationMembers/MembersPageHeader.tsx +++ b/server/sonar-web/src/main/js/apps/organizationMembers/MembersPageHeader.tsx @@ -18,35 +18,110 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; +import { connect } from 'react-redux'; import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router'; -import { translate } from '../../helpers/l10n'; +import AddMemberForm from './AddMemberForm'; +import SyncMemberForm from './SyncMemberForm'; import DeferredSpinner from '../../components/common/DeferredSpinner'; +import DocTooltip from '../../components/docs/DocTooltip'; +import NewInfoBox from '../../components/ui/NewInfoBox'; +import { sanitizeAlmId } from '../../helpers/almIntegrations'; +import { translate, translateWithParameters } from '../../helpers/l10n'; +import { getCurrentUserSetting, Store } from '../../store/rootReducer'; +import { setCurrentUserSetting } from '../../store/users'; interface Props { - children?: React.ReactNode; + dismissSyncNotifOrg: string[]; + handleAddMember: (member: T.OrganizationMember) => void; loading: boolean; + members?: T.OrganizationMember[]; + organization: T.Organization; + setCurrentUserSetting: (setting: T.CurrentUserSetting) => void; } -export default function MembersPageHeader(props: Props) { - return ( - <header className="page-header"> - <h1 className="page-title">{translate('organization.members.page')}</h1> - <DeferredSpinner loading={props.loading} /> - {props.children} - <p className="page-description"> - <FormattedMessage - defaultMessage={translate('organization.members.page.description')} - id="organization.members.page.description" - values={{ - link: ( - <Link to="/documentation/organizations/manage-team/"> - {translate('organization.members.manage_a_team')} - </Link> - ) - }} - /> - </p> - </header> - ); +export class MembersPageHeader extends React.PureComponent<Props> { + handleDismissSyncNotif = () => { + const { dismissSyncNotifOrg, organization } = this.props; + this.props.setCurrentUserSetting({ + key: 'organizations.members.dismissSyncNotif', + value: [...dismissSyncNotifOrg, organization.key].join(',') + }); + }; + + render() { + const { dismissSyncNotifOrg, members, organization } = this.props; + const memberLogins = members ? members.map(member => member.login) : []; + const isAdmin = organization.actions && organization.actions.admin; + const almKey = organization.alm && sanitizeAlmId(organization.alm.key); + const hasMemberSync = organization.alm && organization.alm.membersSync; + const showSyncNotif = + isAdmin && + organization.alm && + !hasMemberSync && + !dismissSyncNotifOrg.some(orgKey => orgKey === organization.key); + + return ( + <header className="page-header"> + <h1 className="page-title">{translate('organization.members.page')}</h1> + <DeferredSpinner loading={this.props.loading} /> + {isAdmin && ( + <div className="page-actions text-right"> + {almKey && !showSyncNotif && <SyncMemberForm organization={organization} />} + {!hasMemberSync && ( + <div className="display-inline-block spacer-left spacer-bottom"> + <AddMemberForm + addMember={this.props.handleAddMember} + memberLogins={memberLogins} + organization={organization} + /> + <DocTooltip + className="spacer-left" + doc={import(/* webpackMode: "eager" */ 'Docs/tooltips/organizations/add-organization-member.md')} + /> + </div> + )} + {almKey && + showSyncNotif && ( + <NewInfoBox + description={translate('organization.members.auto_sync_members_from_org', almKey)} + onClose={this.handleDismissSyncNotif} + title={translateWithParameters( + 'organization.members.auto_sync_with_x', + translate(almKey) + )}> + <SyncMemberForm organization={organization} /> + </NewInfoBox> + )} + </div> + )} + <div className="page-description"> + <FormattedMessage + defaultMessage={translate('organization.members.page.description')} + id="organization.members.page.description" + values={{ + link: ( + <Link to="/documentation/organizations/manage-team/"> + {translate('organization.members.manage_a_team')} + </Link> + ) + }} + /> + </div> + </header> + ); + } } + +const mapStateToProps = (state: Store) => ({ + dismissSyncNotifOrg: ( + getCurrentUserSetting(state, 'organizations.members.dismissSyncNotif') || '' + ).split(',') +}); + +const mapDispatchToProps = { setCurrentUserSetting }; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(MembersPageHeader); |