diff --git a/src/FormPipes/Table.jsx b/src/FormPipes/Table.jsx index 65a20423b1768309e50a40ea7edd4c1de0b88283..7ac57d8d0b980cc357765431887c579c77c8ddef 100644 --- a/src/FormPipes/Table.jsx +++ b/src/FormPipes/Table.jsx @@ -44,7 +44,12 @@ export default function PipesTable({ formId, pipes, setPipes }) { const setPipe = (attr, index, value) => { const newPipes = pipes.map((pipe, i) => { - if (index === i) pipe[attr] = value; + if (index === i) { + pipe[attr] = value; + if (attr === "from" && !pipe.to) { + pipe.to = value; + } + } return { ...pipe }; }); diff --git a/src/GeneralSettings/Backends/Backend.jsx b/src/GeneralSettings/Backends/Backend.jsx index 1476c07cbe977727adbc304b69b405c80c4d8bef..11a03ef5e0ecdec93d185b60db28fe39f3ef17ec 100644 --- a/src/GeneralSettings/Backends/Backend.jsx +++ b/src/GeneralSettings/Backends/Backend.jsx @@ -10,14 +10,23 @@ import { useState, useRef, useEffect } from "@wordpress/element"; // source import BackendHeaders from "./Headers"; +import useBackendNames from "../../hooks/useBackendNames"; function NewBackend({ add }) { + const backendNames = useBackendNames(); + const [name, setName] = useState(""); const [baseUrl, setBaseUrl] = useState("https://"); + const [nameConflict, setNameConflict] = useState(false); + + const handleSetName = (name) => { + setNameConflict(backendNames.has(name)); + setName(name.trim()); + }; const onClick = () => add({ name, base_url: baseUrl, headers: [] }); - const disabled = !(name && baseUrl); + const disabled = !(name && baseUrl && !disabled); return ( <div @@ -35,6 +44,11 @@ function NewBackend({ add }) { > <TextControl label={__("Backend name", "wpct-erp-forms")} + help={ + nameConflict + ? __("This name is already in use", "wpct-erp-forms") + : "" + } value={name} onChange={setName} __nextHasNoMarginBottom @@ -64,8 +78,17 @@ export default function Backend({ update, remove, ...data }) { if (data.name === "add") return <NewBackend add={update} />; const [name, setName] = useState(data.name); + const initialName = useRef(data.name); const nameInput = useRef(); + const backendNames = useBackendNames(); + const [nameConflict, setNameConflict] = useState(false); + const handleSetName = (name) => { + console.log(backendNames, name); + setNameConflict(name !== initialName.current && backendNames.has(name)); + setName(name.trim()); + }; + const setHeaders = (headers) => update({ ...data, headers }); useEffect(() => { @@ -76,19 +99,12 @@ export default function Backend({ update, remove, ...data }) { const timeout = useRef(false); useEffect(() => { - if (timeout.current === false) { - timeout.current = 0; - return; - } - clearTimeout(timeout.current); + if (!name || nameConflict) return; timeout.current = setTimeout(() => update({ ...data, name }), 500); }, [name]); - useEffect(() => { - timeout.current = false; - setName(data.name); - }, [data.name]); + useEffect(() => setName(data.name), [data.name]); return ( <div @@ -107,8 +123,13 @@ export default function Backend({ update, remove, ...data }) { <TextControl ref={nameInput} label={__("Backend name", "wpct-erp-forms")} + help={ + nameConflict + ? __("This name is already in use", "wpct-erp-forms") + : "" + } value={name} - onChange={setName} + onChange={handleSetName} onFocus={() => (focus = true)} onBlur={() => (focus = false)} __nextHasNoMarginBottom={true} diff --git a/src/RestApiSettings/FormHooks/FormHook.jsx b/src/RestApiSettings/FormHooks/FormHook.jsx index ba371c83a1c4748f77b79f43800de6cc4af620df..6dee7a5ce65ba2b5bd03b71899cdf88a62d3b70f 100644 --- a/src/RestApiSettings/FormHooks/FormHook.jsx +++ b/src/RestApiSettings/FormHooks/FormHook.jsx @@ -12,9 +12,9 @@ import FormPipes from "../../FormPipes"; function NewFormHook({ add }) { const [{ backends }] = useGeneral(); - const backendOptions = backends.map(({ name, base_url }) => ({ + const backendOptions = backends.map(({ name }) => ({ label: name, - value: base_url, + value: name, })); const forms = useForms(); const formOptions = forms.map(({ id, title }) => ({ @@ -101,9 +101,9 @@ export default function FormHook({ update, remove, ...data }) { if (data.name === "add") return <NewFormHook add={update} />; const [{ backends }] = useGeneral(); - const backendOptions = backends.map(({ name, base_url }) => ({ + const backendOptions = backends.map(({ name }) => ({ label: name, - value: base_url, + value: name, })); const forms = useForms(); const formOptions = forms.map(({ id, title }) => ({ diff --git a/src/RpcApiSettings/FormHooks/FormHook.jsx b/src/RpcApiSettings/FormHooks/FormHook.jsx index e60a76bb355b8c28ad511ae34c92c78ccd7252c1..cd8ae6dbfa34ba386d20140bfb8c71686be38d44 100644 --- a/src/RpcApiSettings/FormHooks/FormHook.jsx +++ b/src/RpcApiSettings/FormHooks/FormHook.jsx @@ -12,9 +12,9 @@ import FormPipes from "../../FormPipes"; function NewFormHook({ add }) { const [{ backends }] = useGeneral(); - const backendOptions = backends.map(({ name, base_url }) => ({ + const backendOptions = backends.map(({ name }) => ({ label: name, - value: base_url, + value: name, })); const forms = useForms(); const formOptions = forms.map(({ id, title }) => ({ @@ -102,9 +102,9 @@ export default function FormHook({ update, remove, ...data }) { if (data.name === "add") return <NewFormHook add={update} />; const [{ backends }] = useGeneral(); - const backendOptions = backends.map(({ name, base_url }) => ({ + const backendOptions = backends.map(({ name }) => ({ label: name, - value: base_url, + value: name, })); const forms = useForms(); const formOptions = forms.map(({ id, title }) => ({ diff --git a/src/SettingsPage/index.jsx b/src/SettingsPage/index.jsx index c67c711e6f8edbea2ce828aa6dd389ccc6a09463..4d1bd85ca14af999d9cc0f776dc6bf8d94eff60c 100644 --- a/src/SettingsPage/index.jsx +++ b/src/SettingsPage/index.jsx @@ -27,7 +27,7 @@ const tabs = [ }, { name: "rpc-api", - title: "RPC API", + title: "Odoo JSON-RPC", }, ]; diff --git a/src/hooks/useBackendNames.js b/src/hooks/useBackendNames.js new file mode 100644 index 0000000000000000000000000000000000000000..4ed8c659f1132ffe7ed1116fdbd86c7dd0d2ac9f --- /dev/null +++ b/src/hooks/useBackendNames.js @@ -0,0 +1,13 @@ +// vendor +import { useMemo } from "@wordpress/element"; + +// source +import { useGeneral } from "../providers/Settings"; + +export default function useBackendNames() { + const [{ backends }] = useGeneral(); + + return useMemo(() => { + return new Set(backends.map(({ name }) => name)); + }, [backends]); +}