diff --git a/analytics-api/src/analytics_api/models/request_type_option.py b/analytics-api/src/analytics_api/models/request_type_option.py index c2a36fda4..4c48e0394 100644 --- a/analytics-api/src/analytics_api/models/request_type_option.py +++ b/analytics-api/src/analytics_api/models/request_type_option.py @@ -19,7 +19,8 @@ class RequestTypeOption(BaseModel, RequestMixin): # pylint: disable=too-few-pub @classmethod def get_survey_result( cls, - engagement_id + engagement_id, + can_view_all_survey_results ): """Get the analytics survey id for an engagement id.""" analytics_survey_id = (db.session.query(SurveyModel.id) @@ -28,15 +29,26 @@ def get_survey_result( .subquery()) # Get all the survey questions specific to a survey id which are in active status. - survey_question = (db.session.query(RequestTypeOption.position.label('position'), - RequestTypeOption.label.label('label'), - RequestTypeOption.request_id) - .filter(and_(RequestTypeOption.survey_id.in_(analytics_survey_id), - RequestTypeOption.is_active == true(), - or_(RequestTypeOption.display == true(), - RequestTypeOption.display.is_(None)))) - .order_by(RequestTypeOption.position) - .subquery()) + # for users with role to view all surveys fetch all survey questions + # for all other users exclude questions excluded on report settings + if can_view_all_survey_results: + survey_question = (db.session.query(RequestTypeOption.position.label('position'), + RequestTypeOption.label.label('label'), + RequestTypeOption.request_id) + .filter(and_(RequestTypeOption.survey_id.in_(analytics_survey_id), + RequestTypeOption.is_active == true())) + .order_by(RequestTypeOption.position) + .subquery()) + else: + survey_question = (db.session.query(RequestTypeOption.position.label('position'), + RequestTypeOption.label.label('label'), + RequestTypeOption.request_id) + .filter(and_(RequestTypeOption.survey_id.in_(analytics_survey_id), + RequestTypeOption.is_active == true(), + or_(RequestTypeOption.display == true(), + RequestTypeOption.display.is_(None)))) + .order_by(RequestTypeOption.position) + .subquery()) # Get all the survey responses with the counts for each response specific to a survey id which # are in active status. diff --git a/analytics-api/src/analytics_api/resources/survey_result.py b/analytics-api/src/analytics_api/resources/survey_result.py index a22c7cce0..a07f57f38 100644 --- a/analytics-api/src/analytics_api/resources/survey_result.py +++ b/analytics-api/src/analytics_api/resources/survey_result.py @@ -19,7 +19,8 @@ from flask_cors import cross_origin from flask_restx import Namespace, Resource -from analytics_api.auth import auth +from analytics_api.auth import jwt as _jwt +from analytics_api.utils.roles import Role from analytics_api.services.survey_result import SurveyResultService from analytics_api.utils.util import allowedorigins, cors_preflight @@ -30,17 +31,41 @@ @cors_preflight('GET,OPTIONS') -@API.route('/') -class SurveyResult(Resource): +@API.route('//internal') +class SurveyResultInternal(Resource): """Resource for managing a survey result for single engagement.""" @staticmethod @cross_origin(origins=allowedorigins()) - @auth.optional + @_jwt.has_one_of_roles([Role.VIEW_ALL_SURVEY_RESULTS.value]) def get(engagement_id): """Fetch survey result for a single engagement id.""" try: - survey_result_record = SurveyResultService().get_survey_result(engagement_id) + survey_result_record = SurveyResultService().get_survey_result(engagement_id, + can_view_all_survey_results=True) + + if survey_result_record: + return jsonify(data=survey_result_record), HTTPStatus.OK + + return 'Engagement was not found', HTTPStatus.NOT_FOUND + except KeyError: + return 'Engagement was not found', HTTPStatus.INTERNAL_SERVER_ERROR + except ValueError as err: + return str(err), HTTPStatus.INTERNAL_SERVER_ERROR + + +@cors_preflight('GET,OPTIONS') +@API.route('//public') +class SurveyResultExternal(Resource): + """Resource for managing a survey result for single engagement.""" + + @staticmethod + @cross_origin(origins=allowedorigins()) + def get(engagement_id): + """Fetch survey result for a single engagement id.""" + try: + survey_result_record = SurveyResultService().get_survey_result(engagement_id, + can_view_all_survey_results=False) if survey_result_record: return jsonify(data=survey_result_record), HTTPStatus.OK diff --git a/analytics-api/src/analytics_api/services/survey_result.py b/analytics-api/src/analytics_api/services/survey_result.py index 2f8128550..9bebe4d2b 100644 --- a/analytics-api/src/analytics_api/services/survey_result.py +++ b/analytics-api/src/analytics_api/services/survey_result.py @@ -9,8 +9,8 @@ class SurveyResultService: # pylint: disable=too-few-public-methods otherdateformat = '%Y-%m-%d' @staticmethod - def get_survey_result(engagement_id) -> SurveyResultSchema: + def get_survey_result(engagement_id, can_view_all_survey_results) -> SurveyResultSchema: """Get Survey result by the engagement id.""" - survey_result = RequestTypeOptionModel.get_survey_result(engagement_id) + survey_result = RequestTypeOptionModel.get_survey_result(engagement_id, can_view_all_survey_results) survey_result_schema = SurveyResultSchema(many=True) return survey_result_schema.dump(survey_result) diff --git a/analytics-api/src/analytics_api/utils/roles.py b/analytics-api/src/analytics_api/utils/roles.py new file mode 100644 index 000000000..e9a801c21 --- /dev/null +++ b/analytics-api/src/analytics_api/utils/roles.py @@ -0,0 +1,58 @@ +# Copyright © 2019 Province of British Columbia +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Role definitions.""" +from enum import Enum + + +class Role(Enum): + """User Role.""" + + PUBLIC_USER = 'public_user' + ANONYMOUS_USER = 'anonymous_user' + + # STAFF Based roles + CREATE_TENANT = 'create_tenant' + VIEW_TENANT = 'view_tenant' + VIEW_USERS = 'view_users' + TOGGLE_USER_STATUS = 'toggle_user_status' + CREATE_ADMIN_USER = 'create_admin_user' + CREATE_TEAM = 'create_team' + CREATE_ENGAGEMENT = 'create_engagement' + VIEW_SURVEYS = 'view_surveys' + CREATE_SURVEY = 'create_survey' + EDIT_SURVEY = 'edit_survey' + CLONE_SURVEY = 'clone_survey' + PUBLISH_ENGAGEMENT = 'publish_engagement' + VIEW_ENGAGEMENT = 'view_engagement' + VIEW_ASSIGNED_ENGAGEMENTS = 'view_assigned_engagements' + VIEW_PRIVATE_ENGAGEMENTS = 'view_private_engagements' + EDIT_ENGAGEMENT = 'edit_engagement' + REVIEW_COMMENTS = 'review_comments' + REVIEW_ALL_COMMENTS = 'review_all_comments' + ACCESS_DASHBOARD = 'access_dashboard' + VIEW_MEMBERS = 'view_members' + EDIT_MEMBERS = 'edit_members' + VIEW_ALL_SURVEYS = 'view_all_surveys' # Super user can view all kind of surveys including hidden + EDIT_ALL_SURVEYS = 'edit_all_surveys' + EDIT_DRAFT_ENGAGEMENT = 'edit_draft_engagement' + EDIT_SCHEDULED_ENGAGEMENT = 'edit_scheduled_engagement' + EDIT_UPCOMING_ENGAGEMENT = 'edit_upcoming_engagement' + EDIT_OPEN_ENGAGEMENT = 'edit_open_engagement' + EDIT_CLOSED_ENGAGEMENT = 'edit_closed_engagement' + VIEW_APPROVED_COMMENTS = 'view_approved_comments' # used just in the front end to show the comment page + VIEW_FEEDBACKS = 'view_feedbacks' + VIEW_ALL_ENGAGEMENTS = 'view_all_engagements' # Allows user access to all engagements including draft + SHOW_ALL_COMMENT_STATUS = 'show_all_comment_status' # Allows user to see all comment status + EXPORT_TO_CSV = 'export_to_csv' # Allows users to export comments to csv + VIEW_ALL_SURVEY_RESULTS = 'view_all_survey_results' # Allows users to view results to all questions diff --git a/analytics-api/src/analytics_api/utils/user_context.py b/analytics-api/src/analytics_api/utils/user_context.py new file mode 100644 index 000000000..a4811cf65 --- /dev/null +++ b/analytics-api/src/analytics_api/utils/user_context.py @@ -0,0 +1,116 @@ +# Copyright © 2019 Province of British Columbia +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""User Context to hold request scoped variables.""" + +import functools +from typing import Dict + +from flask import g, request + +from analytics_api.utils.roles import Role + + +def _get_context(): + """Return User context.""" + return UserContext() + + +class UserContext: # pylint: disable=too-many-instance-attributes + """Object to hold request scoped user context.""" + + def __init__(self): + """Return a User Context object.""" + token_info: Dict = _get_token_info() or {} + self._token_info = token_info + self._user_name: str = token_info.get('username', token_info.get('preferred_username', None)) + self._first_name: str = token_info.get('firstname', None) + self._last_name: str = token_info.get('lastname', None) + self._bearer_token: str = _get_token() + self._roles: list = token_info.get('realm_access', None).get('roles', []) if 'realm_access' in token_info \ + else [] + self._sub: str = token_info.get('sub', None) + self._name: str = f"{token_info.get('firstname', None)} {token_info.get('lastname', None)}" + + @property + def user_name(self) -> str: + """Return the user_name.""" + return self._user_name if self._user_name else None + + @property + def first_name(self) -> str: + """Return the user_first_name.""" + return self._first_name + + @property + def last_name(self) -> str: + """Return the user_last_name.""" + return self._last_name + + @property + def bearer_token(self) -> str: + """Return the bearer_token.""" + return self._bearer_token + + @property + def roles(self) -> list: + """Return the roles.""" + return self._roles + + @property + def sub(self) -> str: + """Return the subject.""" + return self._sub + + def has_role(self, role_name: str) -> bool: + """Return True if the user has the role.""" + return role_name in self._roles + + def is_staff_admin(self) -> bool: + """Return True if the user is staff user.""" + return Role.CREATE_ENGAGEMENT.value in self._roles if self._roles else False + + def is_system(self) -> bool: + """Return True if the user is system user.Helps to idenitfy connections from EPIC.""" + return Role.SYSTEM.value in self._roles if self._roles else False + + @property + def name(self) -> str: + """Return the name.""" + return self._name + + @property + def token_info(self) -> Dict: + """Return the name.""" + return self._token_info + + +def user_context(function): + """Add user context object as an argument to function.""" + + @functools.wraps(function) + def wrapper(*func_args, **func_kwargs): + context = _get_context() + func_kwargs['user_context'] = context + return function(*func_args, **func_kwargs) + + return wrapper + + +def _get_token_info() -> Dict: + return g.jwt_oidc_token_info if g and 'jwt_oidc_token_info' in g else {} + + +def _get_token() -> str: + token: str = request.headers['Authorization'] if request and 'Authorization' in request.headers else None + return token.replace('Bearer ', '') if token else None diff --git a/analytics-api/src/analytics_api/utils/util.py b/analytics-api/src/analytics_api/utils/util.py index a31a522b8..dba5e3a6a 100644 --- a/analytics-api/src/analytics_api/utils/util.py +++ b/analytics-api/src/analytics_api/utils/util.py @@ -76,3 +76,10 @@ class ContentType(Enum): JSON = 'application/json' FORM_URL_ENCODED = 'application/x-www-form-urlencoded' PDF = 'application/pdf' + + +class DashboardType(Enum): + """Dashboard Types.""" + + PUBLIC = 'public' + INTERNAL = 'internal' diff --git a/met-api/src/met_api/utils/roles.py b/met-api/src/met_api/utils/roles.py index fda7d3707..e9a801c21 100644 --- a/met-api/src/met_api/utils/roles.py +++ b/met-api/src/met_api/utils/roles.py @@ -55,3 +55,4 @@ class Role(Enum): VIEW_ALL_ENGAGEMENTS = 'view_all_engagements' # Allows user access to all engagements including draft SHOW_ALL_COMMENT_STATUS = 'show_all_comment_status' # Allows user to see all comment status EXPORT_TO_CSV = 'export_to_csv' # Allows users to export comments to csv + VIEW_ALL_SURVEY_RESULTS = 'view_all_survey_results' # Allows users to view results to all questions diff --git a/met-web/src/apiManager/endpoints/index.ts b/met-web/src/apiManager/endpoints/index.ts index e2f18a307..80b421b1a 100644 --- a/met-web/src/apiManager/endpoints/index.ts +++ b/met-web/src/apiManager/endpoints/index.ts @@ -144,7 +144,7 @@ const Endpoints = { GET: `${AppConfig.analyticsApiUrl}/engagements/map/engagement_id`, }, AnalyticsSurveyResult: { - GET: `${AppConfig.analyticsApiUrl}/surveyresult/engagement_id`, + GET: `${AppConfig.analyticsApiUrl}/surveyresult/engagement_id/dashboard_type`, }, }; diff --git a/met-web/src/components/dashboard/EngagementsAccordion.tsx b/met-web/src/components/dashboard/EngagementsAccordion.tsx index b6862b40d..1349126c4 100644 --- a/met-web/src/components/dashboard/EngagementsAccordion.tsx +++ b/met-web/src/components/dashboard/EngagementsAccordion.tsx @@ -9,6 +9,7 @@ import SurveysCompleted from '../publicDashboard/KPI/SurveysCompleted'; import ProjectLocation from '../publicDashboard/KPI/ProjectLocation'; import SubmissionTrend from '../publicDashboard/SubmissionTrend/SubmissionTrend'; import SurveyBar from '../publicDashboard/SurveyBar'; +import { DashboardType } from 'constants/dashboardType'; const EngagementsAccordion = ({ engagements, @@ -112,7 +113,11 @@ const EngagementsAccordion = ({ - + diff --git a/met-web/src/components/engagement/listing/ActionsDropDown.tsx b/met-web/src/components/engagement/listing/ActionsDropDown.tsx index cdfdc94a6..a629d0c27 100644 --- a/met-web/src/components/engagement/listing/ActionsDropDown.tsx +++ b/met-web/src/components/engagement/listing/ActionsDropDown.tsx @@ -89,9 +89,9 @@ export const ActionsDropDown = ({ engagement }: { engagement: Engagement }) => { }, { value: 3, - label: 'View Report', + label: 'View Report - Public', action: () => { - navigate(`/engagements/${engagement.id}/dashboard`); + navigate(`/engagements/${engagement.id}/dashboard/public`); }, condition: submissionHasBeenOpened && @@ -99,6 +99,17 @@ export const ActionsDropDown = ({ engagement }: { engagement: Engagement }) => { }, { value: 4, + label: 'View Report - Internal', + action: () => { + navigate(`/engagements/${engagement.id}/dashboard/internal`); + }, + condition: + submissionHasBeenOpened && + roles.includes(USER_ROLES.VIEW_ALL_SURVEY_RESULTS) && + (roles.includes(USER_ROLES.ACCESS_DASHBOARD) || assignedEngagements.includes(engagement.id)), + }, + { + value: 5, label: 'View All Comments', action: () => { navigate(`/surveys/${engagement.surveys[0].id}/comments`); diff --git a/met-web/src/components/publicDashboard/Dashboard.tsx b/met-web/src/components/publicDashboard/Dashboard.tsx index cd1e8bde4..df8f2ef80 100644 --- a/met-web/src/components/publicDashboard/Dashboard.tsx +++ b/met-web/src/components/publicDashboard/Dashboard.tsx @@ -25,7 +25,7 @@ const Dashboard = () => { const { slug } = useParams(); const isTablet = useMediaQuery((theme: Theme) => theme.breakpoints.down('md')); const navigate = useNavigate(); - const { engagement, isEngagementLoading } = useContext(DashboardContext); + const { engagement, isEngagementLoading, dashboardType } = useContext(DashboardContext); const [isPrinting, setIsPrinting] = React.useState(false); const [projectMapData, setProjectMapData] = React.useState(null); const [pdfExportProgress, setPdfExportProgress] = React.useState(0); @@ -198,12 +198,14 @@ const Dashboard = () => { diff --git a/met-web/src/components/publicDashboard/DashboardContext.tsx b/met-web/src/components/publicDashboard/DashboardContext.tsx index 29c7bf685..6d3f420ad 100644 --- a/met-web/src/components/publicDashboard/DashboardContext.tsx +++ b/met-web/src/components/publicDashboard/DashboardContext.tsx @@ -7,15 +7,18 @@ import { getEngagement } from 'services/engagementService'; import { openNotification } from 'services/notificationService/notificationSlice'; import { getErrorMessage } from 'utils'; import { getEngagementIdBySlug } from 'services/engagementSlugService'; +import { DashboardType } from 'constants/dashboardType'; export interface DashboardContextState { engagement: Engagement; isEngagementLoading: boolean; + dashboardType: string; } export const DashboardContext = createContext({ engagement: createDefaultEngagement(), isEngagementLoading: true, + dashboardType: DashboardType.PUBLIC, }); interface DashboardContextProviderProps { @@ -25,10 +28,11 @@ interface DashboardContextProviderProps { type EngagementParams = { engagementId?: string; slug?: string; + dashboardType?: string; }; export const DashboardContextProvider = ({ children }: DashboardContextProviderProps) => { - const { engagementId: engagementIdParam, slug } = useParams(); + const { engagementId: engagementIdParam, slug, dashboardType: dashboardTypeParam } = useParams(); const navigate = useNavigate(); const dispatch = useAppDispatch(); const roles = useAppSelector((state) => state.user.roles); @@ -40,6 +44,8 @@ export const DashboardContextProvider = ({ children }: DashboardContextProviderP const [engagement, setEngagement] = useState(createDefaultEngagement()); const [isEngagementLoading, setEngagementLoading] = useState(true); + const dashboardType = dashboardTypeParam ? dashboardTypeParam : DashboardType.PUBLIC; + const validateEngagement = (engagementToValidate: Engagement) => { // submission status e.g. of pending or draft will have id less than of Open const neverOpened = [SubmissionStatus.Upcoming].includes(engagementToValidate?.submission_status); @@ -105,6 +111,7 @@ export const DashboardContextProvider = ({ children }: DashboardContextProviderP value={{ engagement, isEngagementLoading, + dashboardType, }} > {children} diff --git a/met-web/src/components/publicDashboard/SurveyBar/index.tsx b/met-web/src/components/publicDashboard/SurveyBar/index.tsx index 0a56f86b4..95a82ffed 100644 --- a/met-web/src/components/publicDashboard/SurveyBar/index.tsx +++ b/met-web/src/components/publicDashboard/SurveyBar/index.tsx @@ -19,9 +19,10 @@ interface SurveyQuestionProps { engagement: Engagement; engagementIsLoading: boolean; readComments?: () => void; + dashboardType: string; } -export const SurveyBar = ({ readComments, engagement, engagementIsLoading }: SurveyQuestionProps) => { +export const SurveyBar = ({ readComments, engagement, engagementIsLoading, dashboardType }: SurveyQuestionProps) => { const isTablet = useMediaQuery((theme: Theme) => theme.breakpoints.down('md')); const [data, setData] = useState(createSurveyResultData()); const [selectedData, setSelectedData] = useState(defaultData[0]); @@ -37,7 +38,7 @@ export const SurveyBar = ({ readComments, engagement, engagementIsLoading }: Sur setIsLoading(true); setIsError(false); try { - const response = await getSurveyResultData(Number(engagement.id)); + const response = await getSurveyResultData(Number(engagement.id), dashboardType); setData(response); setSelectedData(response?.data[0]); setIsLoading(false); diff --git a/met-web/src/components/publicDashboard/SurveyBarPrintable/index.tsx b/met-web/src/components/publicDashboard/SurveyBarPrintable/index.tsx index b000169d1..20289d001 100644 --- a/met-web/src/components/publicDashboard/SurveyBarPrintable/index.tsx +++ b/met-web/src/components/publicDashboard/SurveyBarPrintable/index.tsx @@ -13,9 +13,10 @@ const HEIGHT = 400; interface SurveyQuestionProps { engagement: Engagement; engagementIsLoading: boolean; + dashboardType: string; } -export const SurveyBarPrintable = ({ engagement, engagementIsLoading }: SurveyQuestionProps) => { +export const SurveyBarPrintable = ({ engagement, engagementIsLoading, dashboardType }: SurveyQuestionProps) => { const [data, setData] = useState(createSurveyResultData()); const [isLoading, setIsLoading] = useState(true); const [isError, setIsError] = useState(false); @@ -23,7 +24,7 @@ export const SurveyBarPrintable = ({ engagement, engagementIsLoading }: SurveyQu const fetchData = async () => { setIsLoading(true); try { - const response = await getSurveyResultData(Number(engagement.id)); + const response = await getSurveyResultData(Number(engagement.id), dashboardType); setData(response); setIsLoading(false); setIsError(false); diff --git a/met-web/src/components/survey/listing/ActionsDropDown.tsx b/met-web/src/components/survey/listing/ActionsDropDown.tsx index ce53084f8..0841ee1c5 100644 --- a/met-web/src/components/survey/listing/ActionsDropDown.tsx +++ b/met-web/src/components/survey/listing/ActionsDropDown.tsx @@ -49,6 +49,14 @@ export const ActionsDropDown = ({ survey }: { survey: Survey }) => { ); }; + const canViewInternalReport = (): boolean => { + return ( + submissionHasBeenOpened && + roles.includes(USER_ROLES.VIEW_ALL_SURVEY_RESULTS) && + (roles.includes(USER_ROLES.ACCESS_DASHBOARD) || assignedEngagements.includes(engagementId)) + ); + }; + const canViewAllComments = (): boolean => { return ( submissionHasBeenOpened && @@ -70,14 +78,22 @@ export const ActionsDropDown = ({ survey }: { survey: Survey }) => { }, { value: 2, - label: 'View Report', + label: 'View Report - Public', action: () => { - navigate(`/engagements/${engagementId}/dashboard`); + navigate(`/engagements/${engagementId}/dashboard/public`); }, condition: canViewReport(), }, { value: 3, + label: 'View Report - Internal', + action: () => { + navigate(`/engagements/${engagementId}/dashboard/internal`); + }, + condition: canViewInternalReport(), + }, + { + value: 4, label: 'View All Comments', action: () => { navigate(`/surveys/${survey.id}/comments`); @@ -85,7 +101,7 @@ export const ActionsDropDown = ({ survey }: { survey: Survey }) => { condition: canViewAllComments(), }, { - value: 4, + value: 5, label: 'Edit Settings', action: () => { navigate(`/surveys/${survey.id}/report`); diff --git a/met-web/src/constants/dashboardType.ts b/met-web/src/constants/dashboardType.ts new file mode 100644 index 000000000..ffb3ff95e --- /dev/null +++ b/met-web/src/constants/dashboardType.ts @@ -0,0 +1,4 @@ +export enum DashboardType { + PUBLIC = 'public', + INTERNAL = 'internal', +} diff --git a/met-web/src/routes/AuthenticatedRoutes.tsx b/met-web/src/routes/AuthenticatedRoutes.tsx index 31f5a0046..d400331f4 100644 --- a/met-web/src/routes/AuthenticatedRoutes.tsx +++ b/met-web/src/routes/AuthenticatedRoutes.tsx @@ -53,7 +53,7 @@ const AuthenticatedRoutes = () => { } /> } /> - } /> + } /> }> } /> diff --git a/met-web/src/routes/UnauthenticatedRoutes.tsx b/met-web/src/routes/UnauthenticatedRoutes.tsx index a7161a0bb..aebc76f11 100644 --- a/met-web/src/routes/UnauthenticatedRoutes.tsx +++ b/met-web/src/routes/UnauthenticatedRoutes.tsx @@ -19,8 +19,8 @@ const UnauthenticatedRoutes = () => { /> } /> } /> - } /> - } /> + } /> + } /> } /> } /> } /> diff --git a/met-web/src/services/analytics/surveyResult/index.tsx b/met-web/src/services/analytics/surveyResult/index.tsx index 70fd02bfe..9b2c4d661 100644 --- a/met-web/src/services/analytics/surveyResult/index.tsx +++ b/met-web/src/services/analytics/surveyResult/index.tsx @@ -3,8 +3,12 @@ import { SurveyResultData } from 'models/analytics/surveyResult'; import Endpoints from 'apiManager/endpoints'; import { replaceUrl } from 'helper'; -export const getSurveyResultData = async (engagementId: number): Promise => { - const url = replaceUrl(Endpoints.AnalyticsSurveyResult.GET, 'engagement_id', String(engagementId)); +export const getSurveyResultData = async (engagementId: number, dashboardType: string): Promise => { + const url = replaceUrl( + replaceUrl(Endpoints.AnalyticsSurveyResult.GET, 'engagement_id', String(engagementId)), + 'dashboard_type', + dashboardType, + ); const response = await http.GetRequest(url); if (response.data) { return response.data; diff --git a/met-web/src/services/userService/constants.ts b/met-web/src/services/userService/constants.ts index 22e821336..43e45ad1e 100644 --- a/met-web/src/services/userService/constants.ts +++ b/met-web/src/services/userService/constants.ts @@ -32,4 +32,5 @@ export const USER_ROLES = { SHOW_ALL_COMMENT_STATUS: 'show_all_comment_status', TOGGLE_USER_STATUS: 'toggle_user_status', EXPORT_TO_CSV: 'export_to_csv', + VIEW_ALL_SURVEY_RESULTS: 'view_all_survey_results', };