diff --git a/src/actions.js b/src/actions.js
index 8e9d199..dcb61bd 100644
--- a/src/actions.js
+++ b/src/actions.js
@@ -1,7 +1,14 @@
import {
graphql, formatMutation, formatPageQueryWithCount, formatGQLString, formatPageQuery,
- baseApiUrl, decodeId, openBlob
+ baseApiUrl, decodeId, openBlob, formatQuery,
} from "@openimis/fe-core";
+import {ACTION_TYPE} from "./reducer";
+
+const GRIEVANCE_CONFIGURATION_PROJECTION = () => [
+ 'grievanceTypes',
+ 'grievanceFlags',
+ 'grievanceChannels',
+];
const CATEGORY_FULL_PROJECTION = (mm) => [
"id",
@@ -212,7 +219,6 @@ export function fetchInsureeTicket(mm, chfId) {
return graphql(payload, 'TICKET_TICKET');
}
-
export function fetchInsureeTickets(mm, filters) {
if (filters.filter((f) => f.startsWith("chfId")).length !== 0) {
qry = "ticketsByInsuree";
@@ -225,3 +231,8 @@ export function fetchInsureeTickets(mm, filters) {
);
return graphql(payload, RDX);
}
+
+export function fetchGrievanceConfiguration(params) {
+ const payload = formatQuery('grievanceConfig', params, GRIEVANCE_CONFIGURATION_PROJECTION())
+ return graphql(payload, ACTION_TYPE.GET_GRIEVANCE_CONFIGURATION);
+}
diff --git a/src/constants.js b/src/constants.js
index 041064f..ac65503 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -1,9 +1,11 @@
-export const TICKET_STATUS = ["Waiting", "Todo", "Inprogress", "Review", "Close"]
+export const TICKET_STATUS = ['Waiting', 'Todo', 'Inprogress', 'Review', 'Close'];
-export const TICKET_PRIORITY = ["Critical", "High", "Normal", "Low"]
+export const TICKET_PRIORITY = ['Critical', 'High', 'Normal', 'Low'];
export const RIGHT_TICKET = 123000;
export const RIGHT_TICKET_SEARCH = 123000;
export const RIGHT_TICKET_ADD = 123001;
export const RIGHT_TICKET_EDIT = 123002;
-export const RIGHT_TICKET_DELETE = 123003;
\ No newline at end of file
+export const RIGHT_TICKET_DELETE = 123003;
+
+export const MODULE_NAME = 'grievanceSocialProtection';
diff --git a/src/dialogs/GrievanceConfigurationDialog.js b/src/dialogs/GrievanceConfigurationDialog.js
new file mode 100644
index 0000000..625a266
--- /dev/null
+++ b/src/dialogs/GrievanceConfigurationDialog.js
@@ -0,0 +1,68 @@
+import React, { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import {
+ coreAlert,
+ useModulesManager,
+ useTranslations,
+} from '@openimis/fe-core';
+import { fetchGrievanceConfiguration } from '../actions';
+import {
+ MODULE_NAME,
+ RIGHT_TICKET,
+ RIGHT_TICKET_ADD,
+ RIGHT_TICKET_DELETE,
+ RIGHT_TICKET_EDIT,
+ RIGHT_TICKET_SEARCH,
+} from '../constants';
+
+function GrievanceConfigurationDialog({
+ rights,
+}) {
+ const modulesManager = useModulesManager();
+ const { formatMessage, formatMessageWithValues } = useTranslations(MODULE_NAME, modulesManager);
+ const dispatch = useDispatch();
+ const grievanceConfiguration = useSelector((state) => state?.grievanceSocialProtection?.grievanceConfig);
+ const fetchedGrievanceConfig = useSelector((state) => state?.grievanceSocialProtection?.fetchedGrievanceConfig);
+
+ const doesUserHaveRights = () => {
+ const rightsArray = [
+ RIGHT_TICKET,
+ RIGHT_TICKET_SEARCH,
+ RIGHT_TICKET_ADD,
+ RIGHT_TICKET_EDIT,
+ RIGHT_TICKET_DELETE,
+ ];
+ return rightsArray.every((right) => rights.includes(right));
+ };
+ const isMatchingConfigObject = (obj) => !(typeof obj !== 'object' || obj === null || Array.isArray(obj));
+
+ const isConfigMissing = (config) => Object.values(config).some((field) => !field);
+
+ const shouldDisplay = () => grievanceConfiguration
+ && doesUserHaveRights()
+ && isMatchingConfigObject(grievanceConfiguration)
+ && isConfigMissing(grievanceConfiguration);
+
+ useEffect(() => {
+ if (shouldDisplay()) {
+ const configString = JSON.stringify(grievanceConfiguration);
+ dispatch(coreAlert(
+ formatMessage('grievanceSocialProtection.dialogs.GrievanceConfigurationDialog.dialogHeader'),
+ formatMessageWithValues(
+ 'grievanceSocialProtection.dialogs.GrievanceConfigurationDialog.dialogBody',
+ { configString },
+ ),
+ ));
+ }
+ }, [grievanceConfiguration]);
+
+ useEffect(() => {
+ if (!fetchedGrievanceConfig) {
+ dispatch(fetchGrievanceConfiguration());
+ }
+ }, [fetchedGrievanceConfig]);
+
+ return null;
+}
+
+export default GrievanceConfigurationDialog;
diff --git a/src/index.js b/src/index.js
index 617d9a7..af909bf 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,54 +1,56 @@
-import React from "react";
-import messages_en from "./translations/en.json";
-import reducer from "./reducer";
-import { ListAlt } from "@material-ui/icons";
-import { FormattedMessage } from "@openimis/fe-core";
-import TicketMainMenu from "./menu/TicketMainMenu";
-import TicketsPage from "./pages/TicketsPage";
-import TicketPage from "./pages/TicketPage";
-import TicketSearcher from "./components/TicketSearcher";
-import TicketPriorityPicker from "./pickers/TicketPriorityPicker";
-import TicketStatusPicker from "./pickers/TicketStatusPicker";
-import DropDownCategoryPicker from "./pickers/DropDownCategoryPicker";
-import CategoryPicker from "./pickers/CategoryPicker";
-
-const ROUTE_TICKET_TICKETS = "ticket/tickets";
-const ROUTE_TICKET_TICKET = "ticket/ticket";
+// Disable due to core architecture
+/* eslint-disable camelcase */
+/* eslint-disable import/prefer-default-export */
+import React from 'react';
+import { ListAlt } from '@material-ui/icons';
+import { FormattedMessage } from '@openimis/fe-core';
+import messages_en from './translations/en.json';
+import reducer from './reducer';
+import TicketMainMenu from './menu/TicketMainMenu';
+import TicketsPage from './pages/TicketsPage';
+import TicketPage from './pages/TicketPage';
+import TicketSearcher from './components/TicketSearcher';
+import TicketPriorityPicker from './pickers/TicketPriorityPicker';
+import TicketStatusPicker from './pickers/TicketStatusPicker';
+import DropDownCategoryPicker from './pickers/DropDownCategoryPicker';
+import CategoryPicker from './pickers/CategoryPicker';
+import GrievanceConfigurationDialog from './dialogs/GrievanceConfigurationDialog';
+import { MODULE_NAME } from './constants';
+
+const ROUTE_TICKET_TICKETS = 'ticket/tickets';
+const ROUTE_TICKET_TICKET = 'ticket/ticket';
const DEFAULT_CONFIG = {
- "translations": [{ key: "en", messages: messages_en }],
- "reducers": [{ key: 'grievance', reducer }],
+ translations: [{ key: 'en', messages: messages_en }],
+ reducers: [{ key: 'grievanceSocialProtection', reducer }],
- "refs": [
- { key: "grievance.route.tickets", ref: ROUTE_TICKET_TICKETS },
- { key: "grievance.route.ticket", ref: ROUTE_TICKET_TICKET },
+ refs: [
+ { key: 'grievanceSocialProtection.route.tickets', ref: ROUTE_TICKET_TICKETS },
+ { key: 'grievanceSocialProtection.route.ticket', ref: ROUTE_TICKET_TICKET },
- { key: "grievance.route.ticketSearcher", ref: TicketSearcher },
+ { key: 'grievanceSocialProtection.route.ticketSearcher', ref: TicketSearcher },
- { key: "grievance.TicketStatusPicker", ref: TicketStatusPicker },
- { key: "grievance.TicketPriorityPicker", ref: TicketPriorityPicker },
- { key: "grievance.DropDownCategoryPicker", ref: DropDownCategoryPicker },
- { key: "grievance.CategoryPicker", ref: CategoryPicker },
+ { key: 'grievanceSocialProtection.TicketStatusPicker', ref: TicketStatusPicker },
+ { key: 'grievanceSocialProtection.TicketPriorityPicker', ref: TicketPriorityPicker },
+ { key: 'grievanceSocialProtection.DropDownCategoryPicker', ref: DropDownCategoryPicker },
+ { key: 'grievanceSocialProtection.CategoryPicker', ref: CategoryPicker },
+ { key: 'grievanceSocialProtection.GrievanceConfigurationDialog', ref: GrievanceConfigurationDialog },
],
- "core.Router": [
+ 'core.Router': [
{ path: ROUTE_TICKET_TICKETS, component: TicketsPage },
- { path: ROUTE_TICKET_TICKET+ "/:ticket_uuid?", component: TicketPage },
+ { path: `${ROUTE_TICKET_TICKET}/:ticket_uuid?`, component: TicketPage },
],
- "admin.MainMenu": [
+ 'admin.MainMenu': [
{
- text: ,
+ text: ,
icon: ,
- route: "/" + ROUTE_TICKET_TICKETS,
+ route: `/${ROUTE_TICKET_TICKETS}`,
},
],
- "core.MainMenu": [TicketMainMenu],
-
-
-}
+ 'core.MainMenu': [TicketMainMenu],
-export const GrievanceSocialProtectionModule = (cfg) => {
- return { ...DEFAULT_CONFIG, ...cfg };
-}
+};
+export const GrievanceSocialProtectionModule = (cfg) => ({ ...DEFAULT_CONFIG, ...cfg });
diff --git a/src/reducer.js b/src/reducer.js
index 3f2a95a..4558c87 100644
--- a/src/reducer.js
+++ b/src/reducer.js
@@ -1,175 +1,206 @@
+// Disabled due to consistency with other modules
+/* eslint-disable default-param-last */
+
import {
- parseData, pageInfo, formatServerError, formatGraphQLError,
- dispatchMutationReq, dispatchMutationResp, dispatchMutationErr,
+ parseData, pageInfo, formatServerError, formatGraphQLError,
+ dispatchMutationReq, dispatchMutationResp, dispatchMutationErr,
} from '@openimis/fe-core';
+import { ERROR, REQUEST, SUCCESS } from './utils/action-type';
+
+export const ACTION_TYPE = {
+ GET_GRIEVANCE_CONFIGURATION: 'GET_GRIEVANCE_CONFIGURATION',
+};
function reducer(
- state = {
- fetchingTickets: false,
- errorTickets: null,
+ state = {
+ fetchingTickets: false,
+ errorTickets: null,
+ fetchedTickets: false,
+ tickets: [],
+ ticketsPageInfo: { totalCount: 0 },
+
+ fetchingTicket: false,
+ errorTicket: null,
+ fetchedTicket: false,
+ ticket: null,
+ ticketPageInfo: { totalCount: 0 },
+
+ fetchingCategory: false,
+ fetchedCategory: false,
+ errorCategory: null,
+ category: [],
+ categoryPageInfo: { totalCount: 0 },
+
+ fetchingTicketAttachments: false,
+ fetchedTicketAttachments: false,
+ errorTicketAttachments: null,
+ ticketAttachments: null,
+
+ fetchingGrievanceConfig: false,
+ fetchedGrievanceConfig: false,
+ errorGrievanceConfig: null,
+ grievanceConfig: null,
+
+ submittingMutation: false,
+ mutation: {},
+ },
+ action,
+) {
+ switch (action.type) {
+ case 'TICKET_TICKETS_REQ':
+ return {
+ ...state,
+ fetchingTickets: true,
fetchedTickets: false,
tickets: [],
ticketsPageInfo: { totalCount: 0 },
-
- fetchingTicket: false,
- errorTicket: null,
+ errorTickets: null,
+ };
+ case 'TICKET_TICKETS_RESP':
+ return {
+ ...state,
+ fetchingTickets: false,
+ fetchedTickets: true,
+ tickets: parseData(action.payload.data.tickets),
+ ticketsPageInfo: pageInfo(action.payload.data.tickets),
+ errorTickets: formatGraphQLError(action.payload),
+ };
+ case 'TICKET_TICKETS_ERR':
+ return {
+ ...state,
+ fetching: false,
+ error: formatServerError(action.payload),
+ };
+ case 'TICKET_TICKET_REQ':
+ return {
+ ...state,
+ fetchingTicket: true,
fetchedTicket: false,
ticket: null,
- ticketPageInfo: { totalCount: 0 },
+ errorTicket: null,
+ };
+ case 'TICKET_TICKET_RESP':
+ var tickt = parseData(action.payload.data.ticketDetails);
+ return {
- fetchingCategory: false,
+ ...state,
+ fetchingTicket: false,
+ fetchedTicket: true,
+ ticket: (!!tickt && tickt.length > 0) ? tickt[0] : null,
+ errorTicket: formatGraphQLError(action.payload),
+ };
+ case 'CATEGORY_CATEGORY_REQ':
+ return {
+ ...state,
+ fetchingCategory: true,
fetchedCategory: false,
- errorCategory: null,
category: [],
- categoryPageInfo: { totalCount: 0 },
-
- fetchingTicketAttachments: false,
+ errorCategory: null,
+ };
+ case 'CATEGORY_CATEGORY_RESP':
+ return {
+ ...state,
+ fetchingCategory: false,
+ fetchedCategory: true,
+ category: parseData(action.payload.data.category),
+ categoryPageInfo: pageInfo(action.payload.data.category),
+ errorCategory: formatGraphQLError(action.payload),
+ };
+ case 'CATEGORY_CATEGORY_ERR':
+ return {
+ ...state,
+ fetching: false,
+ error: formatServerError(action.payload),
+ };
+ case 'TICKET_TICKET_ATTACHMENTS_REQ':
+ return {
+ ...state,
+ fetchingTicketAttachments: true,
fetchedTicketAttachments: false,
- errorTicketAttachments: null,
ticketAttachments: null,
-
- submittingMutation: false,
- mutation: {},
- },
- action,
-) {
- switch (action.type) {
- case 'TICKET_TICKETS_REQ':
- return {
- ...state,
- fetchingTickets: true,
- fetchedTickets: false,
- tickets: [],
- ticketsPageInfo: { totalCount: 0 },
- errorTickets: null,
- };
- case 'TICKET_TICKETS_RESP':
- return {
- ...state,
- fetchingTickets: false,
- fetchedTickets: true,
- tickets: parseData(action.payload.data.tickets),
- ticketsPageInfo: pageInfo(action.payload.data.tickets),
- errorTickets: formatGraphQLError(action.payload)
- };
- case 'TICKET_TICKETS_ERR':
- return {
- ...state,
- fetching: false,
- error: formatServerError(action.payload)
- };
- case 'TICKET_TICKET_REQ':
- return {
- ...state,
- fetchingTicket: true,
- fetchedTicket: false,
- ticket: null,
- errorTicket: null,
- };
- case 'TICKET_TICKET_RESP':
- var tickt = parseData(action.payload.data.ticketDetails);
- return {
-
- ...state,
- fetchingTicket: false,
- fetchedTicket: true,
- ticket: (!!tickt && tickt.length > 0) ? tickt[0] : null,
- errorTicket: formatGraphQLError(action.payload)
- };
- case 'TICKET_TICKETS_ERR':
- return {
- ...state,
- fetching: false,
- error: formatServerError(action.payload)
- };
- case "CATEGORY_CATEGORY_REQ":
- return {
- ...state,
- fetchingCategory: true,
- fetchedCategory: false,
- category: [],
- errorCategory: null,
- };
- case "CATEGORY_CATEGORY_RESP":
- return {
- ...state,
- fetchingCategory: false,
- fetchedCategory: true,
- category: parseData(action.payload.data.category),
- categoryPageInfo: pageInfo(action.payload.data.category),
- errorCategory: formatGraphQLError(action.payload),
- };
- case "CATEGORY_CATEGORY_ERR":
- return {
- ...state,
- fetching: false,
- error: formatServerError(action.payload),
- };
- case "TICKET_TICKET_ATTACHMENTS_REQ":
- return {
- ...state,
- fetchingTicketAttachments: true,
- fetchedTicketAttachments: false,
- ticketAttachments: null,
- errorTicketAttachments: null,
- };
- case "TICKET_TICKET_ATTACHMENTS_RESP":
- return {
- ...state,
- fetchingTicketAttachments: false,
- fetchedTicketAttachments: true,
- ticketAttachments: parseData(action.payload.data.ticketAttachments),
- errorTicketAttachments: formatGraphQLError(action.payload),
- };
- case "TICKET_TICKET_ATTACHMENTS_ERR":
- return {
- ...state,
- fetchingTicketAttachments: false,
- errorTicketAttachments: formatServerError(action.payload),
- };
- case 'TICKET_INSUREE_TICKETS_REQ':
- return {
- ...state,
- fetchingTickets: true,
- fetchedTickets: false,
- tickets: null,
- policy: null,
- errorTickets: null,
- };
- case 'TICKET_INSUREE_TICKETS_RESP':
- return {
- ...state,
- fetchingTickets: false,
- fetchedTickets: true,
- tickets: parseData(action.payload.data.ticketsByInsuree),
- ticketsPageInfo: pageInfo(action.payload.data.ticketsByInsuree),
- errorTickets: formatGraphQLError(action.payload)
- };
- case 'TICKET_INSUREE_TICKETS_ERR':
- return {
- ...state,
- fetchingTickets: false,
- errorTickets: formatServerError(action.payload),
- };
- case "TICKET_MUTATION_REQ":
- return dispatchMutationReq(state, action);
- case "TICKET_MUTATION_ERR":
- return dispatchMutationErr(state, action);
- case "TICKET_CREATE_TICKET_RESP":
- return dispatchMutationResp(state, "createTicket", action);
- case "TICKET_UPDATE_TICKET_RESP":
- return dispatchMutationResp(state, "updateTicket", action);
- case "TICKET_DELETE_TICKET_RESP":
- return dispatchMutationResp(state, "deleteTicket", action);
- case "TICKET_ATTACHMENT_MUTATION_REQ":
- return dispatchMutationReq(state, action);
- case "TICKET_ATTACHMENT_MUTATION_ERR":
- return dispatchMutationErr(state, action);
- case "TICKET_CREATE_TICKET_ATTACHMENT_RESP":
- return dispatchMutationResp(state, "createTicketAttachment", action);
- default:
- return state;
- }
+ errorTicketAttachments: null,
+ };
+ case 'TICKET_TICKET_ATTACHMENTS_RESP':
+ return {
+ ...state,
+ fetchingTicketAttachments: false,
+ fetchedTicketAttachments: true,
+ ticketAttachments: parseData(action.payload.data.ticketAttachments),
+ errorTicketAttachments: formatGraphQLError(action.payload),
+ };
+ case 'TICKET_TICKET_ATTACHMENTS_ERR':
+ return {
+ ...state,
+ fetchingTicketAttachments: false,
+ errorTicketAttachments: formatServerError(action.payload),
+ };
+ case 'TICKET_INSUREE_TICKETS_REQ':
+ return {
+ ...state,
+ fetchingTickets: true,
+ fetchedTickets: false,
+ tickets: null,
+ policy: null,
+ errorTickets: null,
+ };
+ case 'TICKET_INSUREE_TICKETS_RESP':
+ return {
+ ...state,
+ fetchingTickets: false,
+ fetchedTickets: true,
+ tickets: parseData(action.payload.data.ticketsByInsuree),
+ ticketsPageInfo: pageInfo(action.payload.data.ticketsByInsuree),
+ errorTickets: formatGraphQLError(action.payload),
+ };
+ case 'TICKET_INSUREE_TICKETS_ERR':
+ return {
+ ...state,
+ fetchingTickets: false,
+ errorTickets: formatServerError(action.payload),
+ };
+ case REQUEST(ACTION_TYPE.GET_GRIEVANCE_CONFIGURATION):
+ return {
+ ...state,
+ fetchingGrievanceConfig: true,
+ fetchedGrievanceConfig: false,
+ errorGrievanceConfig: null,
+ grievanceConfig: null,
+ };
+ case SUCCESS(ACTION_TYPE.GET_GRIEVANCE_CONFIGURATION):
+ return {
+ ...state,
+ fetchingGrievanceConfig: false,
+ fetchedGrievanceConfig: true,
+ errorGrievanceConfig: null,
+ grievanceConfig: action.payload.data.grievanceConfig,
+ };
+ case ERROR(ACTION_TYPE.GET_GRIEVANCE_CONFIGURATION):
+ return {
+ ...state,
+ fetchingGrievanceConfig: false,
+ fetchedGrievanceConfig: false,
+ errorGrievanceConfig: formatGraphQLError(action.payload),
+ grievanceConfig: null,
+ };
+ case 'TICKET_MUTATION_REQ':
+ return dispatchMutationReq(state, action);
+ case 'TICKET_MUTATION_ERR':
+ return dispatchMutationErr(state, action);
+ case 'TICKET_CREATE_TICKET_RESP':
+ return dispatchMutationResp(state, 'createTicket', action);
+ case 'TICKET_UPDATE_TICKET_RESP':
+ return dispatchMutationResp(state, 'updateTicket', action);
+ case 'TICKET_DELETE_TICKET_RESP':
+ return dispatchMutationResp(state, 'deleteTicket', action);
+ case 'TICKET_ATTACHMENT_MUTATION_REQ':
+ return dispatchMutationReq(state, action);
+ case 'TICKET_ATTACHMENT_MUTATION_ERR':
+ return dispatchMutationErr(state, action);
+ case 'TICKET_CREATE_TICKET_ATTACHMENT_RESP':
+ return dispatchMutationResp(state, 'createTicketAttachment', action);
+ default:
+ return state;
+ }
}
export default reducer;
diff --git a/src/translations/en.json b/src/translations/en.json
index 09bf396..8704db4 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -72,5 +72,7 @@
"ticket.ticketCode":"Code",
"ticket.ticketPriority":"Priority",
"ticket.ticketStatus":"Status",
- "ticket.ticketGrievanct" : "Grievant"
+ "ticket.ticketGrievanct" : "Grievant",
+ "grievanceSocialProtection.dialogs.GrievanceConfigurationDialog.dialogHeader": "Please fill the config.",
+ "grievanceSocialProtection.dialogs.GrievanceConfigurationDialog.dialogBody": "Go to django admin panel and set up missing values: {configString}"
}
\ No newline at end of file
diff --git a/src/utils/action-type.js b/src/utils/action-type.js
new file mode 100644
index 0000000..788e71a
--- /dev/null
+++ b/src/utils/action-type.js
@@ -0,0 +1,5 @@
+export const REQUEST = (actionTypeName) => `${actionTypeName}_REQ`;
+export const SUCCESS = (actionTypeName) => `${actionTypeName}_RESP`;
+export const ERROR = (actionTypeName) => `${actionTypeName}_ERR`;
+export const CLEAR = (actionTypeName) => `${actionTypeName}_CLEAR`;
+export const VALID = (actionTypeName) => `${actionTypeName}_VALID`;