Skip to content

Commit d6d2833

Browse files
authored
Merge pull request #2840 from objectcomputing/bugfix-2837/manage-certifications-from-report
Moved all certification related resolve() calls into the api script…
2 parents 30475ea + 860d21b commit d6d2833

File tree

3 files changed

+89
-72
lines changed

3 files changed

+89
-72
lines changed

web-ui/src/api/certification.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ const certificationUrl = '/services/certification';
55
export const getCertifications = async cookie => {
66
return resolve({
77
url: certificationUrl,
8-
headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' }
8+
headers: {
9+
'X-CSRF-Header': cookie,
10+
Accept: 'application/json',
11+
'Content-Type': 'application/json;charset=UTF-8',
12+
}
913
});
1014
};
1115

@@ -15,3 +19,42 @@ export const getCertification = async (id, cookie) => {
1519
headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' }
1620
});
1721
};
22+
23+
export const createCertification = async (data, cookie) => {
24+
return resolve({
25+
method: 'POST',
26+
url: certificationUrl,
27+
headers: {
28+
'X-CSRF-Header': cookie,
29+
Accept: 'application/json',
30+
'Content-Type': 'application/json;charset=UTF-8'
31+
},
32+
data: data,
33+
});
34+
}
35+
36+
export const updateCertification = async (id, data, cookie) => {
37+
return resolve({
38+
method: 'PUT',
39+
url: `${certificationUrl}/${id}`,
40+
headers: {
41+
'X-CSRF-Header': cookie,
42+
Accept: 'application/json',
43+
'Content-Type': 'application/json;charset=UTF-8'
44+
},
45+
data: data,
46+
});
47+
}
48+
49+
export const mergeCertification = async (sourceId, targetId, cookie) => {
50+
return resolve({
51+
method: 'POST',
52+
url: `${certificationUrl}/merge`,
53+
headers: {
54+
'X-CSRF-Header': cookie,
55+
Accept: 'application/json',
56+
'Content-Type': 'application/json;charset=UTF-8'
57+
},
58+
data: { sourceId, targetId },
59+
});
60+
}

web-ui/src/components/certifications/Certifications.jsx

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ import {
1010
} from '@mui/material';
1111
import Autocomplete from '@mui/material/Autocomplete';
1212

13-
import { resolve } from '../../api/api.js';
13+
import {
14+
getCertifications,
15+
createCertification,
16+
updateCertification,
17+
mergeCertification,
18+
} from '../../api/certification';
1419
import { AppContext } from '../../context/AppContext';
1520
import { selectCsrfToken } from '../../context/selectors';
1621
import ConfirmationDialog from '../dialogs/ConfirmationDialog';
@@ -33,6 +38,7 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
3338
const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);
3439
const [mergeDialogOpen, setMergeDialogOpen] = useState(false);
3540
const [name, setName] = useState('');
41+
const [description, setDescription] = useState('');
3642
const [selectedCertification, setSelectedCertification] = useState(null);
3743
const [selectedTarget, setSelectedTarget] = useState(null);
3844

@@ -48,20 +54,13 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
4854
setAdding(true);
4955
setBadgeUrl('');
5056
setName('');
57+
setDescription('');
5158
setSelectedCertification(null);
5259
setSelectedTarget(null);
5360
};
5461

5562
const loadCertifications = useCallback(async () => {
56-
const res = await resolve({
57-
method: 'GET',
58-
url: certificationBaseUrl,
59-
headers: {
60-
'X-CSRF-Header': csrf,
61-
Accept: 'application/json',
62-
'Content-Type': 'application/json;charset=UTF-8'
63-
}
64-
});
63+
const res = await getCertifications(csrf);
6564
if (res.error) return;
6665

6766
const certs = await res.payload.data;
@@ -78,8 +77,11 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
7877
if (csrf) loadCertifications();
7978
}, [csrf]);
8079

80+
// `exclude` is optional. If supplied, the certification name that matches
81+
// will be removed from the list of options. This is useful when merging
82+
// certifications.
8183
const certificationSelect = useCallback(
82-
(label, setSelected) => (
84+
(label, setSelected, exclude) => (
8385
<Autocomplete
8486
blurOnSelect
8587
clearOnBlur
@@ -97,10 +99,11 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
9799
}
98100
setAdding(!Boolean(foundCert));
99101
setName(foundCert.name);
102+
setDescription(foundCert.description);
100103
setBadgeUrl(foundCert.badgeUrl);
101104
setSelected(foundCert);
102105
}}
103-
options={certifications.map(cert => cert.name)}
106+
options={certifications.map(cert => cert.name).filter(name => name !== exclude)}
104107
renderInput={params => {
105108
return (
106109
<TextField
@@ -120,16 +123,7 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
120123
const deleteCertification = useCallback(async () => {
121124
selectedCertification.active = false;
122125
const { id } = selectedCertification;
123-
const res = await resolve({
124-
method: 'PUT',
125-
url: certificationBaseUrl + '/' + id,
126-
headers: {
127-
'X-CSRF-Header': csrf,
128-
Accept: 'application/json',
129-
'Content-Type': 'application/json;charset=UTF-8'
130-
},
131-
data: selectedCertification
132-
});
126+
const res = await updateCertification(id, selectedCertification, csrf);
133127
if (res.error) return;
134128

135129
setCertificationMap(map => {
@@ -141,19 +135,10 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
141135
close();
142136
}, [certificationMap, certifications, selectedCertification]);
143137

144-
const mergeCertification = useCallback(async () => {
138+
const mergeSelectedCertification = useCallback(async () => {
145139
const sourceId = selectedCertification.id;
146140
const targetId = selectedTarget.id;
147-
const res = await resolve({
148-
method: 'POST',
149-
url: certificationBaseUrl + '/merge',
150-
headers: {
151-
'X-CSRF-Header': csrf,
152-
Accept: 'application/json',
153-
'Content-Type': 'application/json;charset=UTF-8'
154-
},
155-
data: { sourceId, targetId }
156-
});
141+
const res = await mergeCertification(sourceId, targetId, csrf);
157142
if (res.error) return;
158143

159144
setCertifications(certs => certs.filter(cert => cert.id !== sourceId));
@@ -166,19 +151,13 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
166151
}, [selectedCertification, selectedTarget]);
167152

168153
const saveCertification = useCallback(async () => {
169-
const url = adding
170-
? certificationBaseUrl
171-
: certificationBaseUrl + '/' + selectedCertification.id;
172-
const res = await resolve({
173-
method: adding ? 'POST' : 'PUT',
174-
url,
175-
headers: {
176-
'X-CSRF-Header': csrf,
177-
Accept: 'application/json',
178-
'Content-Type': 'application/json;charset=UTF-8'
179-
},
180-
data: { name, badgeUrl }
181-
});
154+
let res;
155+
const data = { name, description, badgeUrl };
156+
if (adding) {
157+
res = await createCertification(data, csrf);
158+
} else {
159+
res = await updateCertification(selectedCertification.id, data, csrf);
160+
}
182161
if (res.error) return;
183162

184163
const newCert = res.payload.data;
@@ -191,7 +170,7 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
191170
);
192171
close();
193172
forceUpdate();
194-
}, [badgeUrl, certificationMap, name, selectedCertification]);
173+
}, [badgeUrl, certificationMap, name, description, selectedCertification]);
195174

196175
return (
197176
<>
@@ -209,6 +188,12 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
209188
onChange={e => setName(e.target.value)}
210189
value={name}
211190
/>
191+
<TextField
192+
label="Description"
193+
required
194+
onChange={e => setDescription(e.target.value)}
195+
value={description}
196+
/>
212197
<TextField
213198
label="Badge URL"
214199
required
@@ -253,9 +238,10 @@ const Certifications = ({ forceUpdate = () => {}, open, onClose }) => {
253238
Merge {selectedCertification?.name} Certification Into
254239
</DialogTitle>
255240
<DialogContent>
256-
{certificationSelect('Target Certification', setSelectedTarget)}
241+
{certificationSelect('Target Certification',
242+
setSelectedTarget, selectedCertification?.name)}
257243
<div className="row">
258-
<Button disabled={!selectedTarget} onClick={mergeCertification}>
244+
<Button disabled={!selectedTarget} onClick={mergeSelectedCertification}>
259245
Merge
260246
</Button>
261247
<Button

web-ui/src/components/certifications/EarnedCertificationsTable.jsx

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import {
2525
} from '@mui/material';
2626

2727
import { resolve } from '../../api/api.js';
28+
import {
29+
getCertifications,
30+
createCertification,
31+
} from '../../api/certification.js';
2832
import DatePickerField from '../date-picker-field/DatePickerField';
2933
import ConfirmationDialog from '../dialogs/ConfirmationDialog';
3034
import { AppContext } from '../../context/AppContext';
@@ -36,7 +40,6 @@ import {
3640
import { formatDate } from '../../helpers/datetime';
3741
import './EarnedCertificationsTable.css';
3842

39-
const certificationBaseUrl = '/services/certification';
4043
const earnedCertificationBaseUrl = '/services/earned-certification';
4144

4245
const newEarned = { earnedDate: formatDate(new Date()) };
@@ -83,15 +86,7 @@ const EarnedCertificationsTable = ({
8386
profiles.sort((a, b) => a.name.localeCompare(b.name));
8487

8588
const loadCertifications = useCallback(async () => {
86-
let res = await resolve({
87-
method: 'GET',
88-
url: certificationBaseUrl,
89-
headers: {
90-
'X-CSRF-Header': csrf,
91-
Accept: 'application/json',
92-
'Content-Type': 'application/json;charset=UTF-8'
93-
}
94-
});
89+
let res = await getCertifications(csrf);
9590
if (res.error) return;
9691

9792
const certs = res.payload.data ?? [];
@@ -464,20 +459,13 @@ const EarnedCertificationsTable = ({
464459
);
465460

466461
const saveCertification = useCallback(async () => {
467-
const res = await resolve({
468-
method: 'POST',
469-
url: certificationBaseUrl,
470-
headers: {
471-
'X-CSRF-Header': csrf,
472-
Accept: 'application/json',
473-
'Content-Type': 'application/json;charset=UTF-8'
474-
},
475-
data: {
462+
const res = await createCertification(
463+
{
476464
name: certificationName,
477465
description: certificationDescription,
478-
badgeUrl
479-
}
480-
});
466+
badgeUrl,
467+
},
468+
csrf);
481469
if (res.error) return;
482470

483471
const newCert = res.payload.data;

0 commit comments

Comments
 (0)