diff --git a/app/shared/overnight-calendar/OvernightCalendar.js b/app/shared/overnight-calendar/OvernightCalendar.js
index 5a20466a9..52a311ec2 100644
--- a/app/shared/overnight-calendar/OvernightCalendar.js
+++ b/app/shared/overnight-calendar/OvernightCalendar.js
@@ -38,10 +38,10 @@ import { hasMaxReservations } from '../../utils/resourceUtils';
import OvernightHiddenHeading from './OvernightHiddenHeading';
function OvernightCalendar({
- currentLanguage, resource, t, selected, actions, isStaff,
+ currentLanguage, resource, t, selected, actions,
history, isLoggedIn, isStrongAuthSatisfied, isMaintenanceModeOn,
reservationId, onEditCancel, onEditConfirm, handleDateChange, selectedDate,
- isSuperuser,
+ isSuperuser, isResourceAdmin, isResourceManager,
}) {
if (!resource || !resource.reservations) {
return null;
@@ -70,10 +70,11 @@ function OvernightCalendar({
overnightStartTime, overnightEndTime, maxPeriod, minPeriod
} = resource;
- const hasAdminBypass = isSuperuser || isStaff;
+ const isUnitAdminOrHigher = isSuperuser || isResourceAdmin;
+ const isUnitManagerOrHigher = isSuperuser || isResourceAdmin || isResourceManager;
useEffect(() => {
- if (!hasAdminBypass && startDate && endDate && !datesSameAsInitial) {
+ if (!isUnitAdminOrHigher && startDate && endDate && !datesSameAsInitial) {
const selectedDuration = getSelectedDuration(
startDate, endDate, overnightStartTime, overnightEndTime);
const isDurBelowMin = isDurationBelowMin(selectedDuration, minPeriod);
@@ -98,7 +99,11 @@ function OvernightCalendar({
const now = moment();
const reservingIsAllowed = isReservingAllowed({
- isLoggedIn, isStrongAuthSatisfied, isMaintenanceModeOn, resource, hasAdminBypass
+ isLoggedIn,
+ isStrongAuthSatisfied,
+ isMaintenanceModeOn,
+ resource,
+ hasAdminBypass: isUnitManagerOrHigher
});
const validateAndSelect = (day, { booked, nextBooked, nextClosed }) => {
@@ -116,7 +121,7 @@ function OvernightCalendar({
minPeriod,
overnightEndTime,
overnightStartTime,
- hasAdminBypass,
+ hasAdminBypass: isUnitManagerOrHigher,
});
if (!reservingIsAllowed) {
@@ -155,7 +160,7 @@ function OvernightCalendar({
const isEditing = !!initialStart;
const handleSelectDatetimes = () => {
- if (!hasAdminBypass && hasMaxReservations(resource) && !isEditing) {
+ if (!isUnitManagerOrHigher && hasMaxReservations(resource) && !isEditing) {
actions.addNotification({
message: t('TimeSlots.maxReservationsPerUser'),
type: 'error',
@@ -176,7 +181,8 @@ function OvernightCalendar({
const selectedDuration = getSelectedDuration(
startDate, endDate, overnightStartTime, overnightEndTime);
- const isDurBelowMin = hasAdminBypass ? false : isDurationBelowMin(selectedDuration, minPeriod);
+ const isDurBelowMin = isUnitAdminOrHigher ? false
+ : isDurationBelowMin(selectedDuration, minPeriod);
return (
@@ -199,7 +205,7 @@ function OvernightCalendar({
minPeriod,
overnightEndTime,
overnightStartTime,
- hasAdminBypass,
+ hasAdminBypass: isUnitManagerOrHigher,
})}
enableOutsideDays
firstDayOfWeek={1}
@@ -271,7 +277,8 @@ OvernightCalendar.propTypes = {
selected: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
- isStaff: PropTypes.bool.isRequired,
+ isResourceAdmin: PropTypes.bool.isRequired,
+ isResourceManager: PropTypes.bool.isRequired,
isSuperuser: PropTypes.bool.isRequired,
isLoggedIn: PropTypes.bool.isRequired,
isStrongAuthSatisfied: PropTypes.bool.isRequired,
diff --git a/app/shared/overnight-calendar/OvernightCalendarSelector.js b/app/shared/overnight-calendar/OvernightCalendarSelector.js
index 207240a63..fb8542dc1 100644
--- a/app/shared/overnight-calendar/OvernightCalendarSelector.js
+++ b/app/shared/overnight-calendar/OvernightCalendarSelector.js
@@ -3,7 +3,8 @@ import { createStructuredSelector } from 'reselect';
import { currentLanguageSelector } from 'state/selectors/translationSelectors';
import {
isLoggedInSelector, isSuperUserSelector,
- createIsAdminForResourceSelector
+ createIsAdminForResourceSelector,
+ createIsManagerForResourceSelector
} from 'state/selectors/authSelectors';
import { createResourceSelector, createStrongAuthSatisfiedSelector } from 'state/selectors/dataSelectors';
@@ -18,7 +19,8 @@ const OvernightCalendarSelector = createStructuredSelector({
isStrongAuthSatisfied: createStrongAuthSatisfiedSelector(resourceSelector),
currentLanguage: currentLanguageSelector,
isLoggedIn: isLoggedInSelector,
- isStaff: createIsAdminForResourceSelector(resourceSelector),
+ isResourceAdmin: createIsAdminForResourceSelector(resourceSelector),
+ isResourceManager: createIsManagerForResourceSelector(resourceSelector),
isSuperuser: isSuperUserSelector,
});
diff --git a/app/shared/overnight-calendar/tests/OvernightCalendar.spec.js b/app/shared/overnight-calendar/tests/OvernightCalendar.spec.js
index 8df02987e..0b44d4f19 100644
--- a/app/shared/overnight-calendar/tests/OvernightCalendar.spec.js
+++ b/app/shared/overnight-calendar/tests/OvernightCalendar.spec.js
@@ -28,7 +28,8 @@ describe('app/shared/overnight-calendar/OvernightCalendar', () => {
addNotification: () => {},
},
history: {},
- isStaff: false,
+ isResourceAdmin: false,
+ isResourceManager: false,
isSuperuser: false,
isLoggedIn: false,
isStrongAuthSatisfied: false,
diff --git a/app/shared/overnight-calendar/tests/OvernightCalendarSelector.spec.js b/app/shared/overnight-calendar/tests/OvernightCalendarSelector.spec.js
index 86ac2be62..6a7571530 100644
--- a/app/shared/overnight-calendar/tests/OvernightCalendarSelector.spec.js
+++ b/app/shared/overnight-calendar/tests/OvernightCalendarSelector.spec.js
@@ -35,8 +35,12 @@ describe('app/shared/overnight-calendar/OvernightCalendarSelector', () => {
expect(getSelected().currentLanguage).toBeDefined();
});
- test('returns isStaff', () => {
- expect(getSelected().isStaff).toBeDefined();
+ test('returns isResourceAdmin', () => {
+ expect(getSelected().isResourceAdmin).toBeDefined();
+ });
+
+ test('returns isResourceManager', () => {
+ expect(getSelected().isResourceManager).toBeDefined();
});
test('returns isSuperUserSelector', () => {
diff --git a/app/state/selectors/authSelectors.js b/app/state/selectors/authSelectors.js
index 7d852205d..95ea0c354 100644
--- a/app/state/selectors/authSelectors.js
+++ b/app/state/selectors/authSelectors.js
@@ -2,7 +2,7 @@ import forIn from 'lodash/forIn';
import includes from 'lodash/includes';
import { createSelector } from 'reselect';
-import { isStaffForResource, isAdminForResource } from 'utils/resourceUtils';
+import { isStaffForResource, isAdminForResource, isManagerForResource } from 'utils/resourceUtils';
const authUserSelector = state => state.auth.user;
const usersSelector = state => state.data.users;
@@ -90,6 +90,13 @@ function createIsAdminForResourceSelector(resourceSelector) {
);
}
+function createIsManagerForResourceSelector(resourceSelector) {
+ return createSelector(
+ resourceSelector,
+ (resource) => isManagerForResource(resource)
+ );
+}
+
const authUserAmrSelector = createSelector(
authUserSelector,
(user) => {
@@ -114,4 +121,5 @@ export {
isManagerForSelector,
hasStrongAuthSelector,
createIsAdminForResourceSelector,
+ createIsManagerForResourceSelector,
};
diff --git a/app/state/selectors/authSelectors.spec.js b/app/state/selectors/authSelectors.spec.js
index 4d03623b7..1c596f4b0 100644
--- a/app/state/selectors/authSelectors.spec.js
+++ b/app/state/selectors/authSelectors.spec.js
@@ -13,6 +13,7 @@ import {
hasStrongAuthSelector,
authUserAmrSelector,
createIsAdminForResourceSelector,
+ createIsManagerForResourceSelector,
} from './authSelectors';
import Resource from '../../utils/fixtures/Resource';
@@ -315,6 +316,34 @@ describe('state/selectors/authSelectors', () => {
});
});
+ describe('createIsManagerForResourceSelector', () => {
+ test('returns true if user has unit manager perm for resource', () => {
+ const resource = Resource.build({
+ userPermissions: {
+ isManager: true,
+ },
+ });
+ const resourceSelector = () => resource;
+ const state = getState({
+ 'data.resources': { [resource.id]: resource }
+ });
+ expect(createIsManagerForResourceSelector(resourceSelector)(state)).toEqual(true);
+ });
+
+ test('returns false if user doesnt not have unit manager perm for resource', () => {
+ const resource = Resource.build({
+ userPermissions: {
+ isManager: false,
+ },
+ });
+ const resourceSelector = () => resource;
+ const state = getState({
+ 'data.resources': { [resource.id]: resource }
+ });
+ expect(createIsManagerForResourceSelector(resourceSelector)(state)).toEqual(false);
+ });
+ });
+
describe('authUserAmrSelector', () => {
test('returns user profile amr value if it exists', () => {
const amr = 'test-amr-1';
diff --git a/app/utils/__tests__/resourceUtils.spec.js b/app/utils/__tests__/resourceUtils.spec.js
index 23eaf36cd..a0edada3f 100644
--- a/app/utils/__tests__/resourceUtils.spec.js
+++ b/app/utils/__tests__/resourceUtils.spec.js
@@ -26,7 +26,8 @@ import {
getEquipment,
isStaffForResource,
isStrongAuthSatisfied,
- isAdminForResource
+ isAdminForResource,
+ isManagerForResource
} from 'utils/resourceUtils';
import { getPrettifiedPeriodUnits } from '../timeUtils';
import Product from '../fixtures/Product';
@@ -1162,6 +1163,18 @@ describe('Utils: resourceUtils', () => {
});
});
+ describe('isManagerForResource', () => {
+ test('returns true when userPermissions is admin is true', () => {
+ const resource = Resource.build({ userPermissions: { isManager: true } });
+ expect(isManagerForResource(resource)).toBe(true);
+ });
+
+ test('returns false when userPermissions is admin is false', () => {
+ const resource = Resource.build({ userPermissions: { isManager: false } });
+ expect(isManagerForResource(resource)).toBe(false);
+ });
+ });
+
describe('isStrongAuthSatisfied', () => {
describe('when resource requires strong auth', () => {
const resource = Resource.build({ authentication: 'strong' });
diff --git a/app/utils/resourceUtils.js b/app/utils/resourceUtils.js
index e5ed86097..7179bef49 100644
--- a/app/utils/resourceUtils.js
+++ b/app/utils/resourceUtils.js
@@ -323,6 +323,21 @@ function isAdminForResource(resource) {
return false;
}
+/**
+ * Check whether current user is manager for given resource.
+ * @param {Object} resource
+ * @returns {boolean} true when user is manager for given resource, false if not.
+ */
+function isManagerForResource(resource) {
+ if (resource.userPermissions) {
+ const perms = resource.userPermissions;
+ if (perms.isManager) {
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* Checks whether strong auth requirement is satisfied with given resource and
* strong auth status.
@@ -357,4 +372,5 @@ export {
isStaffForResource,
isStrongAuthSatisfied,
isAdminForResource,
+ isManagerForResource,
};