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.
Files changed (111) hide show
  1. package/.fx/configs/azure.parameters.Prod_EEA.json +15 -0
  2. package/.fx/configs/azure.parameters.dev.json +15 -0
  3. package/.fx/configs/config.Prod_EEA.json +10 -0
  4. package/.fx/configs/config.dev.json +10 -0
  5. package/.fx/configs/projectSettings.json +83 -0
  6. package/.fx/states/state.Prod_EEA.json +47 -0
  7. package/.fx/states/state.dev.json +47 -0
  8. package/.vscode/launch.json +91 -0
  9. package/.vscode/settings.json +6 -0
  10. package/.vscode/tasks.json +63 -0
  11. package/CHANGELOG.md +140 -0
  12. package/Jenkinsfile +166 -0
  13. package/LICENSE.md +9 -0
  14. package/README.md +55 -0
  15. package/api/.funcignore +11 -0
  16. package/api/extensions.csproj +11 -0
  17. package/api/getGraphData/function.json +27 -0
  18. package/api/getGraphData/index.js +147 -0
  19. package/api/host.json +11 -0
  20. package/api/package-lock.json +1546 -0
  21. package/api/package.json +17 -0
  22. package/api/proxies.json +4 -0
  23. package/package.json +25 -0
  24. package/tabs/.env.teamsfx.Prod_EEA +11 -0
  25. package/tabs/.env.teamsfx.dev +11 -0
  26. package/tabs/.eslintrc.json +48 -0
  27. package/tabs/.prettierrc +7 -0
  28. package/tabs/.stylelintrc.json +6 -0
  29. package/tabs/babel.config.js +3 -0
  30. package/tabs/package-lock.json +15564 -0
  31. package/tabs/package.json +88 -0
  32. package/tabs/public/auth-end.html +76 -0
  33. package/tabs/public/auth-start.html +178 -0
  34. package/tabs/public/deploy.png +0 -0
  35. package/tabs/public/favicon.ico +0 -0
  36. package/tabs/public/hello.png +0 -0
  37. package/tabs/public/index.html +20 -0
  38. package/tabs/public/publish.png +0 -0
  39. package/tabs/src/components/App.jsx +36 -0
  40. package/tabs/src/components/CustomColumnResizeIcon.jsx +68 -0
  41. package/tabs/src/components/CustomDrawer.jsx +51 -0
  42. package/tabs/src/components/EventDialogTitle.jsx +29 -0
  43. package/tabs/src/components/HtmlBox.jsx +18 -0
  44. package/tabs/src/components/Privacy.jsx +17 -0
  45. package/tabs/src/components/ResizableGrid.jsx +44 -0
  46. package/tabs/src/components/Tab.jsx +477 -0
  47. package/tabs/src/components/Tab.scss +138 -0
  48. package/tabs/src/components/TabConfig.jsx +51 -0
  49. package/tabs/src/components/TabPanel.jsx +29 -0
  50. package/tabs/src/components/TermsOfUse.jsx +17 -0
  51. package/tabs/src/components/UnderConstruction.jsx +24 -0
  52. package/tabs/src/components/UserMenu.jsx +109 -0
  53. package/tabs/src/components/_variables.scss +10 -0
  54. package/tabs/src/components/activity/Activity.jsx +301 -0
  55. package/tabs/src/components/activity/ConsultationList.jsx +297 -0
  56. package/tabs/src/components/activity/EventList.jsx +463 -0
  57. package/tabs/src/components/activity/GroupsTags.jsx +26 -0
  58. package/tabs/src/components/activity/Reporting.jsx +13 -0
  59. package/tabs/src/components/activity/activity.scss +153 -0
  60. package/tabs/src/components/event_rating/EventRating.jsx +92 -0
  61. package/tabs/src/components/event_rating/EventRatingDialog.jsx +46 -0
  62. package/tabs/src/components/event_registration/Approval.jsx +80 -0
  63. package/tabs/src/components/event_registration/ApprovalDialog.jsx +30 -0
  64. package/tabs/src/components/event_registration/ApprovalList.jsx +62 -0
  65. package/tabs/src/components/event_registration/EventRegistration.jsx +214 -0
  66. package/tabs/src/components/lib/useData.js +33 -0
  67. package/tabs/src/components/lib/useGraph.js +39 -0
  68. package/tabs/src/components/lib/useTeamsFx.js +55 -0
  69. package/tabs/src/components/my_country/AtAGlance.jsx +151 -0
  70. package/tabs/src/components/my_country/CountryProgress.jsx +92 -0
  71. package/tabs/src/components/my_country/DataReporters.jsx +13 -0
  72. package/tabs/src/components/my_country/GroupView.jsx +54 -0
  73. package/tabs/src/components/my_country/GroupsBoard.jsx +52 -0
  74. package/tabs/src/components/my_country/IndicatorCard.jsx +60 -0
  75. package/tabs/src/components/my_country/ManagementBoard.jsx +109 -0
  76. package/tabs/src/components/my_country/MyCountry.jsx +186 -0
  77. package/tabs/src/components/my_country/ProgressGauge.jsx +125 -0
  78. package/tabs/src/components/my_country/ScientificCommittee.jsx +13 -0
  79. package/tabs/src/components/my_country/YearlyProgress.jsx +41 -0
  80. package/tabs/src/components/my_country/my_country.scss +81 -0
  81. package/tabs/src/components/publications/Publications.jsx +13 -0
  82. package/tabs/src/components/self_service/UserEdit.jsx +334 -0
  83. package/tabs/src/components/self_service/UserEdit.scss +107 -0
  84. package/tabs/src/data/apiProvider.js +153 -0
  85. package/tabs/src/data/constants.json +7 -0
  86. package/tabs/src/data/hooks/useConfiguration.js +18 -0
  87. package/tabs/src/data/icsHelper.js +38 -0
  88. package/tabs/src/data/messages.json +39 -0
  89. package/tabs/src/data/provider.js +199 -0
  90. package/tabs/src/data/selfServiceProvider.js +59 -0
  91. package/tabs/src/data/selfServiceSharepointProvider.js +68 -0
  92. package/tabs/src/data/sharepointProvider.js +729 -0
  93. package/tabs/src/data/validator.js +25 -0
  94. package/tabs/src/data/validator.test.js +9 -0
  95. package/tabs/src/index.css +16 -0
  96. package/tabs/src/index.jsx +6 -0
  97. package/tabs/src/static/images/teams-icon.svg +1 -0
  98. package/tabs/src/utils/uiHelper.js +6 -0
  99. package/templates/appPackage/aad.template.json +133 -0
  100. package/templates/appPackage/manifest.template.json +58 -0
  101. package/templates/appPackage/resources/color.png +0 -0
  102. package/templates/appPackage/resources/outline.png +0 -0
  103. package/templates/azure/config.bicep +27 -0
  104. package/templates/azure/main.bicep +20 -0
  105. package/templates/azure/provision/frontendHosting.bicep +23 -0
  106. package/templates/azure/provision/function.bicep +82 -0
  107. package/templates/azure/provision/identity.bicep +14 -0
  108. package/templates/azure/provision/simpleAuth.bicep +44 -0
  109. package/templates/azure/provision.bicep +58 -0
  110. package/templates/azure/teamsFx/function.bicep +76 -0
  111. package/templates/azure/teamsFx/simpleAuth.bicep +43 -0
@@ -0,0 +1,186 @@
1
+ import { React, useState, useEffect } from 'react';
2
+ import {
3
+ Backdrop,
4
+ Box,
5
+ CircularProgress,
6
+ ListItem,
7
+ ListItemText,
8
+ ListItemButton,
9
+ ListItemIcon,
10
+ } from '@mui/material';
11
+ import { AtAGlance } from './AtAGlance';
12
+ import { ManagementBoard } from './ManagementBoard';
13
+ import {
14
+ getMappingsList,
15
+ getInvitedUsers,
16
+ getOrganisationList,
17
+ getAvailableGroups,
18
+ } from '../../data/sharepointProvider';
19
+ import { GroupsBoard } from './GroupsBoard';
20
+ import './my_country.scss';
21
+ import { getConfiguration } from '../../data/apiProvider';
22
+ import { ScientificCommittee } from './ScientificCommittee';
23
+ import { DataReporters } from './DataReporters';
24
+ import TabPanel from '../TabPanel';
25
+
26
+ import PreviewIcon from '@mui/icons-material/Preview';
27
+ import ManageAccountsIcon from '@mui/icons-material/ManageAccounts';
28
+ import GroupIcon from '@mui/icons-material/Group';
29
+ import GroupWorkIcon from '@mui/icons-material/GroupWork';
30
+ import CustomDrawer from '../CustomDrawer';
31
+
32
+ export function MyCountry({ userInfo, selectedCountry }) {
33
+ const [tabsValue, setTabsValue] = useState(0),
34
+ [users, setUsers] = useState([]),
35
+ [mappings, setMappings] = useState([]),
36
+ [loading, setloading] = useState(false),
37
+ [organisations, setOrganisations] = useState([]),
38
+ [availableGroups, setAvailableGroups] = useState([]),
39
+ [configuration, setConfiguration] = useState({});
40
+
41
+ const loadData = async (country) => {
42
+ setloading(true);
43
+ const loadedUsers = await getInvitedUsers(country),
44
+ loadedOrganisations = await getOrganisationList(country),
45
+ loadedGroups = await getAvailableGroups();
46
+ loadedOrganisations && setOrganisations(loadedOrganisations);
47
+ setUsers(loadedUsers);
48
+ setAvailableGroups(loadedGroups);
49
+ setloading(false);
50
+ };
51
+
52
+ useEffect(() => {
53
+ (async () => {
54
+ setloading(true);
55
+
56
+ const loadedConfiguration = await getConfiguration();
57
+ if (loadedConfiguration) {
58
+ setConfiguration(loadedConfiguration);
59
+ }
60
+
61
+ await loadData(selectedCountry);
62
+
63
+ let loadedMappings = await getMappingsList();
64
+ if (loadedMappings) {
65
+ setMappings(loadedMappings);
66
+ }
67
+
68
+ setloading(false);
69
+ })();
70
+ }, [selectedCountry]);
71
+
72
+ const drawerOptions = (
73
+ <div>
74
+ {' '}
75
+ <ListItem disablePadding className="list-item" key={1}>
76
+ <ListItemButton
77
+ className={'list-item-button' + (tabsValue == 0 ? ' drawer-item-selected' : '')}
78
+ onClick={() => setTabsValue(0)}
79
+ >
80
+ <ListItemIcon className="list-item-icon">
81
+ <PreviewIcon />
82
+ </ListItemIcon>
83
+ <ListItemText primary={'At a glance'} />
84
+ </ListItemButton>
85
+ </ListItem>
86
+ <ListItem disablePadding className="list-item" key={2}>
87
+ <ListItemButton
88
+ className={'list-item-button' + (tabsValue == 1 ? ' drawer-item-selected' : '')}
89
+ onClick={() => setTabsValue(1)}
90
+ >
91
+ <ListItemIcon className="list-item-icon">
92
+ <ManageAccountsIcon />
93
+ </ListItemIcon>
94
+ <ListItemText primary={'NFPs/MB'} />
95
+ </ListItemButton>
96
+ </ListItem>
97
+ <ListItem disablePadding className="list-item" key={3}>
98
+ <ListItemButton
99
+ className={'list-item-button' + (tabsValue == 2 ? ' drawer-item-selected' : '')}
100
+ onClick={() => setTabsValue(2)}
101
+ >
102
+ <ListItemIcon className="list-item-icon">
103
+ <GroupIcon />
104
+ </ListItemIcon>
105
+ <ListItemText primary={'Eionet groups'} />
106
+ </ListItemButton>
107
+ </ListItem>
108
+ <ListItem disablePadding className="list-item" key={4}>
109
+ <ListItemButton
110
+ className={'list-item-button' + (tabsValue == 3 ? ' drawer-item-selected' : '')}
111
+ onClick={() => setTabsValue(3)}
112
+ >
113
+ <ListItemIcon className="list-item-icon">
114
+ <GroupWorkIcon />
115
+ </ListItemIcon>
116
+ <ListItemText primary={'ETCs'} />
117
+ </ListItemButton>
118
+ </ListItem>
119
+ </div>
120
+ );
121
+
122
+ return (
123
+ <div className="main">
124
+ <Box
125
+ sx={{
126
+ overflowY: 'scroll',
127
+ display: 'flex',
128
+ paddingTop: '4rem',
129
+ height: '100%',
130
+ background: '#F9F9F9',
131
+ }}
132
+ >
133
+ <Backdrop
134
+ sx={{ color: '#6b32a8', zIndex: (theme) => theme.zIndex.drawer + 1 }}
135
+ open={loading}
136
+ >
137
+ <CircularProgress color="primary" />
138
+ </Backdrop>
139
+
140
+ <CustomDrawer drawerOptions={drawerOptions}> </CustomDrawer>
141
+ <Box sx={{ width: '100%' }}>
142
+ <TabPanel value={tabsValue} index={0}>
143
+ <AtAGlance
144
+ users={users}
145
+ country={selectedCountry}
146
+ configuration={configuration}
147
+ userInfo={userInfo}
148
+ organisations={organisations}
149
+ availableGroups={availableGroups}
150
+ ></AtAGlance>
151
+ </TabPanel>
152
+ <TabPanel value={tabsValue} index={1}>
153
+ <ManagementBoard users={users} mappings={mappings}></ManagementBoard>
154
+ </TabPanel>
155
+ <TabPanel value={tabsValue} index={2}>
156
+ <GroupsBoard
157
+ users={users}
158
+ mappings={mappings.filter((m) => {
159
+ return !m.OtherMembership;
160
+ })}
161
+ ></GroupsBoard>
162
+ </TabPanel>
163
+ <TabPanel value={tabsValue} index={3}>
164
+ <GroupsBoard
165
+ users={users}
166
+ mappings={mappings.filter((m) => {
167
+ return m.OtherMembership;
168
+ })}
169
+ ></GroupsBoard>
170
+ </TabPanel>
171
+ {false && (
172
+ <TabPanel value={tabsValue} index={4}>
173
+ <ScientificCommittee></ScientificCommittee>
174
+ </TabPanel>
175
+ )}
176
+ {false && (
177
+ <TabPanel value={tabsValue} index={5}>
178
+ <DataReporters></DataReporters>
179
+ </TabPanel>
180
+ )}
181
+ </Box>
182
+ {false && <span>{userInfo.toString()}</span>}
183
+ </Box>
184
+ </div>
185
+ );
186
+ }
@@ -0,0 +1,125 @@
1
+ import { React, useState } from 'react';
2
+ import {
3
+ Box,
4
+ Button,
5
+ Card,
6
+ CardContent,
7
+ CircularProgress,
8
+ Typography,
9
+ IconButton,
10
+ Dialog,
11
+ } from '@mui/material';
12
+ import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
13
+
14
+ export function ProgressGauge({ totalCount, responseCount, label, infoText }) {
15
+ const [infoOpen, setInfoOpen] = useState(false),
16
+ handleInfoOpen = () => {
17
+ infoText && setInfoOpen(true);
18
+ },
19
+ handleInfoClose = () => {
20
+ setInfoOpen(false);
21
+ },
22
+ originalValue = (responseCount / totalCount) * 100,
23
+ valueProgress = isNaN(originalValue) ? 0 : originalValue;
24
+
25
+ function FullCircularProgress(props) {
26
+ return (
27
+ <Box sx={{ position: 'relative', display: 'inline-flex' }}>
28
+ <CircularProgress
29
+ sx={{ position: 'relative', zIndex: 2 }}
30
+ size={150}
31
+ variant="determinate"
32
+ value={valueProgress}
33
+ thickness={6}
34
+ {...props}
35
+ />
36
+ <CircularProgress
37
+ sx={{
38
+ position: 'absolute',
39
+ zIndex: 1,
40
+ right: 0,
41
+ color: (theme) => theme.palette.grey[theme.palette.mode === 'light' ? 200 : 800],
42
+ }}
43
+ size={150}
44
+ variant="determinate"
45
+ value={100}
46
+ thickness={6}
47
+ {...props}
48
+ />
49
+ </Box>
50
+ );
51
+ }
52
+
53
+ return (
54
+ <Card variant="outlined" className="indicator-card">
55
+ <Dialog open={infoOpen} onClose={handleInfoClose} maxWidth="xl">
56
+ <Typography sx={{ padding: '1rem' }} color="secondary">
57
+ {infoText}
58
+ </Typography>
59
+ <Button
60
+ onClick={handleInfoClose}
61
+ sx={{ alignSelf: 'end', marginRight: '0.5rem', marginBottom: '0.5rem' }}
62
+ >
63
+ Close
64
+ </Button>
65
+ </Dialog>
66
+
67
+ <CardContent className="card-content">
68
+ <IconButton
69
+ onClick={handleInfoOpen}
70
+ sx={{
71
+ position: 'absolute',
72
+ right: 0,
73
+ top: 0,
74
+ color: (theme) => theme.palette.grey[500],
75
+ }}
76
+ >
77
+ <HelpOutlineIcon />
78
+ </IconButton>
79
+ <Box sx={{ position: 'relative', display: 'inline-flex' }}>
80
+ <FullCircularProgress></FullCircularProgress>
81
+ <Box
82
+ sx={{
83
+ top: 0,
84
+ left: 0,
85
+ bottom: 0,
86
+ right: 0,
87
+ position: 'absolute',
88
+ display: 'flex',
89
+ alignItems: 'center',
90
+ justifyContent: 'center',
91
+ }}
92
+ >
93
+ <Typography
94
+ sx={{ fontSize: '28px', fontWeight: '600' }}
95
+ variant="caption"
96
+ component="div"
97
+ color="primary"
98
+ >
99
+ {responseCount}
100
+ </Typography>
101
+ <Typography
102
+ sx={{ fontSize: '28px', fontWeight: '400' }}
103
+ variant="caption"
104
+ component="div"
105
+ color="primary"
106
+ >
107
+ /{totalCount}
108
+ </Typography>
109
+ </Box>
110
+ </Box>
111
+ <Typography
112
+ sx={{
113
+ textAlign: 'center',
114
+ marginTop: '1rem',
115
+ width: '150px',
116
+ height: '1rem',
117
+ fontSize: '20px',
118
+ }}
119
+ >
120
+ {label}
121
+ </Typography>
122
+ </CardContent>
123
+ </Card>
124
+ );
125
+ }
@@ -0,0 +1,13 @@
1
+ import { React } from 'react';
2
+ import { Box } from '@mui/material';
3
+ import { UnderConstruction } from '../UnderConstruction';
4
+
5
+ export function ScientificCommittee() {
6
+ return (
7
+ <div className="">
8
+ <Box className="box-fill">
9
+ <UnderConstruction></UnderConstruction>
10
+ </Box>
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,41 @@
1
+ import { React } from 'react';
2
+ import { Box, Typography } from '@mui/material';
3
+ import { ProgressGauge } from './ProgressGauge';
4
+
5
+ export function YearlyProgress({
6
+ allMeetingsCount,
7
+ attendedMeetingsCount,
8
+ allConsultationsCount,
9
+ responseConsultationsCount,
10
+ allSurveysCount,
11
+ responseSurveysCount,
12
+ configuration,
13
+ }) {
14
+ return (
15
+ <div className="">
16
+ <Typography sx={{ fontSize: '16px', fontWeight: '600' }} color="text.secondary">
17
+ Participation:
18
+ </Typography>
19
+ <Box className="cards-container" sx={{ border: '0px' }}>
20
+ <ProgressGauge
21
+ label="Consultations"
22
+ totalCount={allConsultationsCount}
23
+ responseCount={responseConsultationsCount}
24
+ infoText={configuration.YearlyConsultationsCountInfo}
25
+ ></ProgressGauge>
26
+ <ProgressGauge
27
+ label="Inquiries"
28
+ totalCount={allSurveysCount}
29
+ responseCount={responseSurveysCount}
30
+ infoText={configuration.YearlySurveysCountInfo}
31
+ ></ProgressGauge>
32
+ <ProgressGauge
33
+ label="Events"
34
+ totalCount={allMeetingsCount}
35
+ responseCount={attendedMeetingsCount}
36
+ infoText={configuration.YearlyEventsCountInfo}
37
+ ></ProgressGauge>
38
+ </Box>
39
+ </div>
40
+ );
41
+ }
@@ -0,0 +1,81 @@
1
+ @import '../variables.scss';
2
+
3
+ .group-accordion {
4
+ padding-bottom: 0.5rem;
5
+ }
6
+
7
+ .accordion-summary {
8
+ background-color: #dae8f4 !important;
9
+ }
10
+
11
+ .accordion-summary-text {
12
+ font-weight: bold !important;
13
+ font-size: larger !important;
14
+ }
15
+
16
+ .year-tab {
17
+ font-size: 1.8rem !important;
18
+ }
19
+
20
+ .indicator-card {
21
+ margin: 1rem;
22
+ border: 0 !important;
23
+ }
24
+
25
+ .box-fill {
26
+ display: flex;
27
+ align-items: stretch;
28
+ height: 85%;
29
+ width: 100%;
30
+
31
+ &-column {
32
+ @extend .box-fill;
33
+ flex-direction: column;
34
+ }
35
+ }
36
+
37
+ .cards-container {
38
+ display: inline-flex;
39
+ text-align: start;
40
+ flex-wrap: wrap;
41
+ gap: 15px;
42
+ }
43
+
44
+ .card-content {
45
+ position: relative;
46
+ display: flex;
47
+ flex-direction: column;
48
+ }
49
+
50
+ .card-value {
51
+ font-size: 50px !important;
52
+ font-weight: 600 !important;
53
+ padding-top: 0.5rem;
54
+ }
55
+
56
+ .card-second-value {
57
+ font-size: 50px !important;
58
+ }
59
+
60
+ .card-label {
61
+ font-size: 18px !important;
62
+ width: 10rem;
63
+ height: 3rem;
64
+ font-weight: 400;
65
+ }
66
+
67
+ .card-details {
68
+ font-size: 15px !important;
69
+ padding-bottom: 0.5rem !important;
70
+ padding-left: 15px !important;
71
+ }
72
+
73
+ .progress-bar {
74
+ display: flex;
75
+ padding: 0.3rem;
76
+ width: 100%;
77
+ }
78
+
79
+ .country-drawer {
80
+ width: 15% !important;
81
+ }
@@ -0,0 +1,13 @@
1
+ import { React } from 'react';
2
+ import { Box } from '@mui/material';
3
+ import { UnderConstruction } from '../UnderConstruction';
4
+
5
+ export function Publications() {
6
+ return (
7
+ <div className="">
8
+ <Box className="box-fill">
9
+ <UnderConstruction></UnderConstruction>
10
+ </Box>
11
+ </div>
12
+ );
13
+ }