From 7f07d1879a2ed56c21d7418345172f3c4b2bf46b Mon Sep 17 00:00:00 2001 From: jrmartin Date: Wed, 7 May 2025 07:33:28 -0700 Subject: [PATCH 1/8] #92 - Connect add term to dialog --- src/api/endpoints/index.ts | 43 ++++++------- .../Dashboard/EditBulkTerms/TermsTable.jsx | 2 +- .../OverView/CustomizedTable.jsx | 2 +- .../SingleTermView/OverView/OverView.jsx | 2 +- .../OverView/PredicateGroupInput.jsx | 2 +- .../SingleTermView/RequestMergeChanges.jsx | 2 +- .../TermEditor/AddNewTermDialogContent.jsx | 64 ++++++------------- .../TermEditor/ExistingIdsSearch.tsx | 3 +- vite.config.js | 2 +- 9 files changed, 47 insertions(+), 75 deletions(-) diff --git a/src/api/endpoints/index.ts b/src/api/endpoints/index.ts index cba7a7d1..c3c407f5 100644 --- a/src/api/endpoints/index.ts +++ b/src/api/endpoints/index.ts @@ -126,11 +126,11 @@ export const getCuries = async (term) => { }); } -export const getMatchTerms = async (term, filters = {}) => { +export const getMatchTerms = async (group, term, filters = {}) => { const { getEndpointsIlx } = useApi(); /** Call Endpoint */ - return getEndpointsIlx(BASE_GROUP,term, BASE_EXTENSION).then((data) => { + return getEndpointsIlx(group,term, BASE_EXTENSION).then((data) => { return termParser(data, term); }) .catch((error) => { @@ -229,23 +229,23 @@ export const patchTerm = async (group, termID, term) => { }); } -export const addTerm = async (group, term) => { +export const addTerm = async (user: string, token: string, term: { label: string; synonyms: string[] }) => { const { postPrivEntityNew } = useApi(); - /** Call Endpoint */ - return postPrivEntityNew(group, term).then((data) => { - let termParsed = getTerm(data.data); - let response = { - status : data.status, - term : termParsed - } + const headers = { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json', + }; + + const body = { + 'rdf-type': 'owl:Class', + label: term.label, + exact: term.synonyms, + }; + + return await postPrivEntityNew(user, body, { headers }); +}; - return response; - }) - .catch((error) => { - return error; - }); -} export const bulkEditTerms = async (group, payload) => { const { bulkEditTerms } = useMockApi(); @@ -289,14 +289,11 @@ export const getUser = async (id) => { }); } -export const getExistingIDs = async () => { - const { getMatchTerms } = useMockApi(); - +export const getExistingIDs = async (searchTerm) => { /** Call Endpoint */ - return getMatchTerms("base", "*").then((data) => { - const terms = termParser(data, undefined); - let existingIds = terms?.results?.map( term => term.id?.split("/").pop() ); - return terms?.results?.[0]?.id != undefined ? existingIds : []; + return elasticSearch(searchTerm).then((data) => { + const terms = data?.results; + return terms != undefined ? terms : []; }) .catch((error) => { return error; diff --git a/src/components/Dashboard/EditBulkTerms/TermsTable.jsx b/src/components/Dashboard/EditBulkTerms/TermsTable.jsx index 13e6cfe3..5071f919 100644 --- a/src/components/Dashboard/EditBulkTerms/TermsTable.jsx +++ b/src/components/Dashboard/EditBulkTerms/TermsTable.jsx @@ -89,7 +89,7 @@ const TermsTable = ({ setOpenEditAttributes, setAttributes, attributes, searchCo React.useEffect(() => { setLoading(true) - getMatchTerms("i", { filters }).then(data => { + getMatchTerms("base", "i", { filters }).then(data => { setTerms(data.results); setLoading(false); }).catch(err => { diff --git a/src/components/SingleTermView/OverView/CustomizedTable.jsx b/src/components/SingleTermView/OverView/CustomizedTable.jsx index 0a56004b..f01628ed 100644 --- a/src/components/SingleTermView/OverView/CustomizedTable.jsx +++ b/src/components/SingleTermView/OverView/CustomizedTable.jsx @@ -245,7 +245,7 @@ const CustomizedTable = ({ data, term, isAddButtonVisible }) => { // eslint-disable-next-line react-hooks/exhaustive-deps const fetchTerms = useCallback(debounce(async (searchTerm) => { - const data = await getMatchTerms(searchTerm); + const data = await getMatchTerms("base", searchTerm); setTerms(data?.results[0]); }, 500), [getMatchTerms]); diff --git a/src/components/SingleTermView/OverView/OverView.jsx b/src/components/SingleTermView/OverView/OverView.jsx index ee1397ec..3707c58c 100644 --- a/src/components/SingleTermView/OverView/OverView.jsx +++ b/src/components/SingleTermView/OverView/OverView.jsx @@ -23,7 +23,7 @@ const OverView = ({ isCodeViewVisible, selectedDataFormat }) => { const fetchTerms = useCallback( debounce((searchTerm) => { if (searchTerm) { - getMatchTerms(searchTerm).then(data => { + getMatchTerms("base", searchTerm).then(data => { setData(data?.results[0]); setLoading(false); }); diff --git a/src/components/SingleTermView/OverView/PredicateGroupInput.jsx b/src/components/SingleTermView/OverView/PredicateGroupInput.jsx index 0e2caa49..d18cc5b2 100644 --- a/src/components/SingleTermView/OverView/PredicateGroupInput.jsx +++ b/src/components/SingleTermView/OverView/PredicateGroupInput.jsx @@ -39,7 +39,7 @@ const PredicateGroupInput = ({ predicate, onChange }) => { // eslint-disable-next-line react-hooks/exhaustive-deps const fetchTerms = useCallback(debounce(async (searchTerm) => { - const data = await getMatchTerms(searchTerm); + const data = await getMatchTerms("base", searchTerm); setTerms(data?.results); }, 500), [getMatchTerms]); diff --git a/src/components/SingleTermView/RequestMergeChanges.jsx b/src/components/SingleTermView/RequestMergeChanges.jsx index d892a891..679ff7c8 100644 --- a/src/components/SingleTermView/RequestMergeChanges.jsx +++ b/src/components/SingleTermView/RequestMergeChanges.jsx @@ -38,7 +38,7 @@ const RequestMergeChanges = ({ searchTerm, open, handleClose }) => { const fetchTerms = useCallback( debounce((searchTerm) => { if (searchTerm) { - getMatchTerms(searchTerm).then(data => { + getMatchTerms("base", searchTerm).then(data => { setData(data?.results[0]); setLoading(false); }); diff --git a/src/components/TermEditor/AddNewTermDialogContent.jsx b/src/components/TermEditor/AddNewTermDialogContent.jsx index 7c11140e..ba36eb47 100644 --- a/src/components/TermEditor/AddNewTermDialogContent.jsx +++ b/src/components/TermEditor/AddNewTermDialogContent.jsx @@ -14,15 +14,13 @@ import { termParser } from "../../../src/parsers/termParser"; import AddOutlinedIcon from "@mui/icons-material/AddOutlined"; import { getExistingIDs, getUser } from "../../api/endpoints"; import { useState, useEffect, useMemo, useCallback } from "react"; -import * as mockApi from "../../api/endpoints/swaggerMockMissingEndpoints"; -import * as mockApiInterlex from "../../api/endpoints/interLexURIStructureAPI"; +import { getEndpointsIlx, elasticSearch } from './../../api/endpoints/index'; +import { GlobalDataContext } from "../../contexts/DataContext"; +import { useContext } from "react"; import { vars } from "../../theme/variables"; const { gray800, gray700 } = vars; -const useMockApi = () => mockApi; -const useMockApiInterlex = () => mockApiInterlex; - const initialFormState = { label: "", synonyms: [], @@ -49,8 +47,6 @@ const formatIdText = (termId) => { const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChange, onReset }) => { - const { getMatchTerms } = useMockApi(); - const { getEndpointsIlx } = useMockApiInterlex(); const [loading, setLoading] = useState(true); const navigate = useNavigate(); const [termResults, setTermResults] = useState([]); @@ -65,6 +61,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const [url, setUrl] = useState(''); const [formState, setFormState] = useState(initialFormState); const [newTermId, setNewTermId] = useState(""); + const { user, setUserData } = useContext(GlobalDataContext); const memoData = useMemo(() => data, [data]); @@ -74,30 +71,29 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang setLoading(true); if (termValue) { getEndpointsIlx("base", termValue).then(data => { + setLoading(false); const parsedData = termParser(data); setData(parsedData?.results[0]); - setLoading(false); }); } else { - getMatchTerms("base", "i", { filter: "", value: "" }).then(data => { - const parsedData = termParser(data, ""); - setTermResults(parsedData.results); + elasticSearch("a").then(data => { + setTermResults(data.results); setLoading(false); }); } }, 300), - [getEndpointsIlx, getMatchTerms] + [getEndpointsIlx, elasticSearch] ); const addTermRequest = useCallback(async (group, term) => { - await addTerm("base", term).then((response) => { - console.log("Term added ", response) + const token = localStorage.getItem("token") + const groupName = user?.name || group + await addTerm(groupName, token, term).then((response) => { setNewTermId(response.term.id.split("/").pop()) }) .catch((error) => { console.log("Error ", error) }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [addTerm]); const handleChangeTabs = (_, newValue) => setTabValue(newValue); @@ -151,11 +147,11 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang } useEffect(() => { - getMatchTerms("base", "i", { filter: "", value: "" }).then(data => { - const parsedData = termParser(data, termValue); - setTermResults(parsedData.results); + elasticSearch(termValue).then(data => { + setTermResults(data.results); + setLoading(false); }); - }, [termValue, getMatchTerms]); + }, [termValue, elasticSearch]); useEffect(() => { fetchTerms(termValue); @@ -171,14 +167,14 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang }, [memoData]); // eslint-disable-next-line react-hooks/exhaustive-deps - const getIds = useCallback(debounce(async () => { - const ids = await getExistingIDs(); + const getIds = useCallback(debounce(async (termValue) => { + const ids = await getExistingIDs(termValue || "a"); setIds(ids) }), [getUser]); useEffect(() => { - getIds(); - }, [getIds]); + getIds(termValue); + }, [termValue,getIds]); useEffect(() => { if (activeStep === 2) { @@ -186,28 +182,6 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang } }, [addTermRequest, formState, activeStep]); - //can be deleted, use only for testing purposes - useEffect(() => { - const fetchData = async () => { - try { - const response = await fetch('/api/some-endpoint'); - if (!response.ok) { - throw new Error('HTTP error'); - } - const data = await response.json(); - setResponseStatus({ success: true, data }); - } catch (error) { - // should be success: false, but true for now so we can wee success status message - setResponseStatus({ success: true, error: error.message }); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, []); - - const predicatesOptions = predicates.map(row => ({ label: row.title, value: row.title diff --git a/src/components/TermEditor/ExistingIdsSearch.tsx b/src/components/TermEditor/ExistingIdsSearch.tsx index 0543ffd6..5504f802 100644 --- a/src/components/TermEditor/ExistingIdsSearch.tsx +++ b/src/components/TermEditor/ExistingIdsSearch.tsx @@ -19,7 +19,8 @@ const ExistingIdsSearch = ({ options, value, onChange, label, placeholder }) => <> {label} Date: Wed, 7 May 2025 08:19:23 -0700 Subject: [PATCH 2/8] #92 - fix lint --- .../TermEditor/AddNewTermDialogContent.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/TermEditor/AddNewTermDialogContent.jsx b/src/components/TermEditor/AddNewTermDialogContent.jsx index ba36eb47..fc619219 100644 --- a/src/components/TermEditor/AddNewTermDialogContent.jsx +++ b/src/components/TermEditor/AddNewTermDialogContent.jsx @@ -53,7 +53,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const [tabValue, setTabValue] = useState(0); const [openSidebar, setOpenSidebar] = useState(true); const [data, setData] = useState(null); - const [responseStatus, setResponseStatus] = useState(null) + const [responseStatus] = useState(null) const [termValue, setTermValue] = useState(''); const [ids, setIds] = useState([]); const [predicates, setPredicates] = useState([{ subject: '', predicate: '', object: { type: 'Object', value: '', isLink: false } }]); @@ -61,7 +61,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const [url, setUrl] = useState(''); const [formState, setFormState] = useState(initialFormState); const [newTermId, setNewTermId] = useState(""); - const { user, setUserData } = useContext(GlobalDataContext); + const { user } = useContext(GlobalDataContext); const memoData = useMemo(() => data, [data]); @@ -86,7 +86,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang ); const addTermRequest = useCallback(async (group, term) => { - const token = localStorage.getItem("token") + const token = localStorage.getItem("appToken") const groupName = user?.name || group await addTerm(groupName, token, term).then((response) => { setNewTermId(response.term.id.split("/").pop()) @@ -94,7 +94,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang .catch((error) => { console.log("Error ", error) }); - }, [addTerm]); + }, [user]); const handleChangeTabs = (_, newValue) => setTabValue(newValue); const handleSidebarToggle = () => setOpenSidebar(!openSidebar); @@ -151,7 +151,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang setTermResults(data.results); setLoading(false); }); - }, [termValue, elasticSearch]); + }, [termValue]); useEffect(() => { fetchTerms(termValue); @@ -224,7 +224,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang {activeStep === 2 && console.log("Try again")} + onTryAgain={handleAddNewTerm} onClose={handleGoToTermClick} actionButtonStartIcon={} additionalInfo={formattedNewTermId} From 4e1d92bd4c5adfd39ff6184d5daea6af982a2ba0 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 20 May 2025 14:14:44 -0700 Subject: [PATCH 3/8] #92 - update to add new term, missing confirmation POST works --- src/App.jsx | 2 +- src/api/endpoints/interLexURIStructureAPI.ts | 23 +++++++++++-------- src/components/Auth/Login.jsx | 1 + .../TermEditor/AddNewTermDialogContent.jsx | 10 ++++---- src/components/TermEditor/NewTermSidebar.jsx | 4 ++-- src/main.jsx | 2 -- vite.config.js | 4 ++-- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index fd91dbec..4f95d728 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -44,7 +44,7 @@ function MainContent() { const { user, setUserData } = useContext(GlobalDataContext); // check if cookie is expired - if (!user) { + if (!user && user != null) { const sessionCookie = cookies.session; const expires = new Date(cookiesInfo?.expires); const today = new Date(); diff --git a/src/api/endpoints/interLexURIStructureAPI.ts b/src/api/endpoints/interLexURIStructureAPI.ts index 8c28cda5..c5ecb57b 100644 --- a/src/api/endpoints/interLexURIStructureAPI.ts +++ b/src/api/endpoints/interLexURIStructureAPI.ts @@ -7565,16 +7565,21 @@ after the label and exact synonyms are done an no matches confirmed the user sho * @summary The workflow we want for this is a bit more complex than a simple form */ export const postPrivEntityNew = ( - group: string, - options?: SecondParameter,) => { - - - return customInstance( - {url: `https://uri.olympiangods.org/${group}/priv/entity-new`, method: 'POST' + group: string, + data: any, + options?: SecondParameter & { headers?: Record } +) => { + return customInstance( + { + url: `https://uri.olympiangods.org/${group}/priv/entity-new`, + method: 'POST', + data, + headers: options?.headers, }, - options); - } - + options + ); +}; + export const getPostPrivEntityNewMutationOptions = , diff --git a/src/components/Auth/Login.jsx b/src/components/Auth/Login.jsx index ddf73e65..d212ece5 100644 --- a/src/components/Auth/Login.jsx +++ b/src/components/Auth/Login.jsx @@ -74,6 +74,7 @@ const Login = () => { value: sessionCookie.value, expires: expires })); + localStorage.setItem("token", sessionCookie.value) setUserData({ name: userData['groupname'], id: userData['orcid'], diff --git a/src/components/TermEditor/AddNewTermDialogContent.jsx b/src/components/TermEditor/AddNewTermDialogContent.jsx index fc619219..7f05f72d 100644 --- a/src/components/TermEditor/AddNewTermDialogContent.jsx +++ b/src/components/TermEditor/AddNewTermDialogContent.jsx @@ -77,7 +77,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang }); } else { elasticSearch("a").then(data => { - setTermResults(data.results); + setTermResults(data.results?.results); setLoading(false); }); } @@ -86,8 +86,8 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang ); const addTermRequest = useCallback(async (group, term) => { - const token = localStorage.getItem("appToken") - const groupName = user?.name || group + const token = localStorage.getItem("token") + const groupName = user?.groupname || group await addTerm(groupName, token, term).then((response) => { setNewTermId(response.term.id.split("/").pop()) }) @@ -147,8 +147,8 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang } useEffect(() => { - elasticSearch(termValue).then(data => { - setTermResults(data.results); + elasticSearch(termValue, 20, 0).then(data => { + setTermResults(data.results?.results); setLoading(false); }); }, [termValue]); diff --git a/src/components/TermEditor/NewTermSidebar.jsx b/src/components/TermEditor/NewTermSidebar.jsx index 2067f866..6deb79ef 100644 --- a/src/components/TermEditor/NewTermSidebar.jsx +++ b/src/components/TermEditor/NewTermSidebar.jsx @@ -47,7 +47,7 @@ export default function NewTermSidebar({ open, loading, onToggle, results, isRes )} - {open && ( + {(open && results )&& ( {isResultsEmpty ? ( @@ -60,7 +60,7 @@ export default function NewTermSidebar({ open, loading, onToggle, results, isRes ) : ( - <>{results.map((result) => ( + <>{results?.map((result) => ( diff --git a/vite.config.js b/vite.config.js index c0a3c98a..795c1184 100644 --- a/vite.config.js +++ b/vite.config.js @@ -38,7 +38,7 @@ export default defineConfig({ }); }, }, - '^/priv/.*': { + '^/([^/]+)/priv/(.*)': { target: "https://uri.olympiangods.org", secure: false, changeOrigin: true, @@ -59,7 +59,7 @@ export default defineConfig({ console.log('Received Response from the Target:', proxyRes.statusCode, req.url); }); }, - }, + } }, }, }); From a32312018bc370c178c13924e69f33b3ade05d0b Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 23 May 2025 14:41:00 -0700 Subject: [PATCH 4/8] #92 - integrate post term into olympian gods redirects --- mock/mutator/customClient.ts | 43 ++++++++++----- src/api/endpoints/apiActions.ts | 53 +++++++++++++------ src/api/endpoints/apiService.ts | 5 ++ .../TermEditor/AddNewTermDialogContent.jsx | 51 +++++++++--------- src/components/TermEditor/termStatusProps.js | 12 +++-- src/components/common/StatusStep.jsx | 24 ++++----- src/config.js | 1 + vite.config.js | 20 +++++-- 8 files changed, 131 insertions(+), 78 deletions(-) diff --git a/mock/mutator/customClient.ts b/mock/mutator/customClient.ts index b09388ab..598b36f6 100644 --- a/mock/mutator/customClient.ts +++ b/mock/mutator/customClient.ts @@ -1,35 +1,50 @@ -import Axios, { AxiosRequestConfig } from 'axios'; +import Axios, { AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'; import { API_CONFIG } from '../../src/config'; -export const AXIOS_INSTANCE = Axios.create({ baseURL: API_CONFIG.BASE_URL }); -// add a second `options` argument here if you want to pass extra options to each generated query +export const AXIOS_INSTANCE = Axios.create({ + baseURL: API_CONFIG.BASE_URL, + withCredentials: true, // ✅ Always send cookies +}); + export const customInstance = ( config: AxiosRequestConfig, options?: AxiosRequestConfig, ): Promise => { const source = Axios.CancelToken.source(); + const promise = AXIOS_INSTANCE({ ...config, ...options, cancelToken: source.token, - }).then(({ data }) => data).catch(error => { - throw error; - }); + withCredentials: true, + validateStatus: (status) => status >= 200 && status < 400, // ✅ Accept 3xx + }) + .then(async (response: AxiosResponse) => { + const isRedirect = response.status === 303; + const redirectUrl = response.headers['x-redirect-location']; + + if (isRedirect && redirectUrl) { + const redirected = await AXIOS_INSTANCE.get(redirectUrl, { + withCredentials: true, + }); + return redirected.data; + } + + return response.data; + }) + .catch((error: AxiosError) => { + throw error; + }); // @ts-ignore promise.cancel = () => { - console.log("query was cancelled") - source.cancel('Query was cancelled'); + console.log("query was cancelled"); + source.cancel("Query was cancelled"); }; return promise; }; -// In some case with react-query and swr you want to be able to override the return error type so you can also do it here like this +// Utility types (unchanged) export type ErrorType = AxiosError; - export type BodyType = BodyData; - -// Or, in case you want to wrap the body type (optional) -// (if the custom instance is processing data before sending it, like changing the case for example) -export type BodyType = CamelCase; diff --git a/src/api/endpoints/apiActions.ts b/src/api/endpoints/apiActions.ts index 302d05dd..5261d153 100644 --- a/src/api/endpoints/apiActions.ts +++ b/src/api/endpoints/apiActions.ts @@ -6,22 +6,45 @@ import { useCookies } from 'react-cookie' type SecondParameter any> = Parameters[1]; -export const createPostRequest = (endpoint: string, contentType = "application/json") => { - return (data?: D, options?: SecondParameter) => { - return customInstance( - { - url: endpoint, - method: "POST", - data: data, - headers: { - "Content-Type": contentType, +export const createPostRequest = ( + endpoint: string, + contentType = "application/json", + cookie?: string +) => { + return async (data?: D, options?: SecondParameter) => { + try { + const response = await customInstance( + { + url: endpoint, + method: "POST", + data: data, + headers: { + "Content-Type": contentType, + ...(cookie ? { "Cookie": cookie } : {}), + }, + withCredentials: true, + validateStatus: (status) => status >= 200 && status < 400 // ✅ Allow 3xx }, - withCredentials: true - }, - options, - ) - } -} + options + ); + + return response; + } catch (error: any) { + const redirectUrl = error?.response?.headers?.['x-redirect-location']; + + if (error?.response?.status === 303 && redirectUrl) { + // ✅ Manually follow the redirect + return await customInstance({ + url: redirectUrl, + method: "GET", + withCredentials: true + }); + } + + throw error; + } + }; +}; export const createGetRequest = (endpoint: string, contentType?: string) => { return (params?: P, options?: SecondParameter, signal?: AbortSignal) => { diff --git a/src/api/endpoints/apiService.ts b/src/api/endpoints/apiService.ts index fd281631..b8fce984 100644 --- a/src/api/endpoints/apiService.ts +++ b/src/api/endpoints/apiService.ts @@ -77,4 +77,9 @@ export const getSelectedTermLabel = async (searchTerm: string): Promise { + const endpoint = `/${group}${API_CONFIG.REAL_API.CREATE_NEW_ENTITY}`; + return createPostRequest(endpoint, "application/x-www-form-urlencoded", `session=${session}`)(data); }; \ No newline at end of file diff --git a/src/components/TermEditor/AddNewTermDialogContent.jsx b/src/components/TermEditor/AddNewTermDialogContent.jsx index 22721a65..fbec3481 100644 --- a/src/components/TermEditor/AddNewTermDialogContent.jsx +++ b/src/components/TermEditor/AddNewTermDialogContent.jsx @@ -3,21 +3,19 @@ import PropTypes from "prop-types"; import { Box } from "@mui/material"; import ImportFileTab from "./ImportFileTab"; import BasicTabs from "../common/CustomTabs"; -import { addTerm } from "../../api/endpoints"; import NewTermSidebar from "./NewTermSidebar"; import StatusStep from "../common/StatusStep"; import { useNavigate } from "react-router-dom"; import ManualImportTab from "./ManualImportTab"; import AddPredicatesStep from "./AddPredicatesStep"; import { getAddTermStatusProps } from "./termStatusProps"; -import { termParser } from "../../../src/parsers/termParser"; import AddOutlinedIcon from "@mui/icons-material/AddOutlined"; import { getExistingIDs, getUser } from "../../api/endpoints"; import { useState, useEffect, useMemo, useCallback } from "react"; import { getEndpointsIlx, elasticSearch } from './../../api/endpoints/index'; import { GlobalDataContext } from "../../contexts/DataContext"; import { useContext } from "react"; -import { API_CONFIG } from '../../config'; +import { createNewEntity } from './../../api/endpoints/apiService' import { vars } from "../../theme/variables"; const { gray800, gray700 } = vars; @@ -53,8 +51,8 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const [termResults, setTermResults] = useState([]); const [tabValue, setTabValue] = useState(0); const [openSidebar, setOpenSidebar] = useState(true); - const [data, setData] = useState(null); - const [responseStatus] = useState(null) + const [data] = useState(null); + const [addTermResponse, setAddTermResponse] = useState(null) const [termValue, setTermValue] = useState(''); const [ids, setIds] = useState([]); const [predicates, setPredicates] = useState([{ subject: '', predicate: '', object: { type: 'Object', value: '', isLink: false } }]); @@ -70,32 +68,31 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const fetchTerms = useCallback( debounce((termValue) => { setLoading(true); - if (termValue) { - getEndpointsIlx("base", termValue).then(data => { - setLoading(false); - const parsedData = termParser(data); - setData(parsedData?.results[0]); - }); - } else { - elasticSearch("a").then(data => { - setTermResults(data.results?.results); - setLoading(false); - }); - } + elasticSearch(termValue).then(data => { + setTermResults(data.results?.results); + setLoading(false); + }); }, 300), [getEndpointsIlx, elasticSearch] ); const addTermRequest = useCallback(async (group, term) => { - const token = localStorage.getItem("token") - const groupName = user?.groupname || group - await addTerm(groupName, API_CONFIG.SCICRUNCH_KEY, token, term).then((response) => { - setNewTermId(response.term.id.split("/").pop()) - }) - .catch((error) => { - console.log("Error ", error) - }); - }, [user]); + const token = localStorage.getItem("token"); + const groupName = user?.groupname || group; + const body = { + 'rdf-type': 'owl:Class', + label: term.label, + exact: term.synonyms, + }; + + try { + const response = await createNewEntity({ group: groupName, data: body, session: token }); + setAddTermResponse(response); + setNewTermId(response.term.id.split("/").pop()); + } catch (error) { + setAddTermResponse(error.response); + } + }, [user]); const handleChangeTabs = (_, newValue) => setTabValue(newValue); const handleSidebarToggle = () => setOpenSidebar(!openSidebar); @@ -195,7 +192,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const formattedNewTermId = formatIdText(newTermId); - const statusProps = getAddTermStatusProps(responseStatus, termValue); + const statusProps = getAddTermStatusProps(addTermResponse, termValue); return ( <> diff --git a/src/components/TermEditor/termStatusProps.js b/src/components/TermEditor/termStatusProps.js index ff9f0f0d..2714fcda 100644 --- a/src/components/TermEditor/termStatusProps.js +++ b/src/components/TermEditor/termStatusProps.js @@ -1,12 +1,14 @@ -export const getAddTermStatusProps = (responseStatus, termValue) => ({ - statusResponse: responseStatus, +export const getAddTermStatusProps = (response, termValue) => ({ + statusResponse: response, + success : response?.status < 400, + error : response?.status > 400 , successMessage: "Term successfully created", failureMessage: "Unable to create the term", successDescription: `Your term “${termValue.charAt(0).toUpperCase() + termValue.slice(1)}” has been added. Go to your term or add a new one.`, failureDescription: `Your term “${termValue.charAt(0).toUpperCase() + termValue.slice(1)}” has can’t be added. Close or try again.`, - actionButtonMessage: responseStatus?.success ? "Add a new term" : null, - isCloseButtonVisible: responseStatus?.success ? false : true, - isTryButtonVisible: responseStatus?.success ? false : true, + actionButtonMessage: response?.success ? "Add a new term" : null, + isCloseButtonVisible: response?.status < 400 ? false : true, + isTryButtonVisible: response?.status < 400 ? false : true, }); export const getTermStatusProps = (responseStatus, termValue) => ({ diff --git a/src/components/common/StatusStep.jsx b/src/components/common/StatusStep.jsx index 4a1ee49f..d12c4063 100644 --- a/src/components/common/StatusStep.jsx +++ b/src/components/common/StatusStep.jsx @@ -5,7 +5,7 @@ import { StatusErrorBackgroundPattern, AddedSuccessfully } from "../../Icons"; import { vars } from "../../theme/variables"; const { gray900, gray600 } = vars; -const StatusBackground = ({ responseStatus }) => ( +const StatusBackground = ({ success }) => ( ( zIndex: 1, }} > - {responseStatus?.success ? : } + {success ? : } ); StatusBackground.propTypes = { - responseStatus: PropTypes.object, + success: PropTypes.bool, }; const StatusMessage = ({ message, description, additionalInfo }) => ( @@ -38,7 +38,7 @@ const StatusMessage = ({ message, description, additionalInfo }) => ( {description} - {additionalInfo} + {typeof additionalInfo === 'string' ? {additionalInfo} : null} ); @@ -80,7 +80,7 @@ ActionButtons.propTypes = { const StatusStep = ({ statusProps, onAction, onTryAgain, onClose, actionButtonStartIcon, additionalInfo }) => { const { - statusResponse, + success, successMessage, successDescription, failureMessage, @@ -90,17 +90,13 @@ const StatusStep = ({ statusProps, onAction, onTryAgain, onClose, actionButtonSt isCloseButtonVisible, } = statusProps; - const message = statusResponse?.success + const message = success ? successMessage - : statusResponse?.error - ? failureMessage - : ''; + : failureMessage - const description = statusResponse?.success + const description = success ? successDescription - : statusResponse?.error - ? failureDescription - : ''; + : failureDescription return ( - + { console.log(_options); proxy.on('error', (err, _req, _res) => { @@ -51,13 +54,24 @@ export default defineConfig({ }); proxy.on('proxyReq', (proxyReq, req, _res) => { console.log('Sending Request to the Target:', req.method, req.url); + console.log('Headers sent to backend:', proxyReq.getHeaders()); console.log('Response:', _res); console.log('Request:', proxyReq); + // Forward cookies manually if needed + if (req.headers.cookie) { + proxyReq.setHeader('cookie', req.headers.cookie); + } }); - proxy.on('proxyRes', (proxyRes, req, _res) => { - console.log('Received response', _res); - console.log('Received Response from the Target:', proxyRes.statusCode, req.url); + proxy.on('proxyRes', (proxyRes, req, res) => { + const location = proxyRes.headers['location']; + console.log('Received location', location); + + if (proxyRes.statusCode === 303 && location) { + res.setHeader('X-Redirect-Location', location); + res.setHeader('Access-Control-Expose-Headers', 'X-Redirect-Location'); + } }); + }, } }, From a360d445cd71d8a2c3bc6fc01c43fc5e3a00db45 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 26 May 2025 07:27:55 -0700 Subject: [PATCH 5/8] #92 - Clean up --- mock/mutator/customClient.ts | 19 +++++++----- src/api/endpoints/apiActions.ts | 54 ++++++++++----------------------- 2 files changed, 28 insertions(+), 45 deletions(-) diff --git a/mock/mutator/customClient.ts b/mock/mutator/customClient.ts index 598b36f6..670788b6 100644 --- a/mock/mutator/customClient.ts +++ b/mock/mutator/customClient.ts @@ -1,14 +1,14 @@ -import Axios, { AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'; +import Axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'; import { API_CONFIG } from '../../src/config'; export const AXIOS_INSTANCE = Axios.create({ baseURL: API_CONFIG.BASE_URL, - withCredentials: true, // ✅ Always send cookies + withCredentials: true, }); export const customInstance = ( config: AxiosRequestConfig, - options?: AxiosRequestConfig, + options?: AxiosRequestConfig ): Promise => { const source = Axios.CancelToken.source(); @@ -17,17 +17,22 @@ export const customInstance = ( ...options, cancelToken: source.token, withCredentials: true, - validateStatus: (status) => status >= 200 && status < 400, // ✅ Accept 3xx + validateStatus: (status) => status >= 200 && status < 400, }) .then(async (response: AxiosResponse) => { const isRedirect = response.status === 303; const redirectUrl = response.headers['x-redirect-location']; if (isRedirect && redirectUrl) { - const redirected = await AXIOS_INSTANCE.get(redirectUrl, { + const followUp = await AXIOS_INSTANCE.get(redirectUrl, { withCredentials: true, + headers: { + Accept: 'text/turtle', + }, + validateStatus: (status) => status === 200, }); - return redirected.data; + + return followUp.data; } return response.data; @@ -45,6 +50,6 @@ export const customInstance = ( return promise; }; -// Utility types (unchanged) +// Error typing helpers export type ErrorType = AxiosError; export type BodyType = BodyData; diff --git a/src/api/endpoints/apiActions.ts b/src/api/endpoints/apiActions.ts index 5261d153..ceb27cf4 100644 --- a/src/api/endpoints/apiActions.ts +++ b/src/api/endpoints/apiActions.ts @@ -6,45 +6,23 @@ import { useCookies } from 'react-cookie' type SecondParameter any> = Parameters[1]; -export const createPostRequest = ( - endpoint: string, - contentType = "application/json", - cookie?: string -) => { - return async (data?: D, options?: SecondParameter) => { - try { - const response = await customInstance( - { - url: endpoint, - method: "POST", - data: data, - headers: { - "Content-Type": contentType, - ...(cookie ? { "Cookie": cookie } : {}), - }, - withCredentials: true, - validateStatus: (status) => status >= 200 && status < 400 // ✅ Allow 3xx +export const createPostRequest = (endpoint: string, contentType = "application/json", cookie : string) => { + return (data?: D, options?: SecondParameter) => { + return customInstance( + { + url: endpoint, + method: "POST", + data: data, + headers: { + "Content-Type": contentType, + ...(cookie ? { "Cookie": cookie } : {}) }, - options - ); - - return response; - } catch (error: any) { - const redirectUrl = error?.response?.headers?.['x-redirect-location']; - - if (error?.response?.status === 303 && redirectUrl) { - // ✅ Manually follow the redirect - return await customInstance({ - url: redirectUrl, - method: "GET", - withCredentials: true - }); - } - - throw error; - } - }; -}; + withCredentials: true + }, + options, + ) + } +} export const createGetRequest = (endpoint: string, contentType?: string) => { return (params?: P, options?: SecondParameter, signal?: AbortSignal) => { From 624a03332a507dd43a8c7d5e3e9d3a8a6e0bc9ae Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 26 May 2025 14:11:02 -0700 Subject: [PATCH 6/8] #92 - Fixes Get Raw Data , redirects all ILX and TMP id retrieval traffic --- src/api/endpoints/apiService.ts | 73 +++++++++++-------- src/api/endpoints/interLexURIStructureAPI.ts | 2 +- .../SingleTermView/OverView/OverView.jsx | 2 +- .../SingleTermView/OverView/RawDataViewer.jsx | 2 +- .../TermEditor/AddNewTermDialogContent.jsx | 7 +- src/components/TermEditor/TermDialog.jsx | 1 + src/main.jsx | 2 + vite.config.js | 6 +- 8 files changed, 56 insertions(+), 39 deletions(-) diff --git a/src/api/endpoints/apiService.ts b/src/api/endpoints/apiService.ts index c1025159..d11682c0 100644 --- a/src/api/endpoints/apiService.ts +++ b/src/api/endpoints/apiService.ts @@ -79,36 +79,49 @@ export const getSelectedTermLabel = async (searchTerm: string): Promise { - const endpoint = `/${group}${API_CONFIG.REAL_API.CREATE_NEW_ENTITY}`; - const response = await createPostRequest( - endpoint, - "application/x-www-form-urlencoded", - `session=${session}` - )(data); - - // If the response is HTML (a string), extract TMP ID - if (typeof response === "string") { - const match = response.match(/TMP:\d{9}/); - if (match) { - return { - term: { - id: `http://uri.interlex.org/base/${match[0]}`, - }, - raw: response, - status: 200, - }; +export const createNewEntity = async ({group,data,session}: { group: string; data: any; session: string }) => { + try { + const endpoint = `/${group}${API_CONFIG.REAL_API.CREATE_NEW_ENTITY}`; + const response = await createPostRequest( + endpoint, + "application/x-www-form-urlencoded", + `session=${session}` + )(data); + + // If the response is HTML (a string), extract TMP ID + if (typeof response === "string") { + const match = response.match(/TMP:\d{9}/); + if (match) { + return { + term: { + id: `${match[0]}`, + }, + raw: response, + status: 200, + }; + } + } + + // Otherwise, return response as-is + return response; + } catch (error) { + if (error?.response.status === 409) { + const match = error?.response?.data?.existing?.[0]; + if (match) { + return { + term: { + id: `${match}`, + }, + raw: error?.response, + status: error?.response?.status, + }; + } } - } - // Otherwise, return response as-is - return response; + return { + raw: error?.response, + status: error?.response?.status, + }; + } + }; \ No newline at end of file diff --git a/src/api/endpoints/interLexURIStructureAPI.ts b/src/api/endpoints/interLexURIStructureAPI.ts index c5ecb57b..61d7feb2 100644 --- a/src/api/endpoints/interLexURIStructureAPI.ts +++ b/src/api/endpoints/interLexURIStructureAPI.ts @@ -9732,7 +9732,7 @@ export const getEndpointsIlx = ( return customInstance( - {url: `https://uri.olympiangods.org/${group}/${fragPrefId}.${extension}`, method: 'GET', signal + {url: `/${group}/${fragPrefId}.${extension}`, method: 'GET', signal }, options); } diff --git a/src/components/SingleTermView/OverView/OverView.jsx b/src/components/SingleTermView/OverView/OverView.jsx index 8f7f516e..28c36d11 100644 --- a/src/components/SingleTermView/OverView/OverView.jsx +++ b/src/components/SingleTermView/OverView/OverView.jsx @@ -43,7 +43,7 @@ const OverView = ({ searchTerm, isCodeViewVisible, selectedDataFormat }) => { - {isCodeViewVisible ? : + {isCodeViewVisible ? : <>
diff --git a/src/components/SingleTermView/OverView/RawDataViewer.jsx b/src/components/SingleTermView/OverView/RawDataViewer.jsx index c84ad0d6..9ccb3747 100644 --- a/src/components/SingleTermView/OverView/RawDataViewer.jsx +++ b/src/components/SingleTermView/OverView/RawDataViewer.jsx @@ -33,7 +33,7 @@ const RawDataViewer = ({ dataId, dataFormat }) => { const { user } = useContext(GlobalDataContext); useEffect(() => { - getRawData(user?.name || "base",dataId, formatExtensions[dataFormat]).then( rawResponse => { + getRawData("base",dataId, formatExtensions[dataFormat]).then( rawResponse => { setFormattedData(JSON.stringify(rawResponse, null, 2)); setLoading(false) }) diff --git a/src/components/TermEditor/AddNewTermDialogContent.jsx b/src/components/TermEditor/AddNewTermDialogContent.jsx index fc11155a..eb9b1ad6 100644 --- a/src/components/TermEditor/AddNewTermDialogContent.jsx +++ b/src/components/TermEditor/AddNewTermDialogContent.jsx @@ -44,7 +44,7 @@ const formatIdText = (termId) => { ); } -const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChange, onReset }) => { +const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChange, onReset, onClose }) => { const [loading, setLoading] = useState(true); const navigate = useNavigate(); @@ -90,7 +90,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang setAddTermResponse(response); setNewTermId(response.term.id.split("/").pop()); } catch (error) { - setAddTermResponse(error.response); + setAddTermResponse(error); } }, [user]); @@ -99,6 +99,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const handleAddNewTerm = () => { onReset(); setTermValue(''); + setAddTermResponse(null) setIds([]); setFormState(initialFormState) } @@ -223,7 +224,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang statusProps={statusProps} onAction={handleAddNewTerm} onTryAgain={handleAddNewTerm} - onClose={handleGoToTermClick} + onClose={onClose} actionButtonStartIcon={} additionalInfo={formattedNewTermId} />} diff --git a/src/components/TermEditor/TermDialog.jsx b/src/components/TermEditor/TermDialog.jsx index 2017216a..bca961c7 100644 --- a/src/components/TermEditor/TermDialog.jsx +++ b/src/components/TermEditor/TermDialog.jsx @@ -96,6 +96,7 @@ const TermDialog = ({ open, handleClose, searchTerm, forwardPredicateStep }) => areMatchesChecked={areMatchesChecked} onMatchesChange={handleMatchesChange} onReset={handleReset} + onClose={handleCancelBtnClick} /> )} diff --git a/src/main.jsx b/src/main.jsx index 29716269..566b0418 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -8,6 +8,8 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { CookiesProvider } from 'react-cookie'; const queryClient = new QueryClient(); +worker.start(); + ReactDOM.createRoot(document.getElementById('root')).render( diff --git a/vite.config.js b/vite.config.js index fbf05b2a..6dca0b47 100644 --- a/vite.config.js +++ b/vite.config.js @@ -69,7 +69,7 @@ export default defineConfig({ // Inject the location into a custom header we can use in Axios res.setHeader('X-Redirect-Location', location); } - + // Required for credentialed CORS const origin = req.headers.origin; if (origin) { @@ -81,12 +81,12 @@ export default defineConfig({ }, }, - '^/[^/]+/tmp_.*\\.html$': { + '^/[^/]+/(tmp|ilx)_.*\\.(html|ttl|jsonld|n3|owl|csv)$': { target: 'https://uri.olympiangods.org', changeOrigin: true, secure: false, rewrite: path => path, // Keep full path intact - configure: (proxy, _options) => { + configure: (proxy) => { proxy.on('proxyRes', (proxyRes, req, res) => { const origin = req.headers.origin; if (origin) { From 84cfc194d28c6a398a890c121d3166c2a1d41a50 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 26 May 2025 14:22:26 -0700 Subject: [PATCH 7/8] #92 - eslint fixes --- src/components/SingleTermView/OverView/RawDataViewer.jsx | 4 ---- src/components/TermEditor/AddNewTermDialogContent.jsx | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/SingleTermView/OverView/RawDataViewer.jsx b/src/components/SingleTermView/OverView/RawDataViewer.jsx index 9ccb3747..421d2d16 100644 --- a/src/components/SingleTermView/OverView/RawDataViewer.jsx +++ b/src/components/SingleTermView/OverView/RawDataViewer.jsx @@ -3,8 +3,6 @@ import { useState, useEffect } from 'react'; import { Light as SyntaxHighlighter } from 'react-syntax-highlighter'; import { a11yLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'; import { getRawData } from "../../../api/endpoints"; -import { GlobalDataContext } from "../../../contexts/DataContext"; -import { useContext } from "react"; import { vars } from '../../../theme/variables'; const { gray25, gray200, gray500 } = vars; @@ -30,14 +28,12 @@ const RawDataViewer = ({ dataId, dataFormat }) => { const [formattedData, setFormattedData] = useState(null); // eslint-disable-next-line no-unused-vars const [loading, setLoading] = useState(true); - const { user } = useContext(GlobalDataContext); useEffect(() => { getRawData("base",dataId, formatExtensions[dataFormat]).then( rawResponse => { setFormattedData(JSON.stringify(rawResponse, null, 2)); setLoading(false) }) - // eslint-disable-next-line react-hooks/exhaustive-deps }, [dataId, dataFormat]); return ( diff --git a/src/components/TermEditor/AddNewTermDialogContent.jsx b/src/components/TermEditor/AddNewTermDialogContent.jsx index eb9b1ad6..41426fa2 100644 --- a/src/components/TermEditor/AddNewTermDialogContent.jsx +++ b/src/components/TermEditor/AddNewTermDialogContent.jsx @@ -143,6 +143,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang const handleGoToTermClick = () => { navigate(`/view?searchTerm=${newTermId}`); + onClose() } useEffect(() => { @@ -224,7 +225,7 @@ const AddNewTermDialogContent = ({ activeStep, areMatchesChecked, onMatchesChang statusProps={statusProps} onAction={handleAddNewTerm} onTryAgain={handleAddNewTerm} - onClose={onClose} + onClose={handleGoToTermClick} actionButtonStartIcon={} additionalInfo={formattedNewTermId} />} @@ -236,7 +237,8 @@ AddNewTermDialogContent.propTypes = { activeStep: PropTypes.number.isRequired, areMatchesChecked: PropTypes.bool.isRequired, onMatchesChange: PropTypes.func.isRequired, - onReset: PropTypes.func.isRequired + onReset: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, }; export default AddNewTermDialogContent; From ea5ed56c1b8a475d42a23b10dbe47088339483fa Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 26 May 2025 20:04:43 -0700 Subject: [PATCH 8/8] #92 - refactor createpostrequest to take headers --- src/api/endpoints/apiActions.ts | 7 ++----- src/api/endpoints/apiService.ts | 9 ++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/api/endpoints/apiActions.ts b/src/api/endpoints/apiActions.ts index ceb27cf4..d25d8458 100644 --- a/src/api/endpoints/apiActions.ts +++ b/src/api/endpoints/apiActions.ts @@ -6,17 +6,14 @@ import { useCookies } from 'react-cookie' type SecondParameter any> = Parameters[1]; -export const createPostRequest = (endpoint: string, contentType = "application/json", cookie : string) => { +export const createPostRequest = (endpoint: string, headers : object) => { return (data?: D, options?: SecondParameter) => { return customInstance( { url: endpoint, method: "POST", data: data, - headers: { - "Content-Type": contentType, - ...(cookie ? { "Cookie": cookie } : {}) - }, + headers: headers, withCredentials: true }, options, diff --git a/src/api/endpoints/apiService.ts b/src/api/endpoints/apiService.ts index d11682c0..84866d94 100644 --- a/src/api/endpoints/apiService.ts +++ b/src/api/endpoints/apiService.ts @@ -28,9 +28,9 @@ interface JsonLdResponse { '@graph'?: GraphNode[]; } -export const login = createPostRequest(API_CONFIG.REAL_API.SIGNIN, "application/x-www-form-urlencoded") +export const login = createPostRequest(API_CONFIG.REAL_API.SIGNIN, {"Content-Type": "application/x-www-form-urlencoded"}) -export const register = createPostRequest(API_CONFIG.REAL_API.NEWUSER_ILX, "application/x-www-form-urlencoded") +export const register = createPostRequest(API_CONFIG.REAL_API.NEWUSER_ILX, {"Content-Type": "application/x-www-form-urlencoded"}) export const getUserSettings = (group: string) => { @@ -40,7 +40,7 @@ export const getUserSettings = (group: string) => { export const createNewOrganization = ({ group, data }: { group: string, data: any }) => { const endpoint = `/${group}${API_CONFIG.REAL_API.CREATE_NEW_ORGANIZATION}`; - return createPostRequest(endpoint, "application/json")(data); + return createPostRequest(endpoint, { "Content-Type" : "application/json" })(data); }; export const getOrganizations = (group: string) => { @@ -84,8 +84,7 @@ export const createNewEntity = async ({group,data,session}: { group: string; dat const endpoint = `/${group}${API_CONFIG.REAL_API.CREATE_NEW_ENTITY}`; const response = await createPostRequest( endpoint, - "application/x-www-form-urlencoded", - `session=${session}` + { "Content-Type" : "application/x-www-form-urlencoded" } )(data); // If the response is HTML (a string), extract TMP ID