eionet2-dashboard 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.fx/configs/azure.parameters.Prod_EEA.json +15 -0
- package/.fx/configs/azure.parameters.dev.json +15 -0
- package/.fx/configs/config.Prod_EEA.json +10 -0
- package/.fx/configs/config.dev.json +10 -0
- package/.fx/configs/projectSettings.json +83 -0
- package/.fx/states/state.Prod_EEA.json +47 -0
- package/.fx/states/state.dev.json +47 -0
- package/.vscode/launch.json +91 -0
- package/.vscode/settings.json +6 -0
- package/.vscode/tasks.json +63 -0
- package/CHANGELOG.md +140 -0
- package/Jenkinsfile +166 -0
- package/LICENSE.md +9 -0
- package/README.md +55 -0
- package/api/.funcignore +11 -0
- package/api/extensions.csproj +11 -0
- package/api/getGraphData/function.json +27 -0
- package/api/getGraphData/index.js +147 -0
- package/api/host.json +11 -0
- package/api/package-lock.json +1546 -0
- package/api/package.json +17 -0
- package/api/proxies.json +4 -0
- package/package.json +25 -0
- package/tabs/.env.teamsfx.Prod_EEA +11 -0
- package/tabs/.env.teamsfx.dev +11 -0
- package/tabs/.eslintrc.json +48 -0
- package/tabs/.prettierrc +7 -0
- package/tabs/.stylelintrc.json +6 -0
- package/tabs/babel.config.js +3 -0
- package/tabs/package-lock.json +15564 -0
- package/tabs/package.json +88 -0
- package/tabs/public/auth-end.html +76 -0
- package/tabs/public/auth-start.html +178 -0
- package/tabs/public/deploy.png +0 -0
- package/tabs/public/favicon.ico +0 -0
- package/tabs/public/hello.png +0 -0
- package/tabs/public/index.html +20 -0
- package/tabs/public/publish.png +0 -0
- package/tabs/src/components/App.jsx +36 -0
- package/tabs/src/components/CustomColumnResizeIcon.jsx +68 -0
- package/tabs/src/components/CustomDrawer.jsx +51 -0
- package/tabs/src/components/EventDialogTitle.jsx +29 -0
- package/tabs/src/components/HtmlBox.jsx +18 -0
- package/tabs/src/components/Privacy.jsx +17 -0
- package/tabs/src/components/ResizableGrid.jsx +44 -0
- package/tabs/src/components/Tab.jsx +477 -0
- package/tabs/src/components/Tab.scss +138 -0
- package/tabs/src/components/TabConfig.jsx +51 -0
- package/tabs/src/components/TabPanel.jsx +29 -0
- package/tabs/src/components/TermsOfUse.jsx +17 -0
- package/tabs/src/components/UnderConstruction.jsx +24 -0
- package/tabs/src/components/UserMenu.jsx +109 -0
- package/tabs/src/components/_variables.scss +10 -0
- package/tabs/src/components/activity/Activity.jsx +301 -0
- package/tabs/src/components/activity/ConsultationList.jsx +297 -0
- package/tabs/src/components/activity/EventList.jsx +463 -0
- package/tabs/src/components/activity/GroupsTags.jsx +26 -0
- package/tabs/src/components/activity/Reporting.jsx +13 -0
- package/tabs/src/components/activity/activity.scss +153 -0
- package/tabs/src/components/event_rating/EventRating.jsx +92 -0
- package/tabs/src/components/event_rating/EventRatingDialog.jsx +46 -0
- package/tabs/src/components/event_registration/Approval.jsx +80 -0
- package/tabs/src/components/event_registration/ApprovalDialog.jsx +30 -0
- package/tabs/src/components/event_registration/ApprovalList.jsx +62 -0
- package/tabs/src/components/event_registration/EventRegistration.jsx +214 -0
- package/tabs/src/components/lib/useData.js +33 -0
- package/tabs/src/components/lib/useGraph.js +39 -0
- package/tabs/src/components/lib/useTeamsFx.js +55 -0
- package/tabs/src/components/my_country/AtAGlance.jsx +151 -0
- package/tabs/src/components/my_country/CountryProgress.jsx +92 -0
- package/tabs/src/components/my_country/DataReporters.jsx +13 -0
- package/tabs/src/components/my_country/GroupView.jsx +54 -0
- package/tabs/src/components/my_country/GroupsBoard.jsx +52 -0
- package/tabs/src/components/my_country/IndicatorCard.jsx +60 -0
- package/tabs/src/components/my_country/ManagementBoard.jsx +109 -0
- package/tabs/src/components/my_country/MyCountry.jsx +186 -0
- package/tabs/src/components/my_country/ProgressGauge.jsx +125 -0
- package/tabs/src/components/my_country/ScientificCommittee.jsx +13 -0
- package/tabs/src/components/my_country/YearlyProgress.jsx +41 -0
- package/tabs/src/components/my_country/my_country.scss +81 -0
- package/tabs/src/components/publications/Publications.jsx +13 -0
- package/tabs/src/components/self_service/UserEdit.jsx +334 -0
- package/tabs/src/components/self_service/UserEdit.scss +107 -0
- package/tabs/src/data/apiProvider.js +153 -0
- package/tabs/src/data/constants.json +7 -0
- package/tabs/src/data/hooks/useConfiguration.js +18 -0
- package/tabs/src/data/icsHelper.js +38 -0
- package/tabs/src/data/messages.json +39 -0
- package/tabs/src/data/provider.js +199 -0
- package/tabs/src/data/selfServiceProvider.js +59 -0
- package/tabs/src/data/selfServiceSharepointProvider.js +68 -0
- package/tabs/src/data/sharepointProvider.js +729 -0
- package/tabs/src/data/validator.js +25 -0
- package/tabs/src/data/validator.test.js +9 -0
- package/tabs/src/index.css +16 -0
- package/tabs/src/index.jsx +6 -0
- package/tabs/src/static/images/teams-icon.svg +1 -0
- package/tabs/src/utils/uiHelper.js +6 -0
- package/templates/appPackage/aad.template.json +133 -0
- package/templates/appPackage/manifest.template.json +58 -0
- package/templates/appPackage/resources/color.png +0 -0
- package/templates/appPackage/resources/outline.png +0 -0
- package/templates/azure/config.bicep +27 -0
- package/templates/azure/main.bicep +20 -0
- package/templates/azure/provision/frontendHosting.bicep +23 -0
- package/templates/azure/provision/function.bicep +82 -0
- package/templates/azure/provision/identity.bicep +14 -0
- package/templates/azure/provision/simpleAuth.bicep +44 -0
- package/templates/azure/provision.bicep +58 -0
- package/templates/azure/teamsFx/function.bicep +76 -0
- package/templates/azure/teamsFx/simpleAuth.bicep +43 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { apiGet, getConfiguration, apiPost, logInfo, logError } from './apiProvider';
|
|
2
|
+
import { getSPUserByMail, getADUserId, getOrganisationList } from './sharepointProvider';
|
|
3
|
+
|
|
4
|
+
let _profile = undefined;
|
|
5
|
+
export async function getMe() {
|
|
6
|
+
if (!_profile) {
|
|
7
|
+
const config = await getConfiguration(),
|
|
8
|
+
response = await apiGet(
|
|
9
|
+
'me?$select=id,displayName,mail,mobilePhone,country,givenName,surname',
|
|
10
|
+
'user',
|
|
11
|
+
),
|
|
12
|
+
groups = await apiGet('me/memberOf', 'user');
|
|
13
|
+
|
|
14
|
+
const myProfile = response.graphClientMessage;
|
|
15
|
+
if (myProfile) {
|
|
16
|
+
const userData = await getUserByMail(myProfile.mail);
|
|
17
|
+
if (userData.IsValid) {
|
|
18
|
+
let spUser = userData.SharepointUser;
|
|
19
|
+
|
|
20
|
+
if (spUser) {
|
|
21
|
+
const organisations = await getOrganisationList(spUser.fields.Country),
|
|
22
|
+
organisation = organisations.find(
|
|
23
|
+
(o) => o.content === spUser.fields.OrganisationLookupId,
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
spUser.fields.Membership && spUser.fields.Membership.sort();
|
|
27
|
+
spUser.fields.OtherMemberships && spUser.fields.OtherMemberships.sort();
|
|
28
|
+
|
|
29
|
+
_profile = {
|
|
30
|
+
Title: spUser.fields.Title,
|
|
31
|
+
Phone: spUser.fields.Phone,
|
|
32
|
+
Email: spUser.fields.Email,
|
|
33
|
+
Country: spUser.fields.Country,
|
|
34
|
+
Memberships: spUser.fields.Membership,
|
|
35
|
+
OtherMemberships: spUser.fields.OtherMemberships,
|
|
36
|
+
FirstName: userData.ADUser.givenName,
|
|
37
|
+
LastName: userData.ADUser.surname,
|
|
38
|
+
Gender: spUser.fields.Gender,
|
|
39
|
+
GenderTitle: spUser.fields.Gender,
|
|
40
|
+
OrganisationLookupId: spUser.fields.OrganisationLookupId,
|
|
41
|
+
Organisation: organisation ? organisation.header : '',
|
|
42
|
+
NFP: spUser.fields.NFP,
|
|
43
|
+
SuggestedOrganisation: spUser.fields.SuggestedOrganisation,
|
|
44
|
+
id: spUser.fields.id,
|
|
45
|
+
ADUserId: spUser.fields.ADUserId,
|
|
46
|
+
SelfSeviceHelpdeskPreferencesText: config.SelfSeviceHelpdeskPreferencesText,
|
|
47
|
+
SelfSeviceHelpdeskPersonalDetailsText: config.SelfSeviceHelpdeskPersonalDetailsText,
|
|
48
|
+
};
|
|
49
|
+
} else {
|
|
50
|
+
_profile = {};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_profile.country = myProfile.country;
|
|
54
|
+
_profile.mail = myProfile.mail;
|
|
55
|
+
_profile.displayName = myProfile.displayName;
|
|
56
|
+
_profile.isEionetUser = spUser != undefined;
|
|
57
|
+
_profile.givenName = userData.ADUser.givenName;
|
|
58
|
+
_profile.surname = userData.ADUser.surname;
|
|
59
|
+
|
|
60
|
+
if (groups.graphClientMessage) {
|
|
61
|
+
let groupsList = groups.graphClientMessage.value;
|
|
62
|
+
|
|
63
|
+
_profile.isAdmin = groupsList.some((group) => {
|
|
64
|
+
return group.id === config.AdminGroupId;
|
|
65
|
+
});
|
|
66
|
+
_profile.isNFP =
|
|
67
|
+
!_profile.isAdmin &&
|
|
68
|
+
groupsList.some((group) => {
|
|
69
|
+
return group.id === config.NFPGroupId;
|
|
70
|
+
});
|
|
71
|
+
_profile.isGuest = !_profile.isAdmin && !_profile.isNFP;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return _profile;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function getUserByMail(email) {
|
|
80
|
+
try {
|
|
81
|
+
const adResponse = await apiGet("/users/?$filter=mail eq '" + email + "'"),
|
|
82
|
+
spUser = await getSPUserByMail(email),
|
|
83
|
+
adMessage = adResponse.graphClientMessage;
|
|
84
|
+
|
|
85
|
+
const adUser = adMessage.value && adMessage.value.length ? adMessage.value[0] : undefined;
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
ADUser: adUser,
|
|
89
|
+
SharepointUser: spUser,
|
|
90
|
+
IsValid: adUser !== undefined,
|
|
91
|
+
};
|
|
92
|
+
} catch (err) {
|
|
93
|
+
console.log(err);
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export async function getUser(userId) {
|
|
99
|
+
try {
|
|
100
|
+
const response = await apiGet('/users/' + userId);
|
|
101
|
+
return response.graphClientMessage;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.log(err);
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export async function getMeetingJoinInfo(event) {
|
|
109
|
+
const joinMeetingId =
|
|
110
|
+
event.fields.JoinMeetingId && event.fields.JoinMeetingId.split(' ').join('');
|
|
111
|
+
try {
|
|
112
|
+
if (joinMeetingId) {
|
|
113
|
+
const userId = await getADUserId(event.fields.MeetingmanagerLookupId);
|
|
114
|
+
if (userId) {
|
|
115
|
+
const response = await apiGet(
|
|
116
|
+
'/users/' +
|
|
117
|
+
userId +
|
|
118
|
+
"/onlineMeetings?$filter=joinMeetingIdSettings/JoinMeetingId eq '" +
|
|
119
|
+
joinMeetingId +
|
|
120
|
+
"'",
|
|
121
|
+
);
|
|
122
|
+
if (
|
|
123
|
+
response.graphClientMessage &&
|
|
124
|
+
response.graphClientMessage.value &&
|
|
125
|
+
response.graphClientMessage.value.length > 0
|
|
126
|
+
) {
|
|
127
|
+
return response.graphClientMessage.value[0];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
console.log(err);
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export async function sendEmail(subject, text, emails, attachment) {
|
|
139
|
+
const config = await getConfiguration();
|
|
140
|
+
|
|
141
|
+
if (subject && text && emails.length) {
|
|
142
|
+
const recipients = emails.map((email) => {
|
|
143
|
+
return {
|
|
144
|
+
emailAddress: {
|
|
145
|
+
address: email,
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const attachments = [];
|
|
151
|
+
if (attachment) {
|
|
152
|
+
let buffer = undefined;
|
|
153
|
+
const reader = new FileReader();
|
|
154
|
+
|
|
155
|
+
const promise = new Promise((resolve) => {
|
|
156
|
+
reader.onloadend = function () {
|
|
157
|
+
buffer = reader.result;
|
|
158
|
+
resolve();
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
reader.readAsDataURL(attachment);
|
|
162
|
+
await promise;
|
|
163
|
+
|
|
164
|
+
buffer &&
|
|
165
|
+
attachments.push({
|
|
166
|
+
'@odata.type': '#microsoft.graph.fileAttachment',
|
|
167
|
+
name: 'calendar.ics',
|
|
168
|
+
contentType: 'text/plain',
|
|
169
|
+
contentBytes: buffer.split(',')[1],
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const message = {
|
|
174
|
+
subject: subject,
|
|
175
|
+
body: {
|
|
176
|
+
contentType: 'HTML',
|
|
177
|
+
content: text,
|
|
178
|
+
},
|
|
179
|
+
toRecipients: recipients,
|
|
180
|
+
...(attachments.length > 0 && { attachments: attachments }),
|
|
181
|
+
},
|
|
182
|
+
apiPath = 'users/' + config.FromEmailAddress + '/sendMail';
|
|
183
|
+
|
|
184
|
+
await apiPost(apiPath, {
|
|
185
|
+
message: message,
|
|
186
|
+
saveToSentItems: true,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (config.DashboardEmailLoggingEnabled == 'true') {
|
|
190
|
+
await logInfo('Mail sent during registration process', apiPath, message);
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
await logError('Missing subject, body or recipients!', '', {
|
|
194
|
+
subject: subject,
|
|
195
|
+
body: text,
|
|
196
|
+
recipients: emails,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { apiPatch, getConfiguration, logInfo } from './apiProvider';
|
|
2
|
+
|
|
3
|
+
function wrapError(err, message) {
|
|
4
|
+
return {
|
|
5
|
+
Message: message,
|
|
6
|
+
Error: err,
|
|
7
|
+
Success: false,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function saveADUser(userData) {
|
|
12
|
+
let displayName = userData.FirstName + ' ' + userData.LastName + ' (' + userData.Country + ')';
|
|
13
|
+
if (userData.NFP) {
|
|
14
|
+
displayName = userData.FirstName + ' ' + userData.LastName + ' (NFP-' + userData.Country + ')';
|
|
15
|
+
}
|
|
16
|
+
await apiPatch('/users/' + userData.ADUserId, {
|
|
17
|
+
givenName: userData.FirstName,
|
|
18
|
+
surname: userData.LastName,
|
|
19
|
+
displayName: displayName,
|
|
20
|
+
department: 'Eionet',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function saveSPUser(userData) {
|
|
25
|
+
const spConfig = await getConfiguration();
|
|
26
|
+
let fields = {
|
|
27
|
+
fields: {
|
|
28
|
+
Phone: userData.Phone,
|
|
29
|
+
Title: userData.FirstName + ' ' + userData.LastName,
|
|
30
|
+
Gender: userData.Gender,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
let graphURL =
|
|
35
|
+
'/sites/' +
|
|
36
|
+
spConfig.SharepointSiteId +
|
|
37
|
+
'/lists/' +
|
|
38
|
+
spConfig.UserListId +
|
|
39
|
+
'/items/' +
|
|
40
|
+
userData.id;
|
|
41
|
+
await apiPatch(graphURL, fields);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function saveData(user) {
|
|
45
|
+
try {
|
|
46
|
+
await saveADUser(user);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
return wrapError(err, 'saveADUser');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
await saveSPUser(user);
|
|
53
|
+
await logInfo('User edited information', '', user, 'Edit user');
|
|
54
|
+
} catch (err) {
|
|
55
|
+
return wrapError(err, 'saveSPUser');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { Success: true };
|
|
59
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { apiGet, getConfiguration } from './apiProvider';
|
|
2
|
+
|
|
3
|
+
export async function getOrganisationList(country) {
|
|
4
|
+
const config = await getConfiguration();
|
|
5
|
+
try {
|
|
6
|
+
let path =
|
|
7
|
+
'/sites/' +
|
|
8
|
+
config.SharepointSiteId +
|
|
9
|
+
'/lists/' +
|
|
10
|
+
config.OrganisationListId +
|
|
11
|
+
'/items?$expand=fields';
|
|
12
|
+
if (country) {
|
|
13
|
+
path += "&$filter=fields/Country eq '" + country + "' or fields/Unspecified eq 1";
|
|
14
|
+
}
|
|
15
|
+
const response = await apiGet(path);
|
|
16
|
+
return response.graphClientMessage.value.map(function (organisation) {
|
|
17
|
+
return {
|
|
18
|
+
header: organisation.fields.Title,
|
|
19
|
+
content: organisation.id,
|
|
20
|
+
unspecified: organisation.fields.Unspecified,
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
} catch (err) {
|
|
24
|
+
console.log(err);
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function getSPUserByMail(email) {
|
|
30
|
+
const config = await getConfiguration();
|
|
31
|
+
try {
|
|
32
|
+
const path =
|
|
33
|
+
'/sites/' +
|
|
34
|
+
config.SharepointSiteId +
|
|
35
|
+
'/lists/' +
|
|
36
|
+
config.UserListId +
|
|
37
|
+
"/items?$filter=fields/Email eq '" +
|
|
38
|
+
email?.replace("'", "''") +
|
|
39
|
+
"'&$expand=fields",
|
|
40
|
+
response = await apiGet(path),
|
|
41
|
+
profile = response.graphClientMessage;
|
|
42
|
+
if (profile.value && profile.value.length) {
|
|
43
|
+
return profile.value[0];
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.log(err);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function getGenderList() {
|
|
52
|
+
const config = await getConfiguration();
|
|
53
|
+
let genders = [];
|
|
54
|
+
try {
|
|
55
|
+
const response = await apiGet(
|
|
56
|
+
'/sites/' + config.SharepointSiteId + '/lists/' + config.UserListId + '/columns',
|
|
57
|
+
);
|
|
58
|
+
const columns = response.graphClientMessage.value;
|
|
59
|
+
let genderColumn = columns.find((column) => column.name === 'Gender');
|
|
60
|
+
if (genderColumn && genderColumn.choice) {
|
|
61
|
+
genders = genderColumn.choice.choices;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return genders;
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.log(err);
|
|
67
|
+
}
|
|
68
|
+
}
|