Skip to content

Commit cd8fd52

Browse files
committed
Fixes #515
1 parent 2e37066 commit cd8fd52

File tree

3 files changed

+42
-33
lines changed

3 files changed

+42
-33
lines changed

client/src/locale/en.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,7 @@ const en = {
987987
name: "App",
988988
vendor: "Vendor",
989989
connectRequested: "Requested",
990+
disconnectRequested: "Pending disconnect",
990991
connectionMade: "Connected",
991992
status: "Status",
992993
created: "Date connected",
@@ -1036,7 +1037,8 @@ const en = {
10361037
requestMember: "Request application",
10371038
requested: "Application requested",
10381039
disconnect: "Disconnect",
1039-
disconnectRequested: "Request disconnection",
1040+
disconnectRequested: "Request disconnect",
1041+
disconnectRequestedQuestion: "In order to disconnect this application from your institution, we will create a ticket for SURF support. They will disconnect the application.",
10401042
back: "← Back to other apps",
10411043
defaultAccess: "How do you want to configure default access?",
10421044
requestConnection: "A connection to this application must be approved",

client/src/pages/ApplicationDetail.jsx

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {isEmpty, stopEvent} from "../utils/Utils.js";
2929
import {useAppStore} from "../stores/AppStore.js";
3030
import {useShallow} from "zustand/react/shallow";
3131
import ConfirmationDialog from "../components/ConfirmationDialog.jsx";
32-
import {authorities, deriveAccess, hasRequestedDisconnect, isAdmin} from "../utils/Permissions.js";
32+
import {authorities, deriveAccess, isAdmin} from "../utils/Permissions.js";
3333
import InputField from "../components/InputField.jsx";
3434
import {mainMenuItems} from "../utils/MenuItems.js";
3535
import {TabHeader} from "../components/TabHeader.jsx";
@@ -78,6 +78,7 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
7878
const [memberRequestSend, setMemberRequestSend] = useState(false);
7979
const [accessible, setAccessible] = useState(false);
8080
const [readOnly, setReadOnly] = useState(true);
81+
const [pendingDisconnect, setPendingDisconnect] = useState(true);
8182
const [requestedDisconnect, setRequestedDisconnect] = useState(true);
8283
const [showPolicyOverview, setShowPolicyOverview] = useState(false);
8384
const [showPolicyDetails, setShowPolicyDetails] = useState(false);
@@ -121,13 +122,12 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
121122
return;
122123
}
123124
//See if this application is already connected
124-
const {isAccessible, isReadOnly} = deriveAccess(user, res.data.entityid);
125-
const isRequestedDisconnect = hasRequestedDisconnect(user, res.data.entityid);
125+
const {isAccessible, isReadOnly, isPendingDisconnect} = deriveAccess(user, res.data.entityid);
126126
const adminUser = isAdmin(user, authorities);
127127
setAccessible(isAccessible);
128128
setIsAdminUser(adminUser);
129129
setReadOnly(isReadOnly);
130-
setRequestedDisconnect(isRequestedDisconnect);
130+
setPendingDisconnect(isPendingDisconnect);
131131
//Update breadcrumb
132132
useAppStore.setState({
133133
breadcrumbPaths: [
@@ -362,7 +362,7 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
362362
cancel: () => cancelConfirmation(),
363363
action: () => doRequestDisconnection(false),
364364
title: null,
365-
question: null,
365+
question: I18n.t("applicationConnect.disconnectRequestedQuestion"),
366366
okButton: I18n.t("applicationConnect.disconnectRequested")
367367
});
368368
} else {
@@ -540,6 +540,26 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
540540
return renderDetailsApp();
541541
}
542542

543+
const chipTypeForConnectionStatus = () => {
544+
if (readOnly) {
545+
return ChipType.Status_error;
546+
}
547+
if (pendingDisconnect) {
548+
return ChipType.Status_warning;
549+
}
550+
return ChipType.Status_info;
551+
}
552+
553+
const translationForConnectionStatus = () => {
554+
if (readOnly) {
555+
return I18n.t("accessibleApps.connectRequested");
556+
}
557+
if (pendingDisconnect) {
558+
return I18n.t("accessibleApps.disconnectRequested");
559+
}
560+
return I18n.t("accessibleApps.connectionMade");
561+
}
562+
543563
const renderAccessibleApp = () => {
544564
return (
545565
<>
@@ -558,13 +578,13 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
558578
</div>
559579
</div>
560580
<div className="accessible-options">
561-
<Chip type={readOnly ? ChipType.Status_error : ChipType.Status_info}
562-
label={I18n.t(`accessibleApps.${readOnly ? "connectRequested" : "connectionMade"}`)}/>
563-
{(!readOnly && currentOrganization.manageIdentifier && isAdminUser) &&
564-
<Button onClick={() => doRequestDisconnection(true)}
565-
disabled={requestedDisconnect}
566-
type={ButtonType.DestructiveSecondary}
567-
txt={I18n.t(`applicationConnect.${requestedDisconnect ? "disconnectRequested" : "disconnect"}`)}/>}
581+
<Chip type={chipTypeForConnectionStatus()}
582+
label={translationForConnectionStatus()}/>
583+
{(!readOnly && currentOrganization.manageIdentifier && isAdminUser && !pendingDisconnect)
584+
&& <Button onClick={() => doRequestDisconnection(true)}
585+
type={ButtonType.DestructiveSecondary}
586+
txt={I18n.t("applicationConnect.disconnect")}/>
587+
}
568588
</div>
569589
</div>
570590
</TabHeader>

client/src/utils/Permissions.js

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export const hasApplicationDeleteAccess = (user, application) => {
7878
}
7979

8080
export const deriveAccess = (user, spEntityId) => {
81-
let isAccessible = false, isReadOnly = false;
81+
let isAccessible = false, isReadOnly = false, isPendingDisconnect = false;
8282
if (isEmpty(user.identityProvider)) {
8383
//External user
8484
return {isAccessible, isReadOnly};
@@ -94,26 +94,13 @@ export const deriveAccess = (user, spEntityId) => {
9494
cr.pathUpdates.allowedEntities.name === spEntityId
9595
);
9696
}
97+
isPendingDisconnect = user.changeRequests.some(cr =>
98+
cr.requestType === CHANGE_REQUEST_TYPE.UNLINK_REQUEST &&
99+
cr.pathUpdateType === "REMOVAL" &&
100+
cr.pathUpdates.allowedEntities.name === spEntityId
101+
);
97102

98-
return {isAccessible, isReadOnly};
99-
}
100-
101-
export const hasRequestedDisconnect = (user, spEntityId) => {
102-
if (isEmpty(user.identityProvider)) {
103-
//External user
104-
return false;
105-
}
106-
const allowedEntities = user.identityProvider.data.allowedEntities.map(e => e.name);
107-
if (allowedEntities.includes(spEntityId)) {
108-
//already connected
109-
return false;
110-
}
111-
user.changeRequests.some(cr =>
112-
cr.requestType === CHANGE_REQUEST_TYPE.LINK_REQUEST &&
113-
cr.pathUpdateType === "REMOVAL" &&
114-
cr.pathUpdates.allowedEntities.name === spEntityId
115-
);
116-
103+
return {isAccessible, isReadOnly, isPendingDisconnect};
117104
}
118105

119106
export const isAdmin = (user, authorities) => {

0 commit comments

Comments
 (0)