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,463 @@
1
+ import { React, useState } from 'react';
2
+
3
+ import {
4
+ Box,
5
+ CircularProgress,
6
+ Typography,
7
+ Link,
8
+ Button,
9
+ Tooltip,
10
+ IconButton,
11
+ Dialog,
12
+ DialogTitle,
13
+ Badge,
14
+ } from '@mui/material';
15
+
16
+ import { format } from 'date-fns';
17
+ import './activity.scss';
18
+ import DoneIcon from '@mui/icons-material/Done';
19
+ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
20
+ import CloseIcon from '@mui/icons-material/Close';
21
+ import FactCheckOutlinedIcon from '@mui/icons-material/FactCheckOutlined';
22
+ import ReviewsIcon from '@mui/icons-material/Reviews';
23
+ import TaskAltIcon from '@mui/icons-material/TaskAlt';
24
+
25
+ import { ReactComponent as TeamsIcon } from '../../static/images/teams-icon.svg';
26
+ import { GroupsTags } from './GroupsTags';
27
+ import ResizableGrid from '../ResizableGrid';
28
+ import { EventRegistration } from '../event_registration/EventRegistration';
29
+ import { getCurrentParticipant } from '../../data/sharepointProvider';
30
+
31
+ import { EventDialogTitle } from '../EventDialogTitle';
32
+
33
+ export function EventList({
34
+ userInfo,
35
+ configuration,
36
+ pastMeetings,
37
+ currentMeetings,
38
+ upcomingMeetings,
39
+ tabsValue,
40
+ openRating,
41
+ openApproval,
42
+ }) {
43
+ const [tagsCellOpen, setTagCellOpen] = useState(false),
44
+ [participant, setParticipant] = useState({}),
45
+ [selectedEvent, setSelectedEvent] = useState({}),
46
+ [selectedGroups, setSelectedGroups] = useState([]),
47
+ [registrationVisible, setRegistrationVisible] = useState(false),
48
+ [loading, setLoading] = useState(false);
49
+
50
+ const handleRegistrationClose = () => {
51
+ setRegistrationVisible(false);
52
+ };
53
+
54
+ const processParticipants = async (event) => {
55
+ const participant = await getCurrentParticipant(event, userInfo);
56
+
57
+ setSelectedEvent(event);
58
+ setParticipant(participant);
59
+ };
60
+
61
+ const renderCountCell = (params) => {
62
+ const row = params.row;
63
+ return (
64
+ <div>
65
+ {row.IsPast && row.NoOfParticipants > 0 && (
66
+ <Tooltip title={configuration.NoOfParticipantsTooltip}>
67
+ <Box className="grid-cell">
68
+ <Link
69
+ component="button"
70
+ variant="body1"
71
+ onClick={() => {
72
+ params.row.ParticipantsUrl && window.open(params.row.ParticipantsUrl, '_blank');
73
+ }}
74
+ >
75
+ {params.row.NoOfParticipants}
76
+ </Link>
77
+ </Box>
78
+ </Tooltip>
79
+ )}
80
+ {(row.IsUpcoming || row.IsCurrent) && row.NoOfRegistered > 0 && (
81
+ <Tooltip title={configuration.NoOfRegisteredTooltip}>
82
+ <Box className="grid-cell">
83
+ <Link
84
+ component="button"
85
+ variant="body1"
86
+ onClick={() => {
87
+ params.row.RegisteredUrl && window.open(params.row.RegisteredUrl, '_blank');
88
+ }}
89
+ >
90
+ {params.row.NoOfRegistered}
91
+ </Link>
92
+ </Box>
93
+ </Tooltip>
94
+ )}
95
+ </div>
96
+ );
97
+ },
98
+ renderMeetingTitle = (params) => {
99
+ return (
100
+ <Tooltip title={params.row.Title}>
101
+ <Box className="grid-cell">
102
+ {params.row.Linktofolder && (
103
+ <Link
104
+ className="grid-text"
105
+ component="button"
106
+ variant="body1"
107
+ onClick={() => {
108
+ params.row.Linktofolder && window.open(params.row.Linktofolder, '_blank');
109
+ }}
110
+ >
111
+ {params.row.Title}
112
+ </Link>
113
+ )}
114
+ {!params.row.Linktofolder && (
115
+ <Typography className="grid-text" variant="body1" component={'span'}>
116
+ {params.row.Title}
117
+ </Typography>
118
+ )}
119
+ </Box>
120
+ </Tooltip>
121
+ );
122
+ },
123
+ renderMeetingStart = (params) => {
124
+ let dateFormat = params.row.IsPast ? configuration.DateFormatDashboard : longDateFormat;
125
+ return (
126
+ <Typography
127
+ sx={{ whiteSpace: 'pre-line' }}
128
+ className="grid-text"
129
+ variant="body1"
130
+ component={'span'}
131
+ >
132
+ {format(params.row.MeetingStart, dateFormat)}
133
+ </Typography>
134
+ );
135
+ },
136
+ renderMeetingEnd = (params) => {
137
+ let dateFormat = params.row.IsPast ? configuration.DateFormatDashboard : longDateFormat;
138
+ return (
139
+ <Typography
140
+ sx={{ whiteSpace: 'pre-line' }}
141
+ className="grid-text"
142
+ variant="body1"
143
+ component={'span'}
144
+ >
145
+ {params.row.MeetingEnd && format(params.row.MeetingEnd, dateFormat)}
146
+ </Typography>
147
+ );
148
+ },
149
+ renderRegisterUrl = (params) => {
150
+ const event = params.row;
151
+ return (
152
+ <Tooltip title={configuration.RegisterEventButtonTooltip}>
153
+ <IconButton
154
+ variant="contained"
155
+ color={event.HasRegistered ? 'secondary' : 'primary'}
156
+ onClick={async () => {
157
+ setLoading(true);
158
+ await processParticipants(event);
159
+ setRegistrationVisible(true);
160
+ setLoading(false);
161
+ }}
162
+ >
163
+ {event.HasRegistered && <DoneIcon />}
164
+ {!event.HasRegistered && <OpenInNewIcon />}
165
+ </IconButton>
166
+ </Tooltip>
167
+ );
168
+ },
169
+ renderApproval = (params) => {
170
+ const event = params.row,
171
+ participantsCount = event.Participants ? event.Participants.length : 0,
172
+ pendingApprovalCount =
173
+ participantsCount > 0
174
+ ? event.Participants.filter((p) => !p.NFPApproved || p.NFPApproved == 'No value').length
175
+ : 0;
176
+ return (
177
+ <div>
178
+ {event.IsOffline && participantsCount > 0 && (
179
+ <Tooltip title={configuration.RegisterEventButtonTooltip}>
180
+ <Badge badgeContent={pendingApprovalCount} color="secondary" overlap="circular">
181
+ <IconButton
182
+ variant="contained"
183
+ color="primary"
184
+ onClick={async () => {
185
+ openApproval(event);
186
+ }}
187
+ >
188
+ <FactCheckOutlinedIcon />
189
+ </IconButton>
190
+ </Badge>
191
+ </Tooltip>
192
+ )}
193
+ </div>
194
+ );
195
+ },
196
+ renderJoinUrl = (params) => {
197
+ return (
198
+ <div>
199
+ {params.row.MeetingLink && (
200
+ <Tooltip title={configuration.JoinEventButtonTooltip}>
201
+ <IconButton
202
+ variant="contained"
203
+ color="success"
204
+ onClick={() => {
205
+ params.row.MeetingLink && window.open(params.row.MeetingLink, '_blank');
206
+ }}
207
+ >
208
+ <TeamsIcon />
209
+ </IconButton>
210
+ </Tooltip>
211
+ )}
212
+ </div>
213
+ );
214
+ },
215
+ renderGroupsTags = (params) => {
216
+ return <GroupsTags handleClick={handleCellClick} groups={params.row.Group || []} />;
217
+ },
218
+ renderRating = (params) => {
219
+ const event = params.row;
220
+ return (
221
+ <div>
222
+ {!!event.AllowVote && (
223
+ <IconButton
224
+ variant="contained"
225
+ color="primary"
226
+ onClick={async () => {
227
+ openRating(event);
228
+ }}
229
+ >
230
+ <ReviewsIcon />
231
+ </IconButton>
232
+ )}
233
+ {!!event.HasVoted && (
234
+ <IconButton variant="contained" color="primary">
235
+ <TaskAltIcon />
236
+ </IconButton>
237
+ )}
238
+ </div>
239
+ );
240
+ };
241
+
242
+ const handleCellClick = (groups) => {
243
+ setTagCellOpen(true);
244
+ setSelectedGroups(groups);
245
+ },
246
+ handleTagDialogClose = () => {
247
+ setTagCellOpen(false);
248
+ };
249
+
250
+ const baseColumns = [
251
+ {
252
+ field: 'Title',
253
+ headerName: 'Event',
254
+ flex: 1,
255
+
256
+ renderCell: renderMeetingTitle,
257
+ },
258
+ {
259
+ field: 'Group',
260
+ headerName: 'Eionet groups',
261
+
262
+ renderCell: renderGroupsTags,
263
+ flex: 0.5,
264
+ },
265
+ {
266
+ field: 'MeetingStart',
267
+ headerName: 'Start date',
268
+ width: '130',
269
+
270
+ renderCell: renderMeetingStart,
271
+ },
272
+ {
273
+ field: 'MeetingEnd',
274
+ headerName: 'End date',
275
+ width: '130',
276
+ renderCell: renderMeetingEnd,
277
+ },
278
+ ];
279
+ const participantsColumn = {
280
+ field: 'NoOfParticipants',
281
+ headerName: 'Participants',
282
+ align: 'center',
283
+ width: '100',
284
+ renderCell: renderCountCell,
285
+ },
286
+ registrationsColumn = {
287
+ field: 'NoOfRegistered',
288
+ headerName: 'Enrolled',
289
+ align: 'center',
290
+ width: '100',
291
+ renderCell: renderCountCell,
292
+ },
293
+ approvalColumn = {
294
+ field: 'Approval',
295
+ headerName: 'Approval',
296
+ align: 'center',
297
+ width: '100',
298
+ renderCell: renderApproval,
299
+ },
300
+ ratingColumn = {
301
+ field: 'AllowVote',
302
+ headerName: 'Rate',
303
+ description: configuration.RatingColumnHeaderDescription,
304
+ align: 'center',
305
+ width: '100',
306
+ renderCell: renderRating,
307
+ },
308
+ currentColumns = Array.from(baseColumns);
309
+
310
+ currentColumns.push({
311
+ field: 'MeetingLink',
312
+ headerName: 'Join',
313
+ align: 'center',
314
+ width: '60',
315
+ renderCell: renderJoinUrl,
316
+ });
317
+ currentColumns.splice(2, 0, registrationsColumn);
318
+ userInfo.country && userInfo.isEionetUser && currentColumns.splice(2, 0, ratingColumn);
319
+
320
+ let upcomingColumns = Array.from(baseColumns);
321
+ //do not show register column if user is missing the country info.
322
+ userInfo.country &&
323
+ upcomingColumns.push({
324
+ field: 'MeetingRegistrationLink',
325
+ headerName: 'Register',
326
+ align: 'center',
327
+ width: '75',
328
+ renderCell: renderRegisterUrl,
329
+ });
330
+ upcomingColumns.splice(2, 0, registrationsColumn);
331
+ userInfo.isNFP && upcomingColumns.push(approvalColumn);
332
+
333
+ let pastColumns = Array.from(baseColumns);
334
+ pastColumns.splice(2, 0, participantsColumn);
335
+ userInfo.country && userInfo.isEionetUser && pastColumns.splice(2, 0, ratingColumn);
336
+
337
+ const longDateFormat = configuration.DateFormatDashboard + '\n HH:mm';
338
+
339
+ return (
340
+ <div className="">
341
+ <Box
342
+ sx={{
343
+ boxShadow: 2,
344
+ }}
345
+ >
346
+ <Dialog open={tagsCellOpen} onClose={handleTagDialogClose}>
347
+ <GroupsTags groups={selectedGroups} isDialog={true} />
348
+ <Button
349
+ onClick={handleTagDialogClose}
350
+ sx={{ alignSelf: 'end', marginRight: '0.5rem', marginBottom: '0.5rem' }}
351
+ >
352
+ Close
353
+ </Button>
354
+ </Dialog>
355
+ <Dialog
356
+ className="dialog"
357
+ open={registrationVisible}
358
+ onClose={handleRegistrationClose}
359
+ maxWidth="lg"
360
+ fullWidth
361
+ >
362
+ {selectedEvent.Title && (
363
+ <DialogTitle>
364
+ <IconButton
365
+ aria-label="close"
366
+ onClick={handleRegistrationClose}
367
+ sx={{
368
+ position: 'absolute',
369
+ right: 8,
370
+ top: 8,
371
+ color: (theme) => theme.palette.grey[500],
372
+ }}
373
+ >
374
+ <CloseIcon />
375
+ </IconButton>
376
+ <EventDialogTitle
377
+ title={'EVENT REGISTRATION'}
378
+ event={selectedEvent}
379
+ ></EventDialogTitle>
380
+ </DialogTitle>
381
+ )}
382
+ <EventRegistration
383
+ event={selectedEvent}
384
+ userInfo={userInfo}
385
+ participant={participant}
386
+ ></EventRegistration>
387
+ </Dialog>
388
+
389
+ <Box sx={{ display: 'flex', height: '98%', width: '100%' }}>
390
+ {tabsValue == 0 && (
391
+ <ResizableGrid
392
+ rows={currentMeetings}
393
+ columns={currentColumns}
394
+ pageSizeOptions={[25, 50, 100]}
395
+ initialState={{
396
+ pagination: { paginationModel: { pageSize: 25 } },
397
+ sorting: {
398
+ sortModel: [
399
+ {
400
+ field: 'MeetingStart',
401
+ sort: 'asc',
402
+ },
403
+ ],
404
+ },
405
+ }}
406
+ hideFooterSelectedRowCount
407
+ />
408
+ )}
409
+ {tabsValue == 1 && (
410
+ <ResizableGrid
411
+ rows={upcomingMeetings}
412
+ columns={upcomingColumns}
413
+ hideFooterSelectedRowCount
414
+ pageSizeOptions={[25, 50, 100]}
415
+ initialState={{
416
+ pagination: { paginationModel: { pageSize: 25 } },
417
+ sorting: {
418
+ sortModel: [
419
+ {
420
+ field: 'MeetingStart',
421
+ sort: 'asc',
422
+ },
423
+ ],
424
+ },
425
+ }}
426
+ />
427
+ )}
428
+ {tabsValue == 2 && (
429
+ <ResizableGrid
430
+ rows={pastMeetings}
431
+ columns={pastColumns}
432
+ hideFooterSelectedRowCount
433
+ pageSizeOptions={[25, 50, 100]}
434
+ initialState={{
435
+ pagination: { paginationModel: { pageSize: 25 } },
436
+ sorting: {
437
+ sortModel: [
438
+ {
439
+ field: 'MeetingStart',
440
+ sort: 'desc',
441
+ },
442
+ ],
443
+ },
444
+ }}
445
+ />
446
+ )}
447
+ </Box>
448
+ {loading && (
449
+ <CircularProgress
450
+ color="primary"
451
+ sx={{
452
+ position: 'absolute',
453
+ top: '50%',
454
+ left: '50%',
455
+ marginTop: '-12px',
456
+ marginLeft: '-12px',
457
+ }}
458
+ />
459
+ )}
460
+ </Box>
461
+ </div>
462
+ );
463
+ }
@@ -0,0 +1,26 @@
1
+ import { React } from 'react';
2
+ import { Chip, Tooltip } from '@mui/material';
3
+
4
+ export function GroupsTags({ groups, handleClick, isDialog }) {
5
+ let index = 0;
6
+ const styleClass = isDialog ? 'groups-tags-dialog' : '';
7
+ return (
8
+ <div className={styleClass}>
9
+ <Tooltip title={groups.join(', ') || ''} arrow>
10
+ <div id="groups">
11
+ {groups.map((m) => (
12
+ <Chip
13
+ variant="outlined"
14
+ color="primary"
15
+ size="small"
16
+ key={index++}
17
+ label={m}
18
+ clickable={!isDialog}
19
+ onClick={() => handleClick(groups)}
20
+ />
21
+ ))}
22
+ </div>
23
+ </Tooltip>
24
+ </div>
25
+ );
26
+ }
@@ -0,0 +1,13 @@
1
+ import { Box } from '@mui/material';
2
+ import { React } from 'react';
3
+ import { UnderConstruction } from '../UnderConstruction';
4
+
5
+ export function Reporting() {
6
+ return (
7
+ <div className="">
8
+ <Box sx={{ height: '90%' }}>
9
+ <UnderConstruction></UnderConstruction>
10
+ </Box>
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,153 @@
1
+ @import '../variables.scss';
2
+
3
+ .bottom-panel {
4
+ display: flex;
5
+ justify-content: center;
6
+ padding: 1rem;
7
+ }
8
+
9
+ .tab-panel {
10
+ width: 100%;
11
+ height: 100%;
12
+ min-height: 200px;
13
+ margin-bottom: 0.5rem;
14
+ margin-top: 0.25rem;
15
+ }
16
+
17
+ .MuiDataGrid-row:nth-child(even) {
18
+ background-color: #f9f9f9;
19
+ }
20
+
21
+ .MuiDataGrid-columnHeaderTitle {
22
+ font-weight: bold !important;
23
+ }
24
+
25
+ .MuiBottomNavigationAction-label {
26
+ font-size: 1rem !important;
27
+ margin-top: 0.25rem;
28
+ }
29
+
30
+ .grid-cell {
31
+ display: flex;
32
+ }
33
+
34
+ .grid-cell-centered {
35
+ display: flex;
36
+ justify-content: center;
37
+ }
38
+
39
+ .grid-text {
40
+ font-size: 14px !important;
41
+ }
42
+
43
+ .red-cell-text {
44
+ color: red;
45
+ font-weight: 600;
46
+ font-size: larger;
47
+ }
48
+
49
+ .groups-tags-dialog {
50
+ margin: 1rem;
51
+ }
52
+
53
+ .MuiTabs-flexContainer {
54
+ align-items: start !important;
55
+ }
56
+
57
+ .MuiTab-root {
58
+ text-transform: none !important;
59
+ }
60
+
61
+ .MuiBadge-badge {
62
+ top: 13 !important;
63
+ border: 2px solid white !important;
64
+ padding: 0 4px !important;
65
+ }
66
+
67
+ .row {
68
+ display: flex;
69
+ flex-direction: row;
70
+
71
+ @media (max-width: map-get($breakpoints, lg)) {
72
+ flex-direction: column;
73
+ }
74
+
75
+ &.fixed {
76
+ flex-direction: row !important;
77
+ }
78
+ }
79
+
80
+ .control {
81
+ margin: 0.35rem !important;
82
+ margin-left: 0 !important;
83
+ width: 33%;
84
+
85
+ @media (max-width: map-get($breakpoints, lg)) {
86
+ width: auto;
87
+ margin-bottom: 0.75rem !important;
88
+ }
89
+
90
+ &.w50 {
91
+ width: 50%;
92
+
93
+ @media (max-width: map-get($breakpoints, lg)) {
94
+ width: auto;
95
+ }
96
+ }
97
+
98
+ &.w100 {
99
+ width: 100%;
100
+
101
+ @media (max-width: map-get($breakpoints, lg)) {
102
+ width: auto;
103
+ }
104
+ }
105
+ }
106
+
107
+ .box {
108
+ padding: 0.2rem;
109
+ }
110
+
111
+ .approval-row {
112
+ margin-bottom: 1rem;
113
+ width: 100% !important;
114
+
115
+ @media (max-width: map-get($breakpoints, lg)) {
116
+ margin-bottom: 2rem;
117
+ }
118
+
119
+ .row {
120
+ width: 50%;
121
+
122
+ @media (max-width: map-get($breakpoints, lg)) {
123
+ width: auto;
124
+ }
125
+
126
+ .control {
127
+ width: 100%;
128
+ }
129
+ }
130
+ }
131
+
132
+ .approval-row:nth-of-type(even) {
133
+ background-color: white;
134
+ }
135
+
136
+ .popup {
137
+ margin: 1.5rem;
138
+ overflow-y: auto;
139
+ }
140
+
141
+ .button {
142
+ margin-right: 0.5rem !important;
143
+ }
144
+
145
+ .drawer-item-selected {
146
+ border-left: 0.2rem solid !important;
147
+ background-color: $main-color !important;
148
+ color: #ffffff !important;
149
+
150
+ .MuiSvgIcon-root {
151
+ color: #ffffff !important;
152
+ }
153
+ }