Skip to content

Commit 7082040

Browse files
committed
Fixes #623
Fixes #671 Fixes #673
1 parent 5da850c commit 7082040

17 files changed

Lines changed: 276 additions & 199 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {expect, test} from 'vitest'
2+
import {sections} from "../../utils/Connection.js";
3+
4+
test("Store outside functional component", () => {
5+
const connection = {sectionsComplete : 0};
6+
7+
expect(sections.isComplete(connection, sections.technical)).toBeFalsy();
8+
expect(sections.isComplete(connection, sections.informationProfile)).toBeFalsy();
9+
expect(sections.isComplete(connection, sections.productionStatus)).toBeFalsy();
10+
11+
sections.complete(connection, sections.technical);
12+
expect(sections.isComplete(connection, sections.technical)).toBeTruthy();
13+
expect(sections.isComplete(connection, sections.informationProfile)).toBeFalsy();
14+
expect(sections.isComplete(connection, sections.productionStatus)).toBeFalsy();
15+
16+
sections.complete(connection, sections.informationProfile);
17+
expect(sections.isComplete(connection, sections.technical)).toBeTruthy();
18+
expect(sections.isComplete(connection, sections.informationProfile)).toBeTruthy();
19+
expect(sections.isComplete(connection, sections.productionStatus)).toBeFalsy();
20+
21+
sections.complete(connection, sections.productionStatus);
22+
expect(sections.isComplete(connection, sections.technical)).toBeTruthy();
23+
expect(sections.isComplete(connection, sections.informationProfile)).toBeTruthy();
24+
expect(sections.isComplete(connection, sections.productionStatus)).toBeTruthy();
25+
26+
expect(sections.allCompleted(connection)).toBeTruthy();
27+
});

client/src/connection/ConnectionAlert.jsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ import {CONNECTION_STATUSES} from "../utils/Manage.js";
77

88

99
export const ConnectionAlert = ({
10-
user, application, setTab,
10+
user,
11+
application,
12+
setTab,
1113
connectionComplete,
1214
appInformationComplete,
1315
connectionNeedsApproval,
16+
currentOrganization,
1417
customProdTabAction = null,
1518
fullWidth = false
1619
}) => {
@@ -22,10 +25,10 @@ export const ConnectionAlert = ({
2225
return null;
2326
}
2427
let connectionsNeedActivationNames = [];
25-
if (application.signedContract && !isEmpty(application.connections)) {
28+
if ((application.signedContract || !isEmpty(currentOrganization.manageIdentifier)) && !isEmpty(application.connections)) {
2629
const names = application.connections
2730
.filter(conn =>
28-
conn.status === CONNECTION_STATUSES.COMPLETE || conn.status === CONNECTION_STATUSES.IN_PROGRESS)
31+
conn.status === CONNECTION_STATUSES.COMPLETE)
2932
.map(conn => conn.name);
3033
connectionsNeedActivationNames = splitListSemantically(names, I18n.t("forms.and"));
3134
}
@@ -37,14 +40,6 @@ export const ConnectionAlert = ({
3740
message={I18n.t("connection.welcome", {user: user.name, name: application.name})}/>
3841
)
3942
}
40-
if (connectionComplete) {
41-
return (
42-
<Alert close={() => setAlertClosed(true)}
43-
alertType={AlertType.Info}
44-
asChild={true}
45-
message={I18n.t("connection.productionConnectionHint")}/>
46-
)
47-
}
4843
if (connectionNeedsApproval && !appInformationComplete) {
4944
return (
5045
<Alert close={() => setAlertClosed(true)}
@@ -59,7 +54,7 @@ export const ConnectionAlert = ({
5954
alertType={AlertType.Warning}
6055
asChild={true}
6156
message={I18n.t("connection.productionActivationHint", {name: connectionsNeedActivationNames})}
62-
action={() => customProdTabAction ? customProdTabAction() : setTab("prod", "activate")}
57+
action={() => customProdTabAction ? customProdTabAction() : setTab("allConnections", "activate")}
6358
actionLabel={I18n.t("connection.productionActivationAction")}/>
6459
)
6560
}

client/src/connection/Connections.jsx

Lines changed: 122 additions & 155 deletions
Large diffs are not rendered by default.

client/src/connection/Connections.scss

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ $width-percentage: 75%;
9393

9494
h3 {
9595
position: relative;
96+
9697
svg.alert-triangle {
9798
fill: black;
9899
color: white;
@@ -195,23 +196,29 @@ $width-percentage: 75%;
195196

196197
}
197198

198-
.inner-right-idp {
199-
@include card(25px);
199+
.identity-providers {
200+
display: flex;
201+
flex-direction: column;
202+
gap: 20px;
203+
margin-top: 15px;
204+
padding: 15px;
205+
background-color: var(--sds--color--gray--100);
206+
border-radius: 6px;
207+
}
200208

201-
.identity-providers {
202-
display: flex;
203-
flex-direction: column;
204-
gap: 15px;
209+
.test-idp-section {
210+
211+
.switch-field {
212+
padding: 15px;
213+
border: 1px solid var(--sds--color--gray--200);
214+
border-radius: 6px;
215+
margin-top: 0;
205216
}
206217

207218
.idp {
208219
display: flex;
209220
align-items: center;
210221

211-
.idp-info {
212-
margin-left: 25px;
213-
}
214-
215222
.idp-info p:first-child {
216223
font-weight: 600;
217224
}
@@ -436,6 +443,10 @@ $width-percentage: 75%;
436443
}
437444

438445
}
446+
.disclaimer-pending-prod {
447+
font-style: italic;
448+
margin-top: 20px;
449+
}
439450

440451
.actions {
441452
display: flex;

client/src/connection/Overview.jsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,26 @@ import React from "react";
33
import I18n from "../locale/I18n";
44
import {STATUS_LINK_TYPE, StatusLink} from "../components/StatusLink.jsx";
55
import {ConnectionAlert} from "./ConnectionAlert.jsx";
6+
import {isEmpty} from "../utils/Utils.js";
67

78

89
export const Overview = ({
9-
user, application, setTab, initConnection, connectionComplete,
10-
appInformationComplete, connectionNeedsApproval,
10+
user,
11+
application,
12+
currentOrganization,
13+
setTab,
14+
initConnection,
15+
connectionComplete,
16+
appInformationComplete,
17+
connectionNeedsApproval,
1118
}) => {
1219

1320
return (
1421
<div className="application-connection-form">
1522
<ConnectionAlert application={application}
1623
user={user}
1724
setTab={setTab}
25+
currentOrganization={currentOrganization}
1826
connectionComplete={connectionComplete}
1927
connectionNeedsApproval={connectionNeedsApproval}
2028
appInformationComplete={appInformationComplete}/>
@@ -28,11 +36,12 @@ export const Overview = ({
2836
action={() => setTab("application")}
2937
disabled={false}
3038
status={appInformationComplete ? STATUS_LINK_TYPE.ACTIVE : STATUS_LINK_TYPE.PENDING}/>
39+
{isEmpty(currentOrganization.manageIdentifier) &&
3140
<StatusLink info={I18n.t("connection.production.contract")}
3241
action={() => setTab("contract")}
3342
// disabled={!appInformationComplete || !testConnectionComplete}
3443
disabled={false}
35-
status={application.signedContract ? STATUS_LINK_TYPE.ACTIVE : STATUS_LINK_TYPE.PENDING}/>
44+
status={application.signedContract ? STATUS_LINK_TYPE.ACTIVE : STATUS_LINK_TYPE.PENDING}/>}
3645
<p className={`${connectionNeedsApproval} ? "":"pending`}>
3746
{I18n.t("connection.production.disclaimer")}
3847
</p>

client/src/locale/en.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ const en = {
345345
pendingChanges: "Pending change requests",
346346
testIdP: "Test IdP's",
347347
visibility: "Visibility in the catalog",
348+
productionStatus: "Production Status",
348349
help: "Need help?",
349350
callSurf: "Plan a call with SURF",
350351
supportTicket: "Create a support ticket",
@@ -592,6 +593,16 @@ const en = {
592593
signed: "An agreement has been signed.",
593594
sign: "Sign the agreement",
594595
},
596+
productionStatusSection: {
597+
proceedHow: "How do you want to proceed?",
598+
testConnection: "First test this connection",
599+
prodConnection: "Directly request production-ready status",
600+
dummyIdP: "Activate dummy IdP's after comfirmation",
601+
next: "Save and try out",
602+
appInformationIncomplete: "Before requesting production-ready status, all the application information must be filled in",
603+
pendingProdDisclaimer:"This connection is pending production-ready status. If you want to test connections, create a new connection",
604+
prodDisclaimer:"This connection has production-ready status. If you want to test connections, create a new connection"
605+
},
595606
},
596607
testing: {
597608
newConnection: "Add new connection",

client/src/locale/nl.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ const nl = {
345345
pendingChanges: "Openstaande wijzigingsverzoeken",
346346
testIdP: "Test‑IdP's",
347347
visibility: "Zichtbaarheid in de catalogus",
348+
productionStatus: "Productie Status",
348349
help: "Hulp nodig?",
349350
callSurf: "Plan een gesprek met SURF",
350351
supportTicket: "Maak een support‑ticket",
@@ -592,6 +593,16 @@ const nl = {
592593
signed: "Er is een overeenkomst ondertekend.",
593594
sign: "Overeenkomst ondertekenen",
594595
},
596+
productionStatusSection: {
597+
proceedHow: "Hoe wilt u verder gaan?",
598+
testConnection: "Test eerst deze verbinding",
599+
prodConnection: "Vraag direct de status 'productieklaar' aan",
600+
dummyIdP: "Activeer dummy-IdP's na bevestiging",
601+
next: "Opslaan en uitproberen",
602+
appInformationIncomplete: "Voordat de status 'productieklaar' wordt aangevraagd, moet alle applicatie-informatie zijn ingevuld",
603+
pendingProdDisclaimer: "Deze koppeling wacht op de status 'gereed voor productie'. Als je koppelingen wilt testen, maak dan een nieuwe koppeling aan.",
604+
prodDisclaimer:"Deze koppeling heeft de status 'gereed voor productie'. Als je koppelingen wilt testen, maak dan een nieuwe koppeling aan.",
605+
},
595606
},
596607
testing: {
597608
newConnection: "Nieuwe koppeling toevoegen",

client/src/pages/Connection.jsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ export const Connection = () => {
9595
.some(conn => conn.status !== CONNECTION_STATUSES.OPEN),
9696
appInformationComplete: logoSectionValid(application) && contactSectionValid(application) && privacySectionValid(privacy, application)
9797
&& application.status !== APPLICATION_STATUSES.OPEN,
98-
connectionNeedsApproval: application.signedContract && !isEmpty(application.connections) &&
98+
connectionNeedsApproval: (application.signedContract || !isEmpty(currentOrganization.manageIdentifier)) && !isEmpty(application.connections) &&
9999
application.connections
100-
.some(conn => conn.status === CONNECTION_STATUSES.COMPLETE || conn.status === CONNECTION_STATUSES.IN_PROGRESS)
100+
.some(conn => conn.status === CONNECTION_STATUSES.COMPLETE)
101101
}
102102
}, [application, privacy]);
103103

@@ -133,8 +133,9 @@ export const Connection = () => {
133133
profile: application.type === "APP" ? profileOptions[0] : profileOptions[1],
134134
profileMotivation: "",
135135
allowedEntities: iDps.map(idp => idp.entityid),
136-
visibility: visibilities.visible_to_all,
137-
connectOption: connectOptions.connect_with_interaction
136+
productionStatus: visibilities.visible_to_all,
137+
connectOption: connectOptions.connect_with_interaction,
138+
sectionsComplete: 0
138139
});
139140
const newTab = "allConnections";
140141
setCurrentTab(newTab);
@@ -159,6 +160,7 @@ export const Connection = () => {
159160
case "overview": {
160161
return <Overview application={application}
161162
user={user}
163+
currentOrganization={currentOrganization}
162164
initConnection={initConnection}
163165
setTab={changeTab}
164166
connectionComplete={connectionComplete}
@@ -170,6 +172,7 @@ export const Connection = () => {
170172
return <Connections application={application}
171173
connection={connection}
172174
user={user}
175+
currentOrganization={currentOrganization}
173176
connectionComplete={connectionComplete}
174177
appInformationComplete={appInformationComplete}
175178
connectionNeedsApproval={connectionNeedsApproval}
@@ -224,10 +227,12 @@ export const Connection = () => {
224227

225228
return (
226229
<div className="application-connection-container">
227-
<ApplicationConnectionHeader tabs={tabNames.map(name => ({
228-
name: name,
229-
disabled: false
230-
}))}
230+
<ApplicationConnectionHeader tabs={tabNames
231+
.filter(name => name !== "contract" || isEmpty(currentOrganization.manageIdentifier))
232+
.map(name => ({
233+
name: name,
234+
disabled: false
235+
}))}
231236
application={application}
232237
currentTab={currentTab}
233238
setLoading={setLoading}

client/src/pages/Organization.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ const Organization = () => {
122122
if (!application.signedContract) {
123123
status = "in_progress";
124124
} else if (application.signedContract && (
125-
connection.status === CONNECTION_STATUSES.COMPLETE || connection.status === CONNECTION_STATUSES.IN_PROGRESS)) {
125+
connection.status === CONNECTION_STATUSES.COMPLETE)) {
126126
status = "ready_for_prod"
127127
} else if (!isEmpty(connection.changeRequests)) {
128128
status = "open_change_requests";

client/src/utils/Connection.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const convertClientConnectionToServer = (application, connection, arpInfo
3030
allowedEntities: connection.allowedEntities,
3131
pkce: connection.pkce,
3232
secret: connection.secret,
33-
visibility: connection.visibility,
33+
productionStatus: connection.productionStatus,
3434
connectOption: connection.connectOption,
3535
refreshTokenValidity: connection.refreshTokenValidity,
3636
claimsInIdToken: connection.claimsInIdToken,
@@ -93,3 +93,41 @@ export const connectOptions = {
9393
connect_without_interaction_without_email: "connect_without_interaction_without_email"
9494
}
9595

96+
export const sections = {
97+
pendingChanges: "pendingChanges",
98+
technical: "technical",
99+
informationProfile: "informationProfile",
100+
productionStatus: "productionStatus",
101+
overview: "overview",
102+
103+
complete(connection, section) {
104+
connection.sectionsComplete = connection.sectionsComplete | getSectionValue(section);
105+
},
106+
107+
isComplete(connection, section) {
108+
return (connection.sectionsComplete & getSectionValue(section)) !== 0;
109+
},
110+
111+
allCompleted(connection) {
112+
const all = getSectionValue(sections.technical) | getSectionValue(sections.informationProfile) | getSectionValue(sections.productionStatus);
113+
return (connection.sectionsComplete & all) === all;
114+
},
115+
116+
}
117+
118+
const getSectionValue = section => {
119+
switch (section) {
120+
case sections.technical: {
121+
return 1;
122+
}
123+
case sections.informationProfile: {
124+
return 2;
125+
}
126+
case sections.productionStatus: {
127+
return 4;
128+
}
129+
}
130+
return 0;
131+
};
132+
133+

0 commit comments

Comments
 (0)