Skip to content

Commit 34ed5b0

Browse files
committed
Fixes #483
1 parent dc152e0 commit 34ed5b0

File tree

13 files changed

+239
-152
lines changed

13 files changed

+239
-152
lines changed

client/src/App.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, {useEffect, useState} from 'react'
22
import {Loader} from "@surfnet/sds";
33
import './App.scss';
44
import {Navigate, Route, Routes, useLocation, useNavigate} from "react-router-dom";
5-
import {arp, configuration, csrf, me, privacy} from "./api/index.js";
5+
import {allowedAttributes, arp, configuration, csrf, me, privacy} from "./api/index.js";
66
import {useAppStore} from "./stores/AppStore.js";
77
import {Flash} from "./components/Flash.jsx";
88
import {Header} from "./components/Header.jsx";
@@ -65,12 +65,13 @@ const App = () => {
6565
useEffect(() => {
6666
csrf().then(token => {
6767
useAppStore.setState(() => ({csrfToken: token.token}));
68-
Promise.all([configuration(), arp(), privacy()])
68+
Promise.all([configuration(), arp(), privacy(), allowedAttributes()])
6969
.then(res => {
7070
useAppStore.setState(() => ({
7171
config: res[0],
7272
arp: res[1],
73-
privacy: res[2]
73+
privacy: res[2],
74+
allowedAttributes: res[3]
7475
}));
7576
setIsAuthenticated(res[0].authenticated);
7677
if (res[0].authenticated) {

client/src/locale/en.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,13 +1034,11 @@ const en = {
10341034
request: "Request connection",
10351035
requestMember: "Request application",
10361036
back: "← Back to other apps",
1037-
defaultAccess: "Hoe wil je default toegang instellen?",
1037+
defaultAccessTitle: "Koppelen aan {{name}}",
10381038
requestConnection: "Koppeling met deze applicatie moet worden aangevraagd",
10391039
requestConnectionInfo: "De leverancier van deze applicatie ontvangt en beoordeelt de aanvraag. ",
1040-
access: {
1041-
all: "Iedereen van de {{orgName}} heeft direct automatisch toegang",
1042-
some: "Pas toegangsregels toe"
1043-
},
1040+
defaultAccessInfo: "Deze applicatie is direct koppelbaar, er is geen toestemming van de leverancier voor nodig.",
1041+
defaultAccessInfo2: "Na de koppeling kan de toegang tot de applicatie direct worden ingesteld.",
10441042
memberRequestInfo: {
10451043
info:"Om een applicatie gekoppelde te krijgen met het SURF Access platform, moet akkoord gegeven worden worden door de SURF Access Verantwoordelijke van de {{orgName}} organisatie.",
10461044
subInfo:"Geef hieronder aan waarom je deze applicatie geactiveerd wil hebben. Wij versturen het bericht naar hem of haar, je ontvangt zelf ook een kopie."
@@ -1061,9 +1059,11 @@ const en = {
10611059
cancelRequestTitle: "Cancel the request.",
10621060
cancelRequestQuestion: "Are you sure you don't want to have access to this application? The request will be withdrawn.",
10631061
config: "⚡️ Configure automatic access based on attributes",
1062+
edit: "Maintain policies",
10641063
accessFor: "There is access for:",
1065-
everyBody: "Everybody from {{name}}",
1066-
notEveryBody: "Not everybody from {{name}}",
1064+
everyBody: "Everybody from {{name}} has access",
1065+
notEveryBody: "Automatic access is limited",
1066+
policies: "{{nbr}} policies active",
10671067
noAccessFor: "No access for:",
10681068
noOneGroups: "There are no groups excluded from access",
10691069
groupsPresent: "There are certain groups excluded from access",
@@ -1080,10 +1080,11 @@ const en = {
10801080
eduIDOnly: "eduID only",
10811081
everyIdp: "any IdP",
10821082
backToAccess: "← back to access",
1083-
authorizationRules: "Authorization rules for:",
1083+
authorizationRules: "Authorization rules",
10841084
noPolicies: "No authorization rules have been configured yet",
10851085
newPolicy: "New authorization rule",
10861086
editPolicy: "Edit authorization rule",
1087+
new: "New policy",
10871088
active: "Active",
10881089
paused: "Paused",
10891090
activate: "Activate",
@@ -1113,13 +1114,21 @@ const en = {
11131114
denyPlaceholder: "Type your descriptive message",
11141115
submitNew: "Save and activate",
11151116
submitExisting: "Update",
1117+
breakdown: {
1118+
if: "If",
1119+
when: "When"
1120+
},
11161121
flash: {
11171122
created: "Policy {{name}} has been created and is ready for use",
11181123
updated: "Policy {{name}} has been updated",
11191124
deleted: "Policy {{name}} has been deleted",
1125+
paused: "Policy {{name}} has been paused",
1126+
activated: "Policy {{name}} has been activated",
11201127
},
11211128
confirmation: {
1122-
deleteQuestion: "Are you sure you want to delete this policy?"
1129+
deleteQuestion: "Are you sure you want to delete this policy?",
1130+
activateQuestion: "Are you sure you want to activate this policy?",
1131+
pauseQuestion: "Are you sure you want to pause this policy? The policy will no longer be evaluated.",
11231132
}
11241133
},
11251134
error: {

client/src/pages/ApplicationDetail.jsx

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,7 @@ import I18n from "../locale/I18n.js";
1010
import ExternalLinkIcon from "../icons/external-link.svg";
1111
import NotAllowedIcon from "../icons/not-allowed.svg";
1212
import {useNavigate, useParams} from "react-router-dom";
13-
import {
14-
Alert,
15-
AlertType,
16-
Button,
17-
ButtonIconPlacement,
18-
ButtonType,
19-
Chip,
20-
ChipType,
21-
Loader,
22-
RadioOptions,
23-
RadioOptionsOrientation
24-
} from "@surfnet/sds";
13+
import {Alert, AlertType, Button, ButtonIconPlacement, ButtonType, Chip, ChipType, Loader} from "@surfnet/sds";
2514
import StudentPng from "../icons/student2.png";
2615
import PlaceHolderImage from "@surfnet/sds/icons/placeholder-image.svg";
2716
import ArrowLeftIcon from "@surfnet/sds/icons/functional-icons/arrow-left-2.svg";
@@ -80,7 +69,6 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
8069
const [connectWithoutInteraction, setConnectWithoutInteraction] = useState(false);
8170
const [isAdminUser, setIsAdminUser] = useState(false);
8271
const [confirmation, setConfirmation] = useState({});
83-
const [accessChoice, setAccessChoice] = useState("ALL");
8472
const [confirmationModalOption, setConfirmationModalOption] = useState(null);
8573
const [message, setMessage] = useState("");
8674
const [memberRequestSend, setMemberRequestSend] = useState(false);
@@ -103,6 +91,7 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
10391
}
10492
newCurrentPolicy.data.attributes = groupByValues([...newCurrentPolicy.data.attributes]);
10593
}
94+
window.scrollTo({top: 0, behavior: "smooth"});
10695
setCurrentPolicy(newCurrentPolicy);
10796
setShowPolicyDetails(true);
10897
navigate(`/application-detail/${manageType}/${manageId}/details/${policyIdentifier}`);
@@ -223,19 +212,9 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
223212
if (confirmationModalOption === confirmationModalOptions.makeConnection) {
224213
return (
225214
<div className="connect-options-container">
226-
<RadioOptions name={"access"}
227-
label={I18n.t("applicationConnect.defaultAccess")}
228-
value={accessChoice}
229-
onChange={e => {
230-
const newValue = e.target.id.replace("access_", "").toUpperCase();
231-
setAccessChoice(newValue);
232-
}}
233-
isMultiple={true}
234-
labels={["ALL", "SOME"]}
235-
labelResolver={label => I18n.t(`applicationConnect.access.${label.toLowerCase()}`, {
236-
orgName: providerName(I18n.locale, user.identityProvider)
237-
})}
238-
orientation={RadioOptionsOrientation.column}/>
215+
<h3>{I18n.t("applicationConnect.defaultAccessTitle", {name: providerName(I18n.locale, serviceProvider)})}</h3>
216+
<p>{I18n.t("applicationConnect.defaultAccessInfo")}</p>
217+
<p>{I18n.t("applicationConnect.defaultAccessInfo2")}</p>
239218
</div>
240219
);
241220
} else if (confirmationModalOption === confirmationModalOptions.requestConnectionByMember) {
@@ -271,7 +250,6 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
271250
const cancelConfirmation = () => {
272251
setConfirmation({});
273252
setMessage("");
274-
setAccessChoice("ALL")
275253
}
276254

277255
const cancelConnectionRequest = (withConfirmation, e) => {
@@ -309,7 +287,7 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
309287
action: () => doRequestConnection(false, newModalOption),
310288
title: null,
311289
question: null,
312-
okButton: I18n.t(!isAdminUser ? "applicationConnect.sendMessage" : "forms.proceed")
290+
okButton: I18n.t(!isAdminUser ? "applicationConnect.sendMessage" : "applicationConnect.connect")
313291
});
314292
} else {
315293
cancelConfirmation();
@@ -406,7 +384,6 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
406384
}
407385
{showPolicyOverview &&
408386
<PolicyOverview
409-
serviceProvider={serviceProvider}
410387
policies={policies}
411388
backToAccess={e => backToAccess(e, "")}
412389
policyDetails={toPolicyDetail}
@@ -427,28 +404,18 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
427404
setShowPolicyOverview(true);
428405
navigate(`/application-detail/${manageType}/${manageId}/overview`);
429406
}}
430-
txt={I18n.t("forms.edit")}/>
407+
txt={I18n.t("appAccess.edit")}/>
431408
</div>
432-
<p>{I18n.t("appAccess.accessFor")}</p>
433409
<div className="access-card large">
434410
<h4>{I18n.t(`appAccess.${isEmpty(policies) ? "everyBody" : "notEveryBody"}`,
435411
{name: providerOrganizationName(I18n.locale, serviceProvider)})}</h4>
412+
{!isEmpty(policies) &&
413+
<Chip type={ChipType.Status_info}
414+
label={I18n.t("appAccess.policies", {nbr: policies.length})}
415+
className={"policies-active"}/>
416+
}
436417
{renderLogo(user.identityProvider.data.metaDataFields)}
437418
</div>
438-
<p>{I18n.t(`appAccess.${isEmpty(policies) ? "noAccessFor" : "accessFor"}`)}</p>
439-
{isEmpty(policies) && <>
440-
<div className="access-card grey">
441-
{I18n.t("appAccess.noOneGroups")}
442-
</div>
443-
</>}
444-
{!isEmpty(policies) && <>
445-
{policies.map((policy, index) =>
446-
<div key={index} className="access-card large">
447-
{policy.data.name}
448-
449-
</div>)}
450-
451-
</>}
452419
</InfoBlock>
453420
<InfoBlock className="no-gap">
454421
<div className="grouped">

client/src/pages/ApplicationDetail.scss

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ div.application-detail-container {
285285

286286
.app-access-central {
287287
width: 65%;
288+
289+
.sds--chips.policies-active {
290+
margin: 0 auto;
291+
background-color: var(--sl-color-warning);
292+
color: white;
293+
}
288294
}
289295

290296
.app-access-decentral {
@@ -334,15 +340,15 @@ div.application-detail-container {
334340
.access-card {
335341
background: white;
336342
margin: 10px 0;
337-
border: 1px solid var(--sl-color-grey-400);
343+
border: 1px solid var(--sl-color-secondary-400);
338344
border-radius: 10px;
339345
display: flex;
340346
align-items: center;
341347
padding: 8px;
342348
width: 100%;
343349

344350
&.grey {
345-
background-color: var(--sl-color-grey-400);
351+
background-color: var(--sds--color--gray--background);
346352
font-style: italic;
347353
}
348354

client/src/pages/Connection.jsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {AppTeamManagement} from "../application/AppTeamManagement.jsx";
2121
import {connectOptions, visibilities} from "../utils/Connection.js";
2222
import {isEmpty} from "../utils/Utils.js";
2323
import {mainMenuItems} from "../utils/MenuItems.js";
24+
import {useShallow} from "zustand/react/shallow";
2425

2526
const tabNames = ["overview", "testing", "prod", "application", "contract", "appteam"]
2627

@@ -31,7 +32,12 @@ const protocolOptions = Object.values(PROTOCOLS).map(protocol => ({
3132

3233
export const Connection = () => {
3334
const {applicationId, tab = "overview", connectionId} = useParams();
34-
const {user, config, arp, privacy} = useAppStore(state => state);
35+
const {user, config, arp, privacy} = useAppStore(useShallow(state => ({
36+
user: state.user,
37+
config: state.config,
38+
arp: state.arp,
39+
privacy: state.privacy,
40+
})));
3541

3642
const [application, setApplication] = useState({organization: {}});
3743
const [profileOptions, setProfileOptions] = useState([]);
@@ -63,8 +69,11 @@ export const Connection = () => {
6369
useAppStore.setState({
6470
breadcrumbPaths: [
6571
{path: "/home", value: I18n.t("breadCrumb.access"), menuItemName: mainMenuItems.home},
66-
{path: `/organization/${res.organization.id}`, value: I18n.t(`navigation.${mainMenuItems.yourApps}`),
67-
menuItemName: mainMenuItems.yourApps},
72+
{
73+
path: `/organization/${res.organization.id}`,
74+
value: I18n.t(`navigation.${mainMenuItems.yourApps}`),
75+
menuItemName: mainMenuItems.yourApps
76+
},
6877
{value: res.name}
6978
]
7079
});
@@ -252,11 +261,11 @@ export const Connection = () => {
252261
return (
253262
<div className="application-connection-container">
254263
<ApplicationConnectionHeader tabs={tabNames.map(name => ({
255-
name: name,
256-
disabled:
257-
(name === "prod" && !testConnectionComplete) ||
258-
(name === "application" && false) || //!testConnectionComplete) ||
259-
(name === "contract" && false)//!productionConnectionComplete)
264+
name: name,
265+
disabled:
266+
(name === "prod" && !testConnectionComplete) ||
267+
(name === "application" && false) || //!testConnectionComplete) ||
268+
(name === "contract" && false)//!productionConnectionComplete)
260269
}))}
261270
application={application}
262271
currentTab={currentTab}

0 commit comments

Comments
 (0)