Skip to content

Commit

Permalink
WIP for #1691
Browse files Browse the repository at this point in the history
  • Loading branch information
oharsta committed Jan 3, 2025
1 parent a48edca commit a210b8f
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 72 deletions.
149 changes: 88 additions & 61 deletions client/src/components/redesign/CollaborationAdmins.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,11 @@ class CollaborationAdmins extends React.Component {
</a>
</div>
{showResendInvite &&
<div onClick={this.resendFromActionMenu(entity.id, true)}>
<Tooltip tip={I18n.t("models.orgMembers.resendInvitationTooltip")}
standalone={true}
children={<FontAwesomeIcon icon="voicemail"/>}/>
</div>}
<div onClick={this.resendFromActionMenu(entity.id, true)}>
<Tooltip tip={I18n.t("models.orgMembers.resendInvitationTooltip")}
standalone={true}
children={<FontAwesomeIcon icon="voicemail"/>}/>
</div>}
</div>);
}

Expand All @@ -437,43 +437,43 @@ class CollaborationAdmins extends React.Component {
return (
<div className="admin-actions">
{(any && isAdminOfCollaboration && !disabled) &&
<div>
<Tooltip standalone={true}
tip={disabled ? I18n.t("models.orgMembers.removeTooltipDisabled") : I18n.t("models.orgMembers.removeTooltip")}
children={<Button onClick={this.remove(true)}
small={true}
txt={I18n.t("models.orgMembers.remove")}
icon={<ThrashIcon/>}/>}/>
</div>}
<div>
<Tooltip standalone={true}
tip={disabled ? I18n.t("models.orgMembers.removeTooltipDisabled") : I18n.t("models.orgMembers.removeTooltip")}
children={<Button onClick={this.remove(true)}
small={true}
txt={I18n.t("models.orgMembers.remove")}
icon={<ThrashIcon/>}/>}/>
</div>}
{(any && (isAdminOfCollaboration || collaboration.disclose_email_information) && !disabled)
&&
<div>
<Tooltip standalone={true}
tip={disabled ? I18n.t("models.orgMembers.mailTooltipDisabled") : I18n.t("models.orgMembers.mailTooltip")}
children={<a href={`${disabled ? "" : "mailto:"}${bcc}${hrefValue}`}
className="sds--btn sds--btn--primary sds--btn--small"
style={{border: "none", cursor: "default"}}
rel="noopener noreferrer" onClick={e => {
if (disabled) {
stopEvent(e);
} else {
return true;
}
}}>
{I18n.t("models.orgMembers.mail")}<EmailIcon/>
</a>}/>

</div>}
&&
<div>
<Tooltip standalone={true}
tip={disabled ? I18n.t("models.orgMembers.mailTooltipDisabled") : I18n.t("models.orgMembers.mailTooltip")}
children={<a href={`${disabled ? "" : "mailto:"}${bcc}${hrefValue}`}
className="sds--btn sds--btn--primary sds--btn--small"
style={{border: "none", cursor: "default"}}
rel="noopener noreferrer" onClick={e => {
if (disabled) {
stopEvent(e);
} else {
return true;
}
}}>
{I18n.t("models.orgMembers.mail")}<EmailIcon/>
</a>}/>

</div>}
{(any && isAdminOfCollaboration && showResendInvite) &&
<div>
<Tooltip
tip={disabled ? I18n.t("models.orgMembers.resendTooltipDisabled") : I18n.t("models.orgMembers.resendTooltip")}
standalone={true}
children={<Button onClick={this.resend(true)}
small={true}
txt={I18n.t("models.orgMembers.resend")}
icon={<FontAwesomeIcon icon="voicemail"/>}/>}/>
</div>}
<div>
<Tooltip
tip={disabled ? I18n.t("models.orgMembers.resendTooltipDisabled") : I18n.t("models.orgMembers.resendTooltip")}
standalone={true}
children={<Button onClick={this.resend(true)}
small={true}
txt={I18n.t("models.orgMembers.resend")}
icon={<FontAwesomeIcon icon="voicemail"/>}/>}/>
</div>}

</div>);
}
Expand Down Expand Up @@ -558,6 +558,28 @@ class CollaborationAdmins extends React.Component {
return selectedMembers;
}

gotoGroup = (e, collaborationId, groupId) => {
if (e.metaKey || e.ctrlKey) {
return;
}
stopEvent(e);
const {tabChanged} = this.props;
tabChanged("groups", collaborationId, groupId);
};

renderGroups = (collaborationMembership, collaboration) => {
const groups = collaboration.groups
.filter(group => group.collaboration_memberships.some(cm => cm.user_id === collaborationMembership.user_id));
return (
<ul>
{groups.map((group, index) => <li key={index}>
<a href={`/collaborations/${collaboration.id}/groups/${group.id}`}
onClick={e => this.gotoGroup(e, collaboration.id, group.id)}>{group.name}</a>
</li>)}
</ul>
);
}

searchCallback = resultAfterSearch => {
this.setState({resultAfterSearch: resultAfterSearch});
}
Expand Down Expand Up @@ -609,15 +631,15 @@ class CollaborationAdmins extends React.Component {
const isOpen = openExpirationFields[this.getIdentifier(entity)]
return (<div className="date-field-container">
{!isOpen &&
<div className="expiration-toggle" onClick={() => this.toggleExpirationDateField(entity)}>
<div className="text-container">
{entity.expiry_date && <span className={`status ${className}`}>{status}</span>}
<span className="msg">{msg}</span>
</div>
<div className="chevron-container" onClick={() => this.toggleExpirationDateField(entity)}>
<ChevronDown/>
</div>
</div>}
<div className="expiration-toggle" onClick={() => this.toggleExpirationDateField(entity)}>
<div className="text-container">
{entity.expiry_date && <span className={`status ${className}`}>{status}</span>}
<span className="msg">{msg}</span>
</div>
<div className="chevron-container" onClick={() => this.toggleExpirationDateField(entity)}>
<ChevronDown/>
</div>
</div>}
{isOpen && <DateField value={expiryDate}
disabled={!adminOfCollaboration}
onChange={e => this.updateExpiryDate(entity, e, true)}
Expand Down Expand Up @@ -650,7 +672,7 @@ class CollaborationAdmins extends React.Component {
invites.forEach(invite => invite.invite = true);
const hideAdminColumns = !isAdminOfCollaboration || showMemberView;
let i = 0;
let columns = [
const columns = [
{
nonSortable: true,
key: "check",
Expand All @@ -667,11 +689,11 @@ class CollaborationAdmins extends React.Component {
header: "",
mapper: entity => <div className="member-icon">
{entity.invite &&
<Tooltip children={<InviteIcon/>} tip={I18n.t("tooltips.invitations")} standalone={true}/>}
<Tooltip children={<InviteIcon/>} tip={I18n.t("tooltips.invitations")} standalone={true}/>}
{(!entity.invite && entity.role === "admin") &&
<Tooltip children={<UserIcon/>} standalone={true} tip={I18n.t("tooltips.admin")}/>}
<Tooltip children={<UserIcon/>} standalone={true} tip={I18n.t("tooltips.admin")}/>}
{(!entity.invite && entity.role !== "admin") &&
<Tooltip children={<MembersIcon/>} standalone={true} tip={I18n.t("tooltips.user")}/>}
<Tooltip children={<MembersIcon/>} standalone={true} tip={I18n.t("tooltips.user")}/>}

</div>
},
Expand All @@ -696,7 +718,7 @@ class CollaborationAdmins extends React.Component {
header: I18n.t("models.users.role"),
mapper: entity => this.renderSelectRole(entity, isAdminOfCollaboration)
},
{
hideAdminColumns ? null : {
key: "expiry_date",
customSort: expiryDateCustomSort,
header: I18n.t("organisationMembership.member"),
Expand All @@ -705,25 +727,30 @@ class CollaborationAdmins extends React.Component {
const isExpired = entity.invite && isInvitationExpired(entity);
return entity.invite ?
<div className={"chip-container"}>
<Chip label={isExpired ? I18n.t("models.orgMembers.expiredAt", {date: shortDateFromEpoch(entity.expiry_date)}) :
I18n.t("models.orgMembers.inviteSend", {date: shortDateFromEpoch(entity.created_at)})}
type={isExpired ? ChipType.Status_error: ChipType.Status_info}/>
<Chip
label={isExpired ? I18n.t("models.orgMembers.expiredAt", {date: shortDateFromEpoch(entity.expiry_date)}) :
I18n.t("models.orgMembers.inviteSend", {date: shortDateFromEpoch(entity.created_at)})}
type={isExpired ? ChipType.Status_error : ChipType.Status_info}/>
</div>
: this.renderExpiryDate(entity, openExpirationFields, isAdminOfCollaboration);
}
return null;
}
},
{
key: "groups",
nonSortable: true,
hasLink: true,
header: I18n.t("organisationMembership.groups"),
mapper: entity => entity.invite ? null : this.renderGroups(entity, collaboration)
},
hideAdminColumns ? null : {
nonSortable: true,
key: "impersonate",
header: "",
mapper: this.getImpersonateMapper
},
];
if (hideAdminColumns) {
columns = columns.filter(col => col.key !== "impersonate" && col.key !== "expiry_date");
}
].filter(column => !isEmpty(column));
const doHideInvitees = hideInvitees || showMemberView;
const filteredEntities = this.filterEntities(isAdminView, members, filterValue, collaboration, doHideInvitees,
invites);
Expand Down
10 changes: 7 additions & 3 deletions client/src/components/redesign/CollaborationAdmins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@
}

&.name {
width: 35%;
width: 25%;

&.no-admin-columns {
width: 50%;
width: 40%;
}
}

Expand All @@ -94,10 +94,14 @@
}

&.expiry_date {
width: 25%;
width: 20%;
padding-left: calc(var(--sds--space--2) + 5px);
}

&.groups {
width: 15%;
}

&.impersonate {
width: 87px;
text-align: right;
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/redesign/Groups.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class Groups extends React.Component {
}

componentDidMount = callback => {
const {groupId} = this.props.match.params;
const groupId = this.props.match.params.groupId || this.props.groupId;
let selectedGroup = this.getSelectedGroup();
const {collaboration} = this.props;

Expand Down
1 change: 1 addition & 0 deletions client/src/locale/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -2372,6 +2372,7 @@ const en = {
update: "Update",
alreadyMember: "You are already a member of this CO and do not need to accept a new invitation.",
alreadyMemberHeader: "Already member",
groups: "Groups",
status: {
name: "Your membership",
active: "Active",
Expand Down
1 change: 1 addition & 0 deletions client/src/locale/nl.js
Original file line number Diff line number Diff line change
Expand Up @@ -2372,6 +2372,7 @@ const nl = {
update: "Opslaan",
alreadyMember: "je bent al een lid van deze samenwerking en je hoeft geen nieuwe uitnodiging te accepteren.",
alreadyMemberHeader: "Reeds lid",
groups: "Groepen",
status: {
name: "Je lidmaatschap",
active: "Actief",
Expand Down
26 changes: 19 additions & 7 deletions client/src/pages/CollaborationDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ class CollaborationDetail extends React.Component {
confirmationQuestion: "",
lastAdminWarning: "",
joinRequestDialogOpen: false,
socketSubscribed: false
socketSubscribed: false,
groupId: null
}
}

Expand Down Expand Up @@ -393,7 +394,10 @@ class CollaborationDetail extends React.Component {
name="admins"
label={I18n.t("home.tabs.coAdmins")}
notifier={expiredInvitations}>
<CollaborationAdmins {...this.props} collaboration={collaboration} isAdminView={true}
<CollaborationAdmins {...this.props}
collaboration={collaboration}
isAdminView={true}
tabChanged={this.tabChanged}
refresh={callback => this.componentDidMount(callback)}/>
</div>)
}
Expand All @@ -407,7 +411,10 @@ class CollaborationDetail extends React.Component {
label={I18n.t("home.tabs.members")}
readOnly={isJoinRequest}
notifier={expiredInvitations && !showMemberView}>
{!isJoinRequest && <CollaborationAdmins {...this.props} collaboration={collaboration} isAdminView={false}
{!isJoinRequest && <CollaborationAdmins {...this.props}
collaboration={collaboration}
isAdminView={false}
tabChanged={this.tabChanged}
showMemberView={showMemberView}
refresh={callback => this.componentDidMount(callback)}/>}
</div>)
Expand All @@ -417,11 +424,15 @@ class CollaborationDetail extends React.Component {
if (isJoinRequest) {
return null;
}
const {groupId} = this.state;
return (<div key="groups" name="groups"
label={I18n.t("home.tabs.groups", {count: (collaboration.groups || []).length})}
readOnly={isJoinRequest}
>
{!isJoinRequest && <Groups {...this.props} collaboration={collaboration} showMemberView={showMemberView}
{!isJoinRequest && <Groups {...this.props}
collaboration={collaboration}
groupId={groupId}
showMemberView={showMemberView}
refresh={callback => this.componentDidMount(callback)}/>}
</div>)
}
Expand Down Expand Up @@ -521,16 +532,17 @@ class CollaborationDetail extends React.Component {
}
};

tabChanged = (name, id) => {
tabChanged = (name, id, groupIdentifier = null) => {
const collId = id || this.state.collaboration.id;
const {collaboration, adminOfCollaboration, orgManager} = this.state;
const {user, config} = this.props;
if (collaboration) {
this.updateAppStore(user, config, collaboration, adminOfCollaboration, orgManager);
}
const {groupId} = this.props.match.params;
const groupId = groupIdentifier || this.props.match.params.groupId;
const groupIdPart = !isEmpty(groupId) && name === "groups" ? `/${groupId}` : "";
this.setState({tab: name}, () => this.props.history.replace(`/collaborations/${collId}/${name}${groupIdPart}`));
this.setState({tab: name, groupId: groupId}, () => this.props.history.replace(`/collaborations/${collId}/${name}${groupIdPart}`,
{groupId: groupId}));
}


Expand Down

0 comments on commit a210b8f

Please sign in to comment.