@campxdev/shared 1.10.96 → 1.11.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/package.json +1 -1
- package/src/components/HookForm/RadioGroup.tsx +1 -1
- package/src/components/Input/RadioGroup.tsx +2 -2
- package/src/components/Input/SearchSingleSelect.tsx +0 -1
- package/src/components/Layout/SideNav.tsx +39 -5
- package/src/components/ReportHeader.tsx +134 -17
- package/src/hooks/useAuth.ts +2 -0
- package/src/permissions/ValidateAccess.tsx +2 -2
- package/src/shared-state/PermissionsStore.ts +19 -1
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ interface Props extends RadioGroupProps {
|
|
|
10
10
|
sx?: any
|
|
11
11
|
row?: boolean
|
|
12
12
|
required?: boolean
|
|
13
|
-
options: { value: any; label: string | ReactNode }[]
|
|
13
|
+
options: { value: any; label: string | ReactNode; disabled?: boolean }[]
|
|
14
14
|
containerProps?: BoxProps
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -57,7 +57,7 @@ interface Props extends RadioGroupProps {
|
|
|
57
57
|
sx?: any
|
|
58
58
|
row?: boolean
|
|
59
59
|
required?: boolean
|
|
60
|
-
options: { value: any; label: string | ReactNode }[]
|
|
60
|
+
options: { value: any; label: string | ReactNode; disabled?: boolean }[]
|
|
61
61
|
containerProps?: BoxProps
|
|
62
62
|
error?: boolean
|
|
63
63
|
helperText?: string | null
|
|
@@ -97,7 +97,7 @@ export default function RadioGroup(props: Props) {
|
|
|
97
97
|
<Radio
|
|
98
98
|
checkedIcon={<BpCheckedIcon />}
|
|
99
99
|
icon={<BpIcon />}
|
|
100
|
-
disabled={disabled}
|
|
100
|
+
disabled={disabled || item.disabled}
|
|
101
101
|
/>
|
|
102
102
|
}
|
|
103
103
|
label={item.label}
|
|
@@ -18,6 +18,21 @@ import {
|
|
|
18
18
|
|
|
19
19
|
const accessIfNoKey = process.env.NODE_ENV === 'development' ? true : false
|
|
20
20
|
|
|
21
|
+
const checkHasAccess = (
|
|
22
|
+
checkForMasterSlave,
|
|
23
|
+
permissionKey,
|
|
24
|
+
institutionType,
|
|
25
|
+
permissions,
|
|
26
|
+
) => {
|
|
27
|
+
if (checkForMasterSlave) {
|
|
28
|
+
return permissions[permissionKey] && institutionType == 'MASTER_CHILD'
|
|
29
|
+
? true
|
|
30
|
+
: false
|
|
31
|
+
} else {
|
|
32
|
+
return permissionKey ? permissions[permissionKey] : true
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
21
36
|
const sideNavStore = new Store({
|
|
22
37
|
activeKey: '',
|
|
23
38
|
})
|
|
@@ -52,12 +67,24 @@ const SideNav = ({
|
|
|
52
67
|
export default memo(SideNav)
|
|
53
68
|
|
|
54
69
|
const RenderMenuItem = ({ menuItem }) => {
|
|
55
|
-
const {
|
|
70
|
+
const {
|
|
71
|
+
path,
|
|
72
|
+
children,
|
|
73
|
+
title,
|
|
74
|
+
icon,
|
|
75
|
+
permissionKey,
|
|
76
|
+
checkForMasterSlave = false,
|
|
77
|
+
} = menuItem
|
|
56
78
|
let resolved = useResolvedPath(path)
|
|
57
79
|
let match = useMatch({ path: resolved.pathname, end: false })
|
|
58
80
|
|
|
59
|
-
const permissions = PermissionsStore.useState((s) => s)
|
|
60
|
-
const hasAccess =
|
|
81
|
+
const { permissions, institutionType } = PermissionsStore.useState((s) => s)
|
|
82
|
+
const hasAccess = checkHasAccess(
|
|
83
|
+
checkForMasterSlave,
|
|
84
|
+
permissionKey,
|
|
85
|
+
institutionType,
|
|
86
|
+
permissions,
|
|
87
|
+
)
|
|
61
88
|
|
|
62
89
|
if (children?.length)
|
|
63
90
|
return (
|
|
@@ -99,13 +126,20 @@ const RenderMenuItem = ({ menuItem }) => {
|
|
|
99
126
|
|
|
100
127
|
const DropDownMenu = ({ path, title, icon, menuItems }) => {
|
|
101
128
|
const { activeKey } = sideNavStore.useState((s) => s)
|
|
102
|
-
const permissions = PermissionsStore.useState((s) => s)
|
|
129
|
+
const { permissions, institutionType } = PermissionsStore.useState((s) => s)
|
|
103
130
|
|
|
104
131
|
const validateDropdownAccess = () => {
|
|
105
132
|
if (process.env.NODE_ENV === 'development' && !permissions) return true
|
|
106
133
|
|
|
107
134
|
return menuItems?.some((item) =>
|
|
108
|
-
item?.permissionKey
|
|
135
|
+
item?.permissionKey
|
|
136
|
+
? checkHasAccess(
|
|
137
|
+
item?.checkForMasterSlave,
|
|
138
|
+
item?.permissionKey,
|
|
139
|
+
institutionType,
|
|
140
|
+
permissions,
|
|
141
|
+
)
|
|
142
|
+
: accessIfNoKey,
|
|
109
143
|
)
|
|
110
144
|
}
|
|
111
145
|
|
|
@@ -1,24 +1,96 @@
|
|
|
1
1
|
import { Box, SxProps, Typography } from '@mui/material'
|
|
2
2
|
import { Variant } from '@mui/material/styles/createTypography'
|
|
3
|
+
import _ from 'lodash'
|
|
4
|
+
import { PermissionsStore } from '../shared-state'
|
|
5
|
+
import { InstitutionsStore } from '../shared-state/InstitutionsStore'
|
|
3
6
|
|
|
4
|
-
interface
|
|
7
|
+
export interface ReportHeaderTypographyProps {
|
|
5
8
|
text: string
|
|
6
9
|
sx?: SxProps
|
|
7
10
|
variant?: Variant
|
|
11
|
+
hide?: boolean
|
|
8
12
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
|
|
14
|
+
export interface ReportHeaderOptionalTypographyProps {
|
|
15
|
+
text?: string
|
|
16
|
+
sx?: SxProps
|
|
17
|
+
variant?: Variant
|
|
18
|
+
hide?: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export enum ReportHeaderType {
|
|
22
|
+
FULL_HEADER = 'full-header',
|
|
23
|
+
LOGO_HEADER = 'logo-header',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
ReportHeader.defaultProps = {
|
|
27
|
+
headerType: ReportHeaderType.FULL_HEADER,
|
|
28
|
+
address: {
|
|
29
|
+
hide: false,
|
|
30
|
+
variant: 'body1',
|
|
31
|
+
},
|
|
32
|
+
phone: {
|
|
33
|
+
hide: false,
|
|
34
|
+
variant: 'body1',
|
|
35
|
+
},
|
|
36
|
+
recognitionDetails: {
|
|
37
|
+
hide: false,
|
|
38
|
+
variant: 'h5',
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ReportHeaderProps {
|
|
13
43
|
containerSx?: SxProps
|
|
44
|
+
headerType?: ReportHeaderType
|
|
45
|
+
reportHeaderImageUrl?: string
|
|
46
|
+
reportHeaderImageCSS?: any
|
|
47
|
+
typographyList?: ReportHeaderTypographyProps[]
|
|
48
|
+
logoImageUrl?: string
|
|
49
|
+
logoImageCSS?: any
|
|
50
|
+
address?: ReportHeaderOptionalTypographyProps
|
|
51
|
+
recognitionDetails?: ReportHeaderOptionalTypographyProps
|
|
52
|
+
phone?: ReportHeaderOptionalTypographyProps
|
|
14
53
|
}
|
|
15
54
|
|
|
16
55
|
export default function ReportHeader({
|
|
17
|
-
logo,
|
|
18
|
-
typographyList,
|
|
19
56
|
containerSx,
|
|
20
|
-
|
|
57
|
+
headerType,
|
|
58
|
+
reportHeaderImageUrl,
|
|
59
|
+
reportHeaderImageCSS,
|
|
60
|
+
typographyList,
|
|
61
|
+
logoImageUrl,
|
|
62
|
+
logoImageCSS,
|
|
63
|
+
address: {
|
|
64
|
+
hide: hideAddress,
|
|
65
|
+
variant: addressVariant,
|
|
66
|
+
text: addressText,
|
|
67
|
+
sx: addressSx,
|
|
68
|
+
},
|
|
69
|
+
recognitionDetails: {
|
|
70
|
+
hide: hideRecognitionDetails,
|
|
71
|
+
variant: recognitionDetailsVariant,
|
|
72
|
+
text: recognitionDetailsText,
|
|
73
|
+
sx: recognitionDetailsSx,
|
|
74
|
+
},
|
|
75
|
+
phone: {
|
|
76
|
+
hide: hidePhone,
|
|
77
|
+
variant: phoneVariant,
|
|
78
|
+
text: phoneText,
|
|
79
|
+
sx: phoneSx,
|
|
80
|
+
},
|
|
21
81
|
}: ReportHeaderProps) {
|
|
82
|
+
const { masterInstitutionUniqueId, institutionType } =
|
|
83
|
+
PermissionsStore.useState((s) => ({
|
|
84
|
+
institutionType: s.institutionType,
|
|
85
|
+
masterInstitutionUniqueId: s.masterInstitutionUniqueId,
|
|
86
|
+
}))
|
|
87
|
+
const { current, institutions } = InstitutionsStore.useState((s) => s)
|
|
88
|
+
const institutionsMap = _.keyBy(institutions, (institution) => institution.id)
|
|
89
|
+
|
|
90
|
+
const masterInstitution = institutionsMap[masterInstitutionUniqueId]
|
|
91
|
+
|
|
92
|
+
const hasFullHeader = current?.reportHeader?.url ? true : false
|
|
93
|
+
|
|
22
94
|
return (
|
|
23
95
|
<Box
|
|
24
96
|
sx={{
|
|
@@ -29,17 +101,62 @@ export default function ReportHeader({
|
|
|
29
101
|
...containerSx,
|
|
30
102
|
}}
|
|
31
103
|
>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
104
|
+
{hasFullHeader && headerType === ReportHeaderType.FULL_HEADER ? (
|
|
105
|
+
<>
|
|
106
|
+
<img
|
|
107
|
+
style={{
|
|
108
|
+
objectFit: 'contain',
|
|
109
|
+
width: '100%',
|
|
110
|
+
height: '200px',
|
|
111
|
+
...reportHeaderImageCSS,
|
|
112
|
+
}}
|
|
113
|
+
src={
|
|
114
|
+
reportHeaderImageUrl ||
|
|
115
|
+
current?.reportHeader?.url ||
|
|
116
|
+
masterInstitution.reportHeader?.url
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
</>
|
|
120
|
+
) : (
|
|
121
|
+
<>
|
|
122
|
+
<img
|
|
123
|
+
style={{
|
|
124
|
+
height: '40px',
|
|
125
|
+
objectFit: 'contain',
|
|
126
|
+
...logoImageCSS,
|
|
127
|
+
}}
|
|
128
|
+
src={
|
|
129
|
+
logoImageUrl ||
|
|
130
|
+
current?.images?.url ||
|
|
131
|
+
masterInstitution?.images?.url
|
|
132
|
+
}
|
|
133
|
+
/>
|
|
134
|
+
{!hideRecognitionDetails && (
|
|
135
|
+
<Typography
|
|
136
|
+
variant={recognitionDetailsVariant}
|
|
137
|
+
sx={recognitionDetailsSx}
|
|
138
|
+
>
|
|
139
|
+
{recognitionDetailsText ||
|
|
140
|
+
current.recognitionDetails ||
|
|
141
|
+
masterInstitution.recognitionDetails}
|
|
142
|
+
</Typography>
|
|
143
|
+
)}
|
|
144
|
+
{!hideAddress && (
|
|
145
|
+
<Typography variant={addressVariant} sx={addressSx}>
|
|
146
|
+
{addressText || current.address || masterInstitution.address}
|
|
147
|
+
</Typography>
|
|
148
|
+
)}
|
|
149
|
+
{!hidePhone && (
|
|
150
|
+
<Typography variant={phoneVariant} sx={phoneSx}>
|
|
151
|
+
{'Phone: ' +
|
|
152
|
+
(phoneText || current.phone || masterInstitution.phone)}
|
|
153
|
+
</Typography>
|
|
154
|
+
)}
|
|
155
|
+
</>
|
|
156
|
+
)}
|
|
40
157
|
{typographyList &&
|
|
41
158
|
typographyList.map((s) => (
|
|
42
|
-
<Typography variant={s.variant} sx={
|
|
159
|
+
<Typography variant={s.variant || 'body1'} sx={s.sx}>
|
|
43
160
|
{s.text}
|
|
44
161
|
</Typography>
|
|
45
162
|
))}
|
package/src/hooks/useAuth.ts
CHANGED
|
@@ -229,6 +229,8 @@ function useAuth({ permissionsEndpoint, loginUrl }: AuthParams): AuthResponse {
|
|
|
229
229
|
} as any
|
|
230
230
|
s.applications = res.data?.applications ?? []
|
|
231
231
|
s.institutionType = res.data?.institutionType
|
|
232
|
+
s.masterInstitutionUniqueId = res.data?.masterInstitutionUniqueId
|
|
233
|
+
s.masterInstitutionId = res.data?.masterInstitutionId
|
|
232
234
|
})
|
|
233
235
|
AssetsStore.update((s) => {
|
|
234
236
|
s.logo = res.data?.assets.logo
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { Permission, PermissionsStore } from '../shared-state/PermissionsStore'
|
|
2
|
+
import { Permission, PermissionsStore, SquarePermissions } from '../shared-state/PermissionsStore'
|
|
3
3
|
|
|
4
4
|
export default function ValidateAccess({
|
|
5
5
|
accessKey,
|
|
6
6
|
children,
|
|
7
7
|
checkForMasterSlave = false,
|
|
8
8
|
}: {
|
|
9
|
-
accessKey: Permission
|
|
9
|
+
accessKey: Permission | SquarePermissions
|
|
10
10
|
children: React.ReactNode
|
|
11
11
|
checkForMasterSlave?: boolean
|
|
12
12
|
}) {
|
|
@@ -8,6 +8,10 @@ export enum PaymentsPermission {
|
|
|
8
8
|
CAN_MANAGE_PAYMENTS_PROFILE_PERMISSIONS_EDIT = 'can_manage_payments_profile_permissions_edit',
|
|
9
9
|
CAN_MANAGE_PAYMENTS_PROFILE_PERMISSIONS_DELETE = 'can_manage_payments_profile_permissions_delete',
|
|
10
10
|
|
|
11
|
+
//Payments imports
|
|
12
|
+
CAN_IMPORT_RECEIPTS='can_import_receipts',
|
|
13
|
+
CAN_IMPORT_CREDITS='can_import_credits',
|
|
14
|
+
|
|
11
15
|
// Fee Counter
|
|
12
16
|
CAN_FEE_COUNTER_ACADEMIC_FEE = 'can_fee_counter_academic_fee',
|
|
13
17
|
CAN_FEE_COUNTER_EXAM_FEE = 'can_fee_counter_exam_fee',
|
|
@@ -559,6 +563,10 @@ export enum Permission {
|
|
|
559
563
|
CAN_FEE_COUNTER_ACADEMIC_FEE = 'can_fee_counter_academic_fee',
|
|
560
564
|
CAN_FEE_COUNTER_EXAM_FEE = 'can_fee_counter_exam_fee',
|
|
561
565
|
|
|
566
|
+
//Payments imports
|
|
567
|
+
CAN_IMPORT_RECEIPTS='can_import_receipts',
|
|
568
|
+
CAN_IMPORT_CREDITS='can_import_credits',
|
|
569
|
+
|
|
562
570
|
// Fee Groups
|
|
563
571
|
CAN_FEE_GROUP_VIEW = 'can_fee_groups_view',
|
|
564
572
|
CAN_FEE_GROUP_ADD = 'can_fee_groups_add',
|
|
@@ -577,7 +585,7 @@ export enum Permission {
|
|
|
577
585
|
CAN_FEE_STRUCTURE_EDIT = 'can_fee_structure_edit',
|
|
578
586
|
CAN_FEE_STRUCTURE_DELETE = 'can_fee_structure_delete',
|
|
579
587
|
|
|
580
|
-
// Fine
|
|
588
|
+
// Fine Configurastion
|
|
581
589
|
CAN_FINE_CONFIGURATION_VIEW = 'can_fine_configurations_view',
|
|
582
590
|
CAN_FINE_CONFIGURATION_ADD = 'can_fine_configurations_add',
|
|
583
591
|
CAN_FINE_CONFIGURATION_EDIT = 'can_fine_configurations_edit',
|
|
@@ -1432,16 +1440,26 @@ export interface IPermissions {
|
|
|
1432
1440
|
can_assessment_templates_edit: boolean
|
|
1433
1441
|
can_assessment_templates_view: boolean
|
|
1434
1442
|
can_assessment_templates_delete: boolean
|
|
1443
|
+
|
|
1444
|
+
//
|
|
1445
|
+
can_student_academic_performance_view: boolean
|
|
1446
|
+
can_student_permissions_add: boolean
|
|
1447
|
+
can_student_permissions_edit: boolean
|
|
1448
|
+
can_student_permissions_delete: boolean
|
|
1435
1449
|
}
|
|
1436
1450
|
|
|
1437
1451
|
interface IPermissionsStore {
|
|
1438
1452
|
permissions: IPermissions
|
|
1439
1453
|
applications: string[]
|
|
1440
1454
|
institutionType: 'MASTER_CHILD' | 'INDIVIDUAL'
|
|
1455
|
+
masterInstitutionUniqueId?: number
|
|
1456
|
+
masterInstitutionId?: string
|
|
1441
1457
|
}
|
|
1442
1458
|
|
|
1443
1459
|
export const PermissionsStore = new Store<IPermissionsStore>({
|
|
1444
1460
|
permissions: null,
|
|
1445
1461
|
applications: [],
|
|
1446
1462
|
institutionType: null,
|
|
1463
|
+
masterInstitutionUniqueId: null,
|
|
1464
|
+
masterInstitutionId: null,
|
|
1447
1465
|
})
|