added crm driven form via oauth

This commit is contained in:
robert.bond@test.gov.wales
2021-09-07 12:46:59 +01:00
parent 9e13a9e7c8
commit 8e8797418a
12 changed files with 245 additions and 149 deletions
+109 -27
View File
@@ -13,6 +13,10 @@ if (process.browser) {
BASE_URL = process.env.API_ROOT || `http://localhost:${port}`;
}
const WEBAPI_URL = "https://devcrm2016.llcdt.gov.wales/DVPINS";
const API_PATH = "/api/data/v8.2/";
const agent = new https.Agent({
rejectUnauthorized: false,
});
@@ -24,11 +28,8 @@ const crmHeaders = {
"OData-Version": "4.0",
"Accept": "application/json",
"Prefer": 'odata.include-annotations="*"',
agent,
},
auth: {
username: "xm\bondr",
password: "!Sky9fish1972",
"Authorization":
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlVXelVaa0U3OEx0NVBGRkJ0LV9seVdoMjdjTSIsImtpZCI6IlVXelVaa0U3OEx0NVBGRkJ0LV9seVdoMjdjTSJ9.eyJhdWQiOiJodHRwczovL2RldmNybTIwMTYubGxjZHQuZ292LndhbGVzLyIsImlzcyI6Imh0dHA6Ly9mcy50ZXN0Lmdvdi53YWxlcy9hZGZzL3NlcnZpY2VzL3RydXN0IiwiaWF0IjoxNjMxMDAwMjUxLCJuYmYiOjE2MzEwMDAyNTEsImV4cCI6MTYzMTAyOTA1MSwidXBuIjpbIlJvYmVydC5Cb25kQHRlc3QuZ292LndhbGVzIiwicm9iZXJ0LmJvbmRAdGVzdC5nb3Yud2FsZXMiXSwicHJpbWFyeXNpZCI6IlMtMS01LTIxLTE4MDA4NDIwNzYtMjQ1NTYwNjU5LTQyMTU3NzU0NjktMTY2MjgiLCJ1bmlxdWVfbmFtZSI6IlhNXFxCb25kUiIsImFwcHR5cGUiOiJQdWJsaWMiLCJhcHBpZCI6IjQyN2ZhNzljLWI1ZmMtNDJhZC04M2Q0LTQxMGIwMzk0OGFiNiIsImF1dGhtZXRob2QiOiJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvYXV0aGVudGljYXRpb25tZXRob2Qvd2luZG93cyIsImF1dGhfdGltZSI6IjIwMjEtMDktMDdUMDc6Mzc6MjIuMzM3WiIsInZlciI6IjEuMCJ9.L8husDSMXMtZxpxKDS0cpPplG6xoHQjSdd17qMfgKZaEUPUOKPy4rznxNwAMp7WxussNeK__nOKE9vHNgc5Nk4lzxbvcYy3jeE7bLWHsB5UYFa1FIrPZpzuEdPIgoWAzhTa4k-anzsA0YNMHpV6QHT14F9wkBTsT8MUtpT2BiNfbflQQ_xtQavp_pCww-1-guysM6USv5NJkuvrHpXjA5_HpaGbprLI8Or3Htjsdgq9c4uCxfjoAGZsjUmtvaIL-jQnkR6-ndYezo12tes7ql2iV4iZT4-fvcib8sUdzHkgFvNmyzMblhogUo8QciTBcvF7-syCfNzLG2vvWSZJ9_g",
},
};
@@ -39,9 +40,17 @@ export const getBasicSearch = (searchString) => {
axios
//.get("https://devcrm2016.llcdt.gov.wales/DVPINS/api/data/v8.2/incidents?$select=_accountid_value,_customerid_value,pinswg_appealcasetype,statuscode,ticketnumber,title&$filter=contains(title, '" + searchString + "')&$count=true", crmHeaders)
//.get("https://jsonplaceholder.typicode.com/todos/1",{proxy:{protocol: 'http',host:'lon3.sme.zscloud.net',port: 80}})
.get(BASE_URL + "/api/searchresults2", {
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
})
// .get(BASE_URL + "/api/searchresults2", {
// httpsAgent: new https.Agent({ rejectUnauthorized: false }),
// })
.get(
WEBAPI_URL +
API_PATH +
"incidents?$select=_accountid_value,_customerid_value,pinswg_appealcasetype,statuscode,ticketnumber,title&$filter=contains(title, '" +
searchString +
"')&$count=true",
crmHeaders
)
.then((res) => res.data)
.catch((error) => {
console.log("thiserror", error);
@@ -49,6 +58,24 @@ export const getBasicSearch = (searchString) => {
);
};
export const getBasicSearchDetails = (appealType, caseReference) => {
return axios
.get(
WEBAPI_URL +
API_PATH +
"/pinswg_ " +
appealType +
"?$filter=pinswg_name eq '" +
caseReference +
"'&$count=true",
crmHeaders
)
.then((res) => res.data)
.catch((error) => {
console.log("thiserror", error);
});
};
export const getFormData = (whichForm) => {
console.log("got to axios", whichForm);
console.log("api_root: ", BASE_URL);
@@ -62,9 +89,18 @@ export const getFormData = (whichForm) => {
//.get("api/appealforms/pinswg_harbourrevisionorder", {
//.get("api/appealforms/pinswg_planningappeals78", {
//.get(api/appealforms/pinswg_householderappealhas", {
.get(BASE_URL + "/api/appealforms/pinswg_" + whichForm, {
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
})
// .get(BASE_URL + "/api/appealforms/pinswg_" + whichForm, {
// httpsAgent: new https.Agent({ rejectUnauthorized: false }),
// })
.get(
WEBAPI_URL +
API_PATH +
"systemforms?$select=formid,name,formxml,type,objecttypecode&$filter=(objecttypecode%20eq%20%27pinswg_" +
whichForm +
"%27and%20type%20eq%202)&$count=true",
crmHeaders
)
.then((res) => res.data)
.catch((error) => {
console.log("thiserror", error);
@@ -72,19 +108,59 @@ export const getFormData = (whichForm) => {
);
};
export const getAppealsTypes = () => {
console.log("got to axios: appeal types");
console.log("api_root: ", BASE_URL);
export const getMandatoryFields = (whichForm) => {
return axios
.get(BASE_URL + "/api/lookups/pinswg_appealcasetype", {
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
})
.get(
WEBAPI_URL +
API_PATH +
"EntityDefinitions(LogicalName='pinswg_" +
whichForm +
"')/Attributes?$count=true&$select=LogicalName,RequiredLevel",
crmHeaders
)
.then((res) => res.data)
.catch((error) => {
console.log("thiserror", error);
});
};
export const getPickLists = (whichForm) => {
return axios
.get(
WEBAPI_URL +
API_PATH +
"EntityDefinitions(LogicalName='pinswg_" +
whichForm +
"')/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet,GlobalOptionSet&$count=true",
crmHeaders
)
.then((res) => res.data)
.catch((error) => {
console.log("thiserror", error);
});
};
export const getAppealsTypes = () => {
console.log("got to axios: appeal types");
console.log("api_root: ", BASE_URL);
return (
axios
// .get(BASE_URL + "/api/lookups/pinswg_appealcasetype", {
// httpsAgent: new https.Agent({ rejectUnauthorized: false }),
// })
.get(
WEBAPI_URL +
API_PATH +
"stringmaps?$filter=attributename%20eq%20%27pinswg_appealcasetype%27&$count=true&$select=value,stringmapid,organizationid,attributevalue",
crmHeaders
)
.then((res) => res.data)
.catch((error) => {
console.log("thiserror", error);
})
);
};
export const getBasicSearch2 = (searchString) => {
var req = new XMLHttpRequest();
req.open(
@@ -189,17 +265,23 @@ export const getAppealTypeDetail = (caseReference, appealcasetype) => {
export const getLPA = () => {
console.log("api_root: ", BASE_URL);
return axios
return (
axios
.get(
BASE_URL + "/api/lookups/pinswg_lpa",
//.get("https://devcrm2016.llcdt.gov.wales/DVPINS/api/data/v8.2/accounts?$select=name",
{ httpsAgent: new https.Agent({ rejectUnauthorized: false }) }
)
.then((res) => res.data)
.catch((error) => {
console.log("thi serror", error);
});
// .get(
// BASE_URL + "/api/lookups/pinswg_lpa",
// //.get("https://devcrm2016.llcdt.gov.wales/DVPINS/api/data/v8.2/accounts?$select=name",
// { httpsAgent: new https.Agent({ rejectUnauthorized: false }) }
// )
.get(
WEBAPI_URL + API_PATH + "accounts?$count=true&$select=name",
crmHeaders
)
.then((res) => res.data)
.catch((error) => {
console.log("thi serror", error);
})
);
};
export const getPersonalAccount = () => {
+9 -26
View File
@@ -5,6 +5,7 @@ import DatePicker from "react-datepicker";
import React, { useState } from "react";
import "react-datepicker/dist/react-datepicker.css";
import moment from "moment";
import jsonpath from "jsonpath";
const RenderTextfield = ({
id,
@@ -356,35 +357,17 @@ export function YesNofield(props) {
const RenderPickList = ({
datafieldname,
picklistData,
name,
label,
input,
meta: { touched, errorStr },
}) => {
const fetcher = (url) => fetch(url).then((res) => res.json());
const { data, error } = useSWR("/api/lookups/" + datafieldname, fetcher);
if (error)
return (
<div className="govuk-form-group">
<label className="govuk-label govuk-body-m" htmlFor={name}>
{label}
</label>
<select className="govuk-select" id={name} name={name}>
<option value="">empty</option>
</select>
</div>
);
if (!data)
return (
<div>
<div className="govuk-form-group">{label} loading...</div>
</div>
);
//console.log(JSON.stringify(data.GlobalOptionSet.Options));
const dropdownObj = data.GlobalOptionSet.Options;
var dropdownObj = jsonpath.query(
picklistData,
"$..value[?(@.LogicalName=='" + datafieldname + "')]..Options"
);
dropdownObj = dropdownObj[0];
return (
<div>
<select {...input} className="govuk-select " id={name} name={name}>
@@ -394,9 +377,8 @@ const RenderPickList = ({
<option
key={key}
value={
dropdownObj[key].Label.LocalizedLabels[0].value
dropdownObj[key].Label.LocalizedLabels[0].Label
}
// value={dropdownObj[key].Label.LocalizedLabels[0].MetadataId}
>
{dropdownObj[key].Label.LocalizedLabels[0].Label}
</option>
@@ -421,6 +403,7 @@ export function PickList(props) {
name={props.name}
component={RenderPickList}
datafieldname={datafieldname}
picklistData={props.picklistData}
/>
</div>
);
+40 -36
View File
@@ -56,44 +56,48 @@ let BuildCheckRow = (props) => {
rowXML[key].outerHTML,
"text/xml"
);
var rows = xpath.select("//label/@description", doc);
var fieldtype = xpath.select("//@classid", doc);
var datafieldname = xpath.select("//@datafieldname", doc);
if (_.isEmpty(rowXML[key].innerHTML)) {
("");
} else {
var rows = xpath.select("//label/@description", doc);
var fieldtype = xpath.select("//@classid", doc);
var datafieldname = xpath.select("//@datafieldname", doc);
return (
<div className="govuk-summary-list__row" key={key}>
<dt className="govuk-summary-list__key">
{rows[0].value}
</dt>
<dd className="govuk-summary-list__value">
{fieldtype[0].value ==
"{5B773807-9FB2-42db-97C3-7A91EFF8ADFF}"
? formatDate(
props.props.form["appealForm"].values[
return (
<div className="govuk-summary-list__row" key={key}>
<dt className="govuk-summary-list__key">
{rows[0].value}
</dt>
<dd className="govuk-summary-list__value">
{fieldtype[0].value ==
"{5B773807-9FB2-42db-97C3-7A91EFF8ADFF}"
? formatDate(
props.props.form["appealForm"].values[
datafieldname[0].value
]
)
: props.props.form["appealForm"].values[
datafieldname[0].value
]
)
: props.props.form["appealForm"].values[
datafieldname[0].value
]}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
updateCurrentSection(whichSection);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
name
</span>
</a>
</dd>
</div>
);
]}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
updateCurrentSection(whichSection);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
name
</span>
</a>
</dd>
</div>
);
}
})}
</>
);
+1
View File
@@ -41,6 +41,7 @@ export default function BuildField(props) {
name={props.datafieldname}
label={props.label}
datafieldname={props.datafieldname}
picklistData={props.picklistData}
/>
);
break;
+20 -12
View File
@@ -1,4 +1,5 @@
import Link from "next/link";
import _ from "lodash";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import xpath from "xpath";
@@ -21,18 +22,25 @@ export default function BuildRow(props) {
rowXML[key].outerHTML,
"text/xml"
);
var rows = xpath.select("//label/@description", doc);
var fieldtype = xpath.select("//@classid", doc);
var datafieldname = xpath.select("//@datafieldname", doc);
return (
<BuildField
fieldType={fieldtype[0].value}
label={rows[0].value}
datafieldname={datafieldname[0].value}
key={key}
props={props}
/>
);
if (_.isEmpty(rowXML[key].innerHTML)) {
("");
} else {
var rows = xpath.select("//label/@description", doc);
var fieldtype = xpath.select("//@classid", doc);
var datafieldname = xpath.select("//@datafieldname", doc);
return (
<BuildField
fieldType={fieldtype[0].value}
label={rows[0].value}
datafieldname={datafieldname[0].value}
key={key}
props={props}
picklistData={
props.props.props.formData.pickListData
}
/>
);
}
})}
</div>
);
+13 -32
View File
@@ -33,11 +33,9 @@ let CreateCase = (props) => {
? [{}]
: _.isEmpty(props.appealType.appealTypeOptions)
? [{}]
: _.isEmpty(props.appealType.appealTypeOptions.GlobalOptionSet)
: _.isEmpty(props.appealType.appealTypeOptions.value)
? [{}]
: _.isEmpty(props.appealType.appealTypeOptions.GlobalOptionSet.Options)
? [{}]
: props.appealType.appealTypeOptions.GlobalOptionSet.Options;
: props.appealType.appealTypeOptions.value;
let lpaOptionsObj = _.isEmpty(props)
? [{}]
@@ -158,51 +156,34 @@ let CreateCase = (props) => {
<option
key={key}
value={
_.isEmpty(
optionsObj[key].Label
)
_.isEmpty(optionsObj[key])
? ""
: _.isEmpty(
optionsObj[key]
.Label
.LocalizedLabels
)
? ""
: _.isEmpty(
optionsObj[key]
.Label
.LocalizedLabels[0]
.Label
.value
)
? ""
: optionsObj[
key
].Label.LocalizedLabels[0].Label.replace(
/[\s\-\+\(\)\,]/g,
""
).toLowerCase()
: optionsObj[key].value
.replace(
/[\s\-\+\(\)\,]/g,
""
)
.toLowerCase()
}
>
{_.isEmpty(optionsObj[key])
? ""
: _.isEmpty(
optionsObj[key].Label
)
: _.isEmpty(optionsObj[key])
? ""
: _.isEmpty(
optionsObj[key].Label
.LocalizedLabels
optionsObj[key].value
)
? ""
: _.isEmpty(
optionsObj[key].Label
.LocalizedLabels[0]
.Label
)
? ""
: optionsObj[key].Label
.LocalizedLabels[0]
.Label}
: optionsObj[key].value}
</option>
);
})}
+18 -8
View File
@@ -22,7 +22,13 @@ import {
setCaseReference,
} from "../../store/appealType/action";
import { setForm, getFormObj } from "../../store/formData/action";
import { getFormData, getAppealsTypes, createCase } from "../../actions";
import {
getFormData,
getAppealsTypes,
getMandatoryFields,
createCase,
getPickLists,
} from "../../actions";
import xpath from "xpath";
import { reduxForm, FormName } from "redux-form";
@@ -56,12 +62,9 @@ let Home = (props) => {
var tabs = xpath.select("//form/tabs/tab[*]", doc);
let optionsStr = props.appealType.appealTypeOptions.GlobalOptionSet.Options;
let optionsStr = props.appealType.appealTypeOptions.value;
let selectedObj = jsonpath.query(
optionsStr,
"$..LocalizedLabels[?(@.Label)].Label"
);
let selectedObj = jsonpath.query(optionsStr, "$..value");
//let optionsTitleObj = [];
@@ -154,8 +157,15 @@ export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ query, req, res }) => {
//console.log("the query", query);
const [appealTypeData, formdata] = await Promise.all([
const [
appealTypeData,
mandatoryFieldsData,
pickListData,
formdata,
] = await Promise.all([
await getAppealsTypes(),
await getMandatoryFields(query.appealtypes),
await getPickLists(query.appealtypes),
await getFormData(query.appealtypes),
]);
@@ -166,7 +176,7 @@ export const getServerSideProps = wrapper.getServerSideProps(
xmlStr = xmlStr.replace(/\\"/g, "");
store.dispatch(setAppealTypeID(query.appealtypes));
store.dispatch(setCaseReference(caseReference));
store.dispatch(setForm(xmlStr));
store.dispatch(setForm(xmlStr, mandatoryFieldsData, pickListData));
store.dispatch(setAppealType(appealTypeData));
}
);
+7 -2
View File
@@ -19,7 +19,7 @@ import {
setSearchResults,
getSearchResultsObj,
} from "../store/searchOutput/action";
import { getBasicSearch } from "../actions";
import { getBasicSearch, getBasicSearchDetails } from "../actions";
const Home = (props) => {
const { footerLinks, pages } = props;
@@ -57,8 +57,13 @@ export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ query, req, res }) => {
console.log("query-", query);
const searchResultsObj = (await getBasicSearch(query.q)) || null;
const [searchResultsObj, searchDetailsObj] = await Promise.all(
await getBasicSearch(query.q),
await getBasicSearchDetails(query.d)
);
store.dispatch(setSearchResults(searchResultsObj));
store.dispatch(setSearchDetails(searchDetailsObj));
store.dispatch(setSearch(query.q));
}
);
+9 -6
View File
@@ -10,9 +10,12 @@ export const getFormObj = () => (dispatch) => {
});
};
export const setForm = (formData) => (dispatch) => {
return dispatch({
type: formDataActionTypes.SETFORMDATA,
formData: formData,
});
};
export const setForm =
(formData, mandatoryFieldsData, pickListData) => (dispatch) => {
return dispatch({
type: formDataActionTypes.SETFORMDATA,
formData: formData,
mandatoryFieldsData: mandatoryFieldsData,
pickListData: pickListData,
});
};
+4
View File
@@ -2,6 +2,8 @@ import { formDataActionTypes } from "./action";
const formDataInitialState = {
formData: {},
mandatoryFieldsData: {},
pickListData: {},
};
export default function reducer(state = formDataInitialState, action) {
@@ -9,6 +11,8 @@ export default function reducer(state = formDataInitialState, action) {
case formDataActionTypes.SETFORMDATA:
return {
formData: action.formData,
mandatoryFieldsData: action.mandatoryFieldsData,
pickListData: action.pickListData,
};
default:
return state;
+8
View File
@@ -2,6 +2,7 @@ export const searchResultsActionTypes = {
GETSEARCHRESULTS: "GETSEARCHRESULTS",
SETSEARCHRESULTS: "SETSEARCHRESULTS",
UPDATESEARCHRESULTS: "UPDATESEARCHRESULTS",
SETSEARCHDETAILS: "SETSEARCHDETAILS",
};
export const getSearchResultshObj = () => (dispatch) => {
@@ -16,3 +17,10 @@ export const setSearchResults = (searchResults) => (dispatch) => {
searchResultsObj: searchResults,
});
};
export const setSearchDetails = (searchDetails) => (dispatch) => {
return dispatch({
type: searchResultsActionTypes.SETSEARCHDETAILS,
searchDetailsObj: searchDetails,
});
};
+7
View File
@@ -2,14 +2,21 @@ import { searchResultsActionTypes } from "./action";
const searchResultsInitialState = {
searchResultsObj: {},
searchDetailsObj: {},
};
export default function reducer(state = searchResultsInitialState, action) {
switch (action.type) {
case searchResultsActionTypes.SETSEARCHRESULTS:
return {
...state,
searchResultsObj: action.searchResultsObj,
};
case searchResultsActionTypes.SETSEARCHDETAILS:
return {
...state,
searchDetailsObj: action.searchDetailsObj,
};
default:
return state;
}