Fix more build errors

This commit is contained in:
Darren Clarke 2023-03-15 12:17:43 +00:00
parent 1bdc1e60db
commit 30ce47826f
61 changed files with 1161 additions and 541 deletions

View file

@ -4,22 +4,21 @@ import { signIn, signOut, getSession } from "next-auth/react";
import { useLogin, useTranslate } from "react-admin";
export const authProvider = {
login: (o: any) => {
login(o: any) {
if (o.ok) return Promise.resolve();
return Promise.reject();
},
logout: async () => {
async logout() {
const session = await getSession();
if (session) {
await signOut();
}
},
checkError: (e: any) => {
checkError(e: any) {
if (e.graphQLErrors && e.graphQLErrors.length > 0) {
const permDenied =
e.graphQLErrors.filter((e: any) =>
e.message.match(/.*permission denied.*/)
).length > 0;
const permDenied = e.graphQLErrors.some((e: any) =>
e.message.match(/.*permission denied.*/)
);
if (permDenied)
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject({ message: "auth.permissionDenied" });
@ -31,17 +30,15 @@ export const authProvider = {
return Promise.resolve();
},
checkAuth: async () => {
async checkAuth() {
const session = await getSession();
if (!session) {
return Promise.reject();
throw new Error("Invalid session");
}
return Promise.resolve();
},
getIdentity: async () => {
async getIdentity() {
const session = await getSession();
if (!session) return Promise.reject(new Error("Invalid session"));
if (!session) throw new Error("Invalid session");
return {
id: session.user?.email,
@ -59,10 +56,10 @@ export const AdminLogin: FC = () => {
useEffect(() => {
(async () => {
const session = await getSession();
if (!session) {
signIn();
} else {
if (session) {
reactAdminLogin({ ok: true });
} else {
signIn();
}
})();
});

View file

@ -10,7 +10,7 @@ export const Auth: FC = ({ children }) => {
if (!session && !loading) {
router.push("/login");
}
}, [session, loading]);
}, [session, loading, router]);
if (loading) {
return <CircularProgress />;

View file

@ -1,3 +1,4 @@
/* eslint-disable react/display-name */
import { forwardRef } from "react";
import useDigitInput, { InputAttributes } from "react-digit-input";
import styles from "./DigitInput.module.css";
@ -7,36 +8,35 @@ const DigitInputElement = forwardRef<
Omit<InputAttributes, "ref"> & {
autoFocus?: boolean;
}
>(({ ...props }, ref) => {
return (
<>
<input
aria-label="verification code"
className={styles.input}
{...props}
ref={ref}
inputMode="decimal"
/>
</>
);
});
>(({ ...props }, ref) => (
<>
<input
aria-label="verification code"
className={styles.input}
{...props}
ref={ref}
inputMode="decimal"
/>
</>
));
const DigitSeparator = forwardRef<
HTMLInputElement,
Omit<InputAttributes, "ref"> & {
autoFocus?: boolean;
}
>(({ ...props }, ref) => {
return (
>(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
({ ...props }, ref) => (
<>
<span className={styles.hyphen} ref={ref} />
</>
);
});
)
);
export const SixDigitInput = ({ value, onChange }: any) => {
const digits = useDigitInput({
acceptedCharacters: /^[0-9]$/,
acceptedCharacters: /^\d$/,
length: 6,
value,
onChange,

View file

@ -18,11 +18,10 @@ import voiceProviders from "./voice/providers";
import webhooks from "./webhooks";
import { AdminLogin, authProvider } from "./AdminLogin";
const i18nProvider = polyglotI18nProvider((_locale) => {
return englishMessages;
}, "en");
const i18nProvider = polyglotI18nProvider((_locale) => englishMessages, "en");
const MetamigoAdmin: FC = () => {
// eslint-disable-next-line unicorn/no-null
const [dataProvider, setDataProvider] = useState(null);
const client = useApolloClient();

View file

@ -37,7 +37,7 @@ const AccountEditToolbar: FC<AccountEditToolbarProps> = (props: any) => {
const AccountTitle = ({ record }: { record?: any }) => {
let title = "";
if (record) title = record.name ? record.name : record.email;
if (record) title = record.name ?? record.email;
return <span>Account {title}</span>;
};

View file

@ -1,8 +1,9 @@
/* eslint-disable import/no-named-as-default */
/* eslint-disable import/no-anonymous-default-export */
import AccountIcon from "@material-ui/icons/AccountTree";
import AccountList from "./AccountList";
import AccountEdit from "./AccountEdit";
// eslint-disable-next-line import/no-anonymous-default-export
export default {
list: AccountList,
edit: AccountEdit,

View file

@ -16,6 +16,7 @@ const useStyles = makeStyles({
},
});
// eslint-disable-next-line react/display-name
const ConfigurationMenu = forwardRef<any, any>((props, ref) => {
const translate = useTranslate();
return (

View file

@ -1,3 +1,4 @@
/* eslint-disable import/no-named-as-default */
import { Layout as RaLayout, LayoutProps, Sidebar } from "react-admin";
import AppBar from "./AppBar";
import Menu from "./Menu";
@ -5,17 +6,15 @@ import { theme } from "./themes";
const CustomSidebar = (props: any) => <Sidebar {...props} size={200} />;
const Layout = (props: LayoutProps) => {
return (
<RaLayout
{...props}
appBar={AppBar}
menu={Menu}
sidebar={CustomSidebar}
// @ts-ignore
theme={theme}
/>
);
};
const Layout = (props: LayoutProps) => (
<RaLayout
{...props}
appBar={AppBar}
menu={Menu}
sidebar={CustomSidebar}
// @ts-ignore
theme={theme}
/>
);
export default Layout;

View file

@ -1,106 +1,104 @@
import { SVGProps } from "react";
const Logo = (props: SVGProps<SVGSVGElement>) => {
return (
<svg width="220.001" height="43.659" {...props}>
<path d="M59.39 24.586h4.6v8.512c-1.058.2-3.743.57-5.742.57-6.398 0-7.74-3.77-7.74-11.452 0-7.827 1.4-11.54 7.797-11.54 3.627 0 8.597.828 8.597.828l.115-2.542s-4.885-1.056-9.083-1.056c-8.312 0-10.626 5.112-10.626 14.31 0 8.968 2.228 14.167 10.711 14.167 3.028 0 8.17-.8 8.998-.971V21.816H59.39zm13.14 11.397h2.998V21.302s3.514-1.943 7.284-2.714V15.56c-3.828.743-7.312 3.142-7.312 3.142v-2.713h-2.97zm27.962-13.967c0-4.342-1.913-6.427-6.455-6.427-3.427 0-7.826.885-7.826.885l.114 2.285s4.77-.542 7.57-.542c2.4 0 3.598 1 3.598 3.799v1.742l-6.284.6c-4.113.4-6.112 2.056-6.112 5.912 0 4.028 2 6.113 5.627 6.113 3.6 0 7.198-1.6 7.198-1.6 1.2 1.2 2.656 1.6 4.77 1.6l.114-2.37c-1.285-.144-2.228-.6-2.314-1.743zm-2.999 3.998v6.599s-3.313 1.256-6.284 1.256c-2.028 0-3.027-1.37-3.027-3.684 0-2.2.942-3.37 3.4-3.6zm17.738-10.425c-2.828 0-5.855 1.4-5.855 1.4V7.277h-2.97v28.677s4.283.429 6.683.429c7.283 0 9.425-2.77 9.425-10.711 0-7.198-1.828-10.083-7.283-10.083zm-2.2 18.109c-1.056 0-3.655-.2-3.655-.2V19.416s2.8-1.142 5.54-1.142c3.514 0 4.57 2.228 4.57 7.398 0 5.598-.97 8.026-6.454 8.026zm28.535-11.682c0-4.342-1.942-6.427-6.455-6.427-3.428 0-7.826.885-7.826.885l.114 2.285s4.77-.542 7.57-.542c2.4 0 3.598 1 3.598 3.799v1.742l-6.284.6c-4.113.4-6.112 2.056-6.112 5.912 0 4.028 2 6.113 5.626 6.113 3.6 0 7.198-1.6 7.198-1.6 1.2 1.2 2.628 1.6 4.77 1.6l.115-2.37c-1.286-.144-2.257-.6-2.314-1.743zm-3 3.998v6.599s-3.34 1.256-6.283 1.256c-2.057 0-3.056-1.37-3.056-3.684 0-2.2.97-3.37 3.4-3.6zm24.25-18.737h-2.94v8.826c-.6-.114-3.2-.514-4.914-.514-6.084 0-8.369 3.513-8.369 10.568 0 8.626 3.285 10.226 7.198 10.226 3 0 6.084-1.771 6.084-1.771v1.37h2.942zm-8.654 26.42c-2.37 0-4.484-1.084-4.484-7.54 0-5.198 1.228-7.97 5.427-7.97 1.657 0 4.113.373 4.77.487v13.539s-2.885 1.485-5.713 1.485zM176.3 15.59c-6.313 0-8.54 3.285-8.54 10.168 0 7.255 1.827 10.626 8.54 10.626 6.77 0 8.57-3.37 8.57-10.626 0-6.883-2.2-10.168-8.57-10.168zm0 18.195c-4.713 0-5.484-2.371-5.484-8.027 0-5.57 1.256-7.57 5.484-7.57 4.284 0 5.484 2 5.484 7.57 0 5.656-.714 8.027-5.484 8.027zm13.453 2.199h3V21.303s3.512-1.943 7.254-2.714V15.56c-3.828.743-7.312 3.142-7.312 3.142V15.99h-2.942zm27.934-13.967c0-4.342-1.913-6.427-6.426-6.427-3.456 0-7.855.885-7.855.885l.143 2.285s4.741-.542 7.54-.542c2.4 0 3.6 1 3.6 3.799v1.742l-6.285.6c-4.113.4-6.112 2.056-6.112 5.912 0 4.028 2 6.113 5.655 6.113 3.6 0 7.198-1.6 7.198-1.6 1.2 1.2 2.628 1.6 4.742 1.6l.114-2.37c-1.257-.144-2.228-.6-2.314-1.743zm-2.999 3.998v6.599s-3.313 1.256-6.284 1.256c-2.028 0-3.027-1.37-3.027-3.684 0-2.2.97-3.37 3.4-3.6z" />
<defs>
<linearGradient
gradientTransform="rotate(25)"
id="a"
x1="0"
y1="0"
x2="1"
y2="0"
>
<stop offset="0%" stopColor="#8C48D2" />
<stop offset="100%" stopColor="#CF705A" />
</linearGradient>
<linearGradient
xlinkHref="#a"
id="c"
gradientTransform="scale(.7746 1.291)"
x1="15.492"
y1="4.648"
x2="23.238"
y2="4.648"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="d"
gradientTransform="scale(1.27 .7874)"
x1="7.874"
y1="15.24"
x2="15.748"
y2="15.24"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="e"
gradientTransform="scale(.91287 1.09545)"
x1="10.954"
y1="7.303"
x2="21.909"
y2="7.303"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="f"
gradientTransform="scale(1.13606 .88024)"
x1="3.521"
y1="13.576"
x2="22.886"
y2="13.576"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="g"
gradientTransform="scale(1.029 .97183)"
x1="5.831"
y1="1.029"
x2="23.324"
y2="1.029"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="b"
gradientTransform="scale(.88647 1.12807)"
x1="4.512"
y1=".886"
x2="29.33"
y2=".886"
gradientUnits="userSpaceOnUse"
/>
</defs>
<g transform="translate(-6.238 -1.56) scale(1.55946)" fill="url(#b)">
<path
d="M12 9v4a3 3 0 006 0V9a3 3 0 00-6 0zm3-2a2 2 0 012 2v4a2 2 0 11-4 0V9a2 2 0 012-2z"
fill="url(#c)"
/>
<path
d="M10 13.2a5 5 0 0010 0v-.7a.5.5 0 10-1 0v.7a4 4 0 11-8 0v-.7a.5.5 0 10-1 0z"
fill="url(#d)"
/>
<path
d="M19.5 13a.5.5 0 100-1h-9a.5.5 0 100 1zm-3 6a.5.5 0 110 1h-3a.5.5 0 110-1h1v-1h1v1zm-3-10a.5.5 0 000-1h-1v1zm0 2a.5.5 0 000-1h-1v1zm3 0a.5.5 0 110-1h1v1zm0-2a.5.5 0 110-1h1v1z"
fill="url(#e)"
/>
<path
d="M25.947 14.272a.51.51 0 01.053.23v13.994a.5.5 0 01-.5.5h-21a.5.5 0 01-.5-.5V14.502a.502.502 0 01.2-.406L7 11.95v1.26l-2 1.533v1.253l6.667 5h6.666l6.667-5v-1.253l-2-1.533v-1.26l2.8 2.146a.502.502 0 01.147.176zM10.739 21.55L5 27.29V17.245l5.739 4.304zm.968.446h6.586l6 6H5.707zm7.554-.446L25 17.246V27.29l-5.739-5.739z"
fill="url(#f)"
/>
<path
d="M24 6.2a.5.5 0 00-.146-.354l-4.7-4.7A.5.5 0 0018.8 1H6.5a.5.5 0 00-.5.5V18h1V2h11v4.5a.5.5 0 00.5.5H23v11h1zM19 6V2.41L22.59 6z"
fill="url(#g)"
/>
</g>
</svg>
);
};
const Logo = (props: SVGProps<SVGSVGElement>) => (
<svg width="220.001" height="43.659" {...props}>
<path d="M59.39 24.586h4.6v8.512c-1.058.2-3.743.57-5.742.57-6.398 0-7.74-3.77-7.74-11.452 0-7.827 1.4-11.54 7.797-11.54 3.627 0 8.597.828 8.597.828l.115-2.542s-4.885-1.056-9.083-1.056c-8.312 0-10.626 5.112-10.626 14.31 0 8.968 2.228 14.167 10.711 14.167 3.028 0 8.17-.8 8.998-.971V21.816H59.39zm13.14 11.397h2.998V21.302s3.514-1.943 7.284-2.714V15.56c-3.828.743-7.312 3.142-7.312 3.142v-2.713h-2.97zm27.962-13.967c0-4.342-1.913-6.427-6.455-6.427-3.427 0-7.826.885-7.826.885l.114 2.285s4.77-.542 7.57-.542c2.4 0 3.598 1 3.598 3.799v1.742l-6.284.6c-4.113.4-6.112 2.056-6.112 5.912 0 4.028 2 6.113 5.627 6.113 3.6 0 7.198-1.6 7.198-1.6 1.2 1.2 2.656 1.6 4.77 1.6l.114-2.37c-1.285-.144-2.228-.6-2.314-1.743zm-2.999 3.998v6.599s-3.313 1.256-6.284 1.256c-2.028 0-3.027-1.37-3.027-3.684 0-2.2.942-3.37 3.4-3.6zm17.738-10.425c-2.828 0-5.855 1.4-5.855 1.4V7.277h-2.97v28.677s4.283.429 6.683.429c7.283 0 9.425-2.77 9.425-10.711 0-7.198-1.828-10.083-7.283-10.083zm-2.2 18.109c-1.056 0-3.655-.2-3.655-.2V19.416s2.8-1.142 5.54-1.142c3.514 0 4.57 2.228 4.57 7.398 0 5.598-.97 8.026-6.454 8.026zm28.535-11.682c0-4.342-1.942-6.427-6.455-6.427-3.428 0-7.826.885-7.826.885l.114 2.285s4.77-.542 7.57-.542c2.4 0 3.598 1 3.598 3.799v1.742l-6.284.6c-4.113.4-6.112 2.056-6.112 5.912 0 4.028 2 6.113 5.626 6.113 3.6 0 7.198-1.6 7.198-1.6 1.2 1.2 2.628 1.6 4.77 1.6l.115-2.37c-1.286-.144-2.257-.6-2.314-1.743zm-3 3.998v6.599s-3.34 1.256-6.283 1.256c-2.057 0-3.056-1.37-3.056-3.684 0-2.2.97-3.37 3.4-3.6zm24.25-18.737h-2.94v8.826c-.6-.114-3.2-.514-4.914-.514-6.084 0-8.369 3.513-8.369 10.568 0 8.626 3.285 10.226 7.198 10.226 3 0 6.084-1.771 6.084-1.771v1.37h2.942zm-8.654 26.42c-2.37 0-4.484-1.084-4.484-7.54 0-5.198 1.228-7.97 5.427-7.97 1.657 0 4.113.373 4.77.487v13.539s-2.885 1.485-5.713 1.485zM176.3 15.59c-6.313 0-8.54 3.285-8.54 10.168 0 7.255 1.827 10.626 8.54 10.626 6.77 0 8.57-3.37 8.57-10.626 0-6.883-2.2-10.168-8.57-10.168zm0 18.195c-4.713 0-5.484-2.371-5.484-8.027 0-5.57 1.256-7.57 5.484-7.57 4.284 0 5.484 2 5.484 7.57 0 5.656-.714 8.027-5.484 8.027zm13.453 2.199h3V21.303s3.512-1.943 7.254-2.714V15.56c-3.828.743-7.312 3.142-7.312 3.142V15.99h-2.942zm27.934-13.967c0-4.342-1.913-6.427-6.426-6.427-3.456 0-7.855.885-7.855.885l.143 2.285s4.741-.542 7.54-.542c2.4 0 3.6 1 3.6 3.799v1.742l-6.285.6c-4.113.4-6.112 2.056-6.112 5.912 0 4.028 2 6.113 5.655 6.113 3.6 0 7.198-1.6 7.198-1.6 1.2 1.2 2.628 1.6 4.742 1.6l.114-2.37c-1.257-.144-2.228-.6-2.314-1.743zm-2.999 3.998v6.599s-3.313 1.256-6.284 1.256c-2.028 0-3.027-1.37-3.027-3.684 0-2.2.97-3.37 3.4-3.6z" />
<defs>
<linearGradient
gradientTransform="rotate(25)"
id="a"
x1="0"
y1="0"
x2="1"
y2="0"
>
<stop offset="0%" stopColor="#8C48D2" />
<stop offset="100%" stopColor="#CF705A" />
</linearGradient>
<linearGradient
xlinkHref="#a"
id="c"
gradientTransform="scale(.7746 1.291)"
x1="15.492"
y1="4.648"
x2="23.238"
y2="4.648"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="d"
gradientTransform="scale(1.27 .7874)"
x1="7.874"
y1="15.24"
x2="15.748"
y2="15.24"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="e"
gradientTransform="scale(.91287 1.09545)"
x1="10.954"
y1="7.303"
x2="21.909"
y2="7.303"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="f"
gradientTransform="scale(1.13606 .88024)"
x1="3.521"
y1="13.576"
x2="22.886"
y2="13.576"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="g"
gradientTransform="scale(1.029 .97183)"
x1="5.831"
y1="1.029"
x2="23.324"
y2="1.029"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
xlinkHref="#a"
id="b"
gradientTransform="scale(.88647 1.12807)"
x1="4.512"
y1=".886"
x2="29.33"
y2=".886"
gradientUnits="userSpaceOnUse"
/>
</defs>
<g transform="translate(-6.238 -1.56) scale(1.55946)" fill="url(#b)">
<path
d="M12 9v4a3 3 0 006 0V9a3 3 0 00-6 0zm3-2a2 2 0 012 2v4a2 2 0 11-4 0V9a2 2 0 012-2z"
fill="url(#c)"
/>
<path
d="M10 13.2a5 5 0 0010 0v-.7a.5.5 0 10-1 0v.7a4 4 0 11-8 0v-.7a.5.5 0 10-1 0z"
fill="url(#d)"
/>
<path
d="M19.5 13a.5.5 0 100-1h-9a.5.5 0 100 1zm-3 6a.5.5 0 110 1h-3a.5.5 0 110-1h1v-1h1v1zm-3-10a.5.5 0 000-1h-1v1zm0 2a.5.5 0 000-1h-1v1zm3 0a.5.5 0 110-1h1v1zm0-2a.5.5 0 110-1h1v1z"
fill="url(#e)"
/>
<path
d="M25.947 14.272a.51.51 0 01.053.23v13.994a.5.5 0 01-.5.5h-21a.5.5 0 01-.5-.5V14.502a.502.502 0 01.2-.406L7 11.95v1.26l-2 1.533v1.253l6.667 5h6.666l6.667-5v-1.253l-2-1.533v-1.26l2.8 2.146a.502.502 0 01.147.176zM10.739 21.55L5 27.29V17.245l5.739 4.304zm.968.446h6.586l6 6H5.707zm7.554-.446L25 17.246V27.29l-5.739-5.739z"
fill="url(#f)"
/>
<path
d="M24 6.2a.5.5 0 00-.146-.354l-4.7-4.7A.5.5 0 0018.8 1H6.5a.5.5 0 00-.5.5V18h1V2h11v4.5a.5.5 0 00.5.5H23v11h1zM19 6V2.41L22.59 6z"
fill="url(#g)"
/>
</g>
</svg>
);
export default Logo;

View file

@ -6,7 +6,7 @@ import VoiceIcon from "@material-ui/icons/PhoneInTalk";
import { Box } from "@material-ui/core";
import { useTheme } from "@material-ui/core/styles";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { useTranslate, MenuItemLink, MenuProps } from "react-admin";
import { useTranslate, MenuItemLink } from "react-admin";
import users from "../users";
import accounts from "../accounts";
import webhooks from "../webhooks";
@ -33,9 +33,7 @@ export const Menu: FC = ({ onMenuClick, logout, dense = false }: any) => {
setState((state) => ({ ...state, [menu]: !state[menu] }));
};
return <div />;
};
/*
return (
<Box mt={1}>
<MenuItemLink
to={`/whatsappbots`}
@ -129,5 +127,5 @@ export const Menu: FC = ({ onMenuClick, logout, dense = false }: any) => {
</Box>
);
};
*/
export default Menu;

View file

@ -1,5 +1,3 @@
import AppBar from "./AppBar";
import Layout from "./Layout";
import Menu from "./Menu";
export { AppBar, Layout, Menu };
export {default as AppBar} from "./AppBar";
export {default as Layout} from "./Layout";
export {default as Menu} from "./Menu";

View file

@ -182,7 +182,7 @@ const VerificationCodeRequest = ({
onFailure,
});
})();
}, []);
}, [data.id, onFailure, onSuccess, verifyMode]);
return (
<>
@ -409,7 +409,7 @@ const VerificationCodeDialog = (props: any) => {
);
};
const SignalBotShowActions = ({ basePath, data }: any) => {
const SignalBotShowActions = ({ data }: any) => {
const [open, setOpen] = React.useState(false);
const [verifyMode, setVerifyMode] = React.useState("");
const refresh = useRefresh();

View file

@ -1,3 +1,4 @@
/* eslint-disable react/display-name */
import {
SelectInput,
required,
@ -6,19 +7,21 @@ import {
TextField,
} from "react-admin";
export const SignalBotSelectInput = (source: string) => () => (
<ReferenceInput
label="Signal Bot"
source={source}
reference="signalBots"
validate={[required()]}
>
<SelectInput optionText="phoneNumber" />
</ReferenceInput>
);
export const SignalBotSelectInput = (source: string) => () =>
(
<ReferenceInput
label="Signal Bot"
source={source}
reference="signalBots"
validate={[required()]}
>
<SelectInput optionText="phoneNumber" />
</ReferenceInput>
);
export const SignalBotField = (source: string) => () => (
<ReferenceField label="Signal Bot" reference="signalBots" source={source}>
<TextField source="phoneNumber" />
</ReferenceField>
);
export const SignalBotField = (source: string) => () =>
(
<ReferenceField label="Signal Bot" reference="signalBots" source={source}>
<TextField source="phoneNumber" />
</ReferenceField>
);

View file

@ -30,7 +30,7 @@ const UserEditToolbar = (props: any) => {
<Toolbar className={classes.defaultToolbar} {...props}>
<SaveButton
label="save"
mutationOptions={{ onSuccess: (response) => redirect("/users") }}
mutationOptions={{ onSuccess: () => redirect("/users") }}
/>
<DeleteButton disabled={props.session.user.id === props.record.id} />
</Toolbar>
@ -39,7 +39,7 @@ const UserEditToolbar = (props: any) => {
const UserTitle = ({ record }: { record?: any }) => {
let title = "";
if (record) title = record.name ? record.name : record.email;
if (record) title = record.name ?? record.email;
return <span>User {title}</span>;
};

View file

@ -7,27 +7,25 @@ import {
} from "react-admin";
import { ProviderKindInput } from "./shared";
import TextField from "@material-ui/core/TextField";
// import TextField from "@material-ui/core/TextField";
const TwilioCredentialsInput = () => (
/* const TwilioCredentialsInput = () => (
<span>
<TextField name="accountSid" label="Account Sid" />
<TextField name="authToken" label="Auth Token" />
</span>
); */
const ProviderCreate = (props: CreateProps) => (
<Create {...props} title="Create Providers">
<SimpleForm>
<ProviderKindInput />
<TextInput source="name" />
<TextInput source="credentials.accountSid" />
<TextInput source="credentials.apiKeySid" />
<PasswordInput source="credentials.apiKeySecret" />
</SimpleForm>
</Create>
);
const ProviderCreate = (props: CreateProps) => {
return (
<Create {...props} title="Create Providers">
<SimpleForm>
<ProviderKindInput />
<TextInput source="name" />
<TextInput source="credentials.accountSid" />
<TextInput source="credentials.apiKeySid" />
<PasswordInput source="credentials.apiKeySecret" />
</SimpleForm>
</Create>
);
};
export default ProviderCreate;

View file

@ -9,23 +9,21 @@ import { ProviderKindInput } from "./shared";
const ProviderTitle = ({ record }: { record?: any }) => {
let title = "";
if (record) title = record.name ? record.name : record.email;
if (record) title = record.name ?? record.email;
return <span>Provider {title}</span>;
};
const ProviderEdit = (props: EditProps) => {
return (
<Edit title={<ProviderTitle />} {...props}>
<SimpleForm>
<TextInput disabled source="id" />
<ProviderKindInput disabled />
<TextInput source="name" />
<TextInput source="credentials.accountSid" />
<TextInput source="credentials.apiKeySid" />
<PasswordInput source="credentials.apiKeySecret" />
</SimpleForm>
</Edit>
);
};
const ProviderEdit = (props: EditProps) => (
<Edit title={<ProviderTitle />} {...props}>
<SimpleForm>
<TextInput disabled source="id" />
<ProviderKindInput disabled />
<TextInput source="name" />
<TextInput source="credentials.accountSid" />
<TextInput source="credentials.apiKeySid" />
<PasswordInput source="credentials.apiKeySecret" />
</SimpleForm>
</Edit>
);
export default ProviderEdit;

View file

@ -1,3 +1,4 @@
/* eslint-disable import/no-anonymous-default-export */
import ProviderIcon from "@material-ui/icons/Business";
import ProviderList from "./ProviderList";
import ProviderEdit from "./ProviderEdit";

View file

@ -8,14 +8,13 @@ import { makeStyles, useTheme } from "@material-ui/core/styles";
import AudioPlayer from "material-ui-audio-player";
import { useStopwatch } from "react-timer-hook";
import style from "./MicInput.module.css";
//import type { ReactMicProps } from "react-mic";
// import type { ReactMicProps } from "react-mic";
const ReactMic = dynamic<any>(
// eslint-disable-next-line promise/prefer-await-to-then
() => {
throw new Error(
"MIC INPUT FEATURE IS DISABLED"
); /*return import("react-mic").then((mod) => mod.ReactMic);*/
); /* return import("react-mic").then((mod) => mod.ReactMic); */
},
{ ssr: false }
);
@ -58,7 +57,7 @@ const MicInput = (props: any) => {
field: { value, onChange },
} = useInput(props);
let [record, setRecorder] = useState({ record: false });
const [record, setRecorder] = useState({ record: false });
const decodedValue = resultToDataUri(value);
const startRecording = () => {
setRecorder({ record: true });
@ -71,7 +70,9 @@ const MicInput = (props: any) => {
pause();
};
async function onData(recordedBlob: any) {}
async function onData(recordedBlob: any) {
console.log({ recordedBlob });
}
async function onStop(recordedBlob: any) {
const result = await blobToResult(recordedBlob.blob);
@ -84,16 +85,14 @@ const MicInput = (props: any) => {
.toString()
.padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
const useStyles = makeStyles((theme) => {
return {
volumeIcon: {
display: "none",
},
mainSlider: {
display: "none",
},
};
});
const useStyles = makeStyles(() => ({
volumeIcon: {
display: "none",
},
mainSlider: {
display: "none",
},
}));
return (
<div className="MuiFormControl-marginDense RaFormInput-input-40">

View file

@ -17,38 +17,36 @@ import {
} from "./shared";
import MicInput from "./MicInput";
const VoiceLineCreate = (props: CreateProps) => {
return (
<Create {...props} title="Create Voice Line" transform={populateNumber}>
<SimpleForm>
<ReferenceInput
label="Provider"
source="providerId"
reference="voiceProviders"
validate={[required()]}
>
<SelectInput optionText={(p) => `${p.kind}: ${p.name}`} />
</ReferenceInput>
<FormDataConsumer subscription={{ values: true }}>
{AvailableNumbersInput}
</FormDataConsumer>
<SelectInput
source="language"
choices={TwilioLanguages.languages}
validate={[required()]}
/>
<FormDataConsumer subscription={{ values: true }}>
{VoiceInput}
</FormDataConsumer>
const VoiceLineCreate = (props: CreateProps) => (
<Create {...props} title="Create Voice Line" transform={populateNumber}>
<SimpleForm>
<ReferenceInput
label="Provider"
source="providerId"
reference="voiceProviders"
validate={[required()]}
>
<SelectInput optionText={(p) => `${p.kind}: ${p.name}`} />
</ReferenceInput>
<FormDataConsumer subscription={{ values: true }}>
{AvailableNumbersInput}
</FormDataConsumer>
<SelectInput
source="language"
choices={TwilioLanguages.languages}
validate={[required()]}
/>
<FormDataConsumer subscription={{ values: true }}>
{VoiceInput}
</FormDataConsumer>
<FormDataConsumer subscription={{ values: true }}>
{PromptInput}
</FormDataConsumer>
<BooleanInput source="audioPromptEnabled" />
<MicInput source="promptAudio" />
</SimpleForm>
</Create>
);
};
<FormDataConsumer subscription={{ values: true }}>
{PromptInput}
</FormDataConsumer>
<BooleanInput source="audioPromptEnabled" />
<MicInput source="promptAudio" />
</SimpleForm>
</Create>
);
export default VoiceLineCreate;

View file

@ -15,37 +15,35 @@ import MicInput from "./MicInput";
const VoiceLineTitle = ({ record }: { record?: any }) => {
let title = "";
if (record) title = record.name ? record.name : record.email;
if (record) title = record.name ?? record.email;
return <span>VoiceLine {title}</span>;
};
const VoiceLineEdit = (props: EditProps) => {
return (
<Edit title={<VoiceLineTitle />} {...props}>
<SimpleForm>
<ReferenceInput
disabled
label="Provider"
source="providerId"
reference="providers"
validate={[required()]}
>
<SelectInput optionText={(p) => `${p.kind}: ${p.name}`} />
</ReferenceInput>
<TextInput disabled source="providerLineSid" />
<TextInput disabled source="number" />
<SelectInput source="language" choices={TwilioLanguages.languages} />
<FormDataConsumer subscription={{ values: true }}>
{VoiceInput}
</FormDataConsumer>
<FormDataConsumer subscription={{ values: true }}>
{PromptInput}
</FormDataConsumer>
<BooleanInput source="audioPromptEnabled" />
<MicInput source="promptAudio" />
</SimpleForm>
</Edit>
);
};
const VoiceLineEdit = (props: EditProps) => (
<Edit title={<VoiceLineTitle />} {...props}>
<SimpleForm>
<ReferenceInput
disabled
label="Provider"
source="providerId"
reference="providers"
validate={[required()]}
>
<SelectInput optionText={(p) => `${p.kind}: ${p.name}`} />
</ReferenceInput>
<TextInput disabled source="providerLineSid" />
<TextInput disabled source="number" />
<SelectInput source="language" choices={TwilioLanguages.languages} />
<FormDataConsumer subscription={{ values: true }}>
{VoiceInput}
</FormDataConsumer>
<FormDataConsumer subscription={{ values: true }}>
{PromptInput}
</FormDataConsumer>
<BooleanInput source="audioPromptEnabled" />
<MicInput source="promptAudio" />
</SimpleForm>
</Edit>
);
export default VoiceLineEdit;

View file

@ -1,3 +1,4 @@
/* eslint-disable react/display-name */
import React, { useState, useEffect } from "react";
import PlayIcon from "@material-ui/icons/PlayCircleFilled";
import {
@ -25,7 +26,7 @@ const tts = async (providerId: any): Promise<TTSProvider> => {
return (voice, language, prompt): Promise<void> =>
new Promise((resolve) => {
if (!voice || !language || !prompt) resolve();
const Device = twilioClient.Device;
const { Device } = twilioClient;
const device = new Device();
const silence = `${absoluteUrl().origin}/static/silence.mp3`;
device.setup(token, {
@ -39,7 +40,7 @@ const tts = async (providerId: any): Promise<TTSProvider> => {
outgoing: silence,
},
});
device.on("ready", function (device: any) {
device.on("ready", (device: any) => {
device.connect({ language, voice, prompt });
});
device.on("disconnect", () => resolve());
@ -69,14 +70,14 @@ export const TextToSpeechButton = ({ form }: any) => {
useEffect(() => {
(async () => {
setPlayText({
func: async () => {
async func() {
setLoading(true);
if (ttsProvider) await ttsProvider.provider(voice, language, prompt);
setLoading(false);
},
});
})();
}, [prompt, language, voice, ttsProvider?.provider]);
}, [prompt, language, voice, ttsProvider, ttsProvider?.provider]);
const disabled = !(providerId && prompt?.length >= 2 && voice && language);
/* TODO add this back to IconButtonwhen we know how to extend MUI theme and appease typescript
@ -90,19 +91,17 @@ export const TextToSpeechButton = ({ form }: any) => {
);
};
export const PromptInput = (form: any, ...rest: any[]) => {
return (
<TextInput
source="promptText"
multiline
options={{ fullWidth: true }}
InputProps={{ endAdornment: <TextToSpeechButton form={form} /> }}
{...rest}
/>
);
};
export const PromptInput = (form: any, ...rest: any[]) => (
<TextInput
source="promptText"
multiline
options={{ fullWidth: true }}
InputProps={{ endAdornment: <TextToSpeechButton form={form} /> }}
{...rest}
/>
);
const validateVoice = (args: any, values: any) => {
const validateVoice = (_args: any, values: any) => {
if (!values.language) return "validation.language";
if (!values.voice) return "validation.voice";
// @ts-expect-error
@ -145,25 +144,20 @@ const getAvailableNumbers = async (providerId: string) => {
}
};
const sidToNumber = (sid: any) => {
return availableNumbers
.filter(({ id }) => id === sid)
.map(({ name }) => name)[0];
};
const sidToNumber = (sid: any) =>
availableNumbers.filter(({ id }) => id === sid).map(({ name }) => name)[0];
export const populateNumber = (data: any) => {
return {
...data,
number: sidToNumber(data.providerLineSid),
};
};
export const populateNumber = (data: any) => ({
...data,
number: sidToNumber(data.providerLineSid),
});
const hasNumbers = (
args: any,
value: any,
values: any,
translate: any,
...props: any[]
_args: any,
_value: any,
_values: any,
_translate: any,
..._props: any[]
) => {
if (noAvailableNumbers) return "validation.noAvailableNumbers";
@ -197,7 +191,7 @@ export const AvailableNumbersInput = (form: any, ...rest: any[]) => {
notify("validation.noAvailableNumbers", { type: "error" });
setLoading(false);
}
}, [form && form.formData ? form.formData.providerId : undefined]);
}, [form, notify, translate]);
return (
<>

View file

@ -22,35 +22,30 @@ import { BackendTypeInput, BackendIdInput, HttpMethodInput } from "./shared";
<SelectInput optionText="number" />
</ReferenceInput>
*/
const WebhookCreate = (props: CreateProps) => {
return (
<Create {...props} title="Create Webhooks">
<SimpleForm>
<TextInput source="name" validate={[required()]} />
<BackendTypeInput />
<FormDataConsumer subscription={{ values: true }}>
{BackendIdInput}
</FormDataConsumer>
<TextInput
source="endpointUrl"
validate={[required(), regex(/^https?:\/\/[^/]+/, "validation.url")]}
/>
<HttpMethodInput />
<ArrayInput source="headers">
<SimpleFormIterator>
<TextInput
source="header"
validate={[
required(),
regex(/^[\w-]+$/, "validation.headerName"),
]}
/>
<TextInput source="value" validate={[required()]} />
</SimpleFormIterator>
</ArrayInput>
</SimpleForm>
</Create>
);
};
const WebhookCreate = (props: CreateProps) => (
<Create {...props} title="Create Webhooks">
<SimpleForm>
<TextInput source="name" validate={[required()]} />
<BackendTypeInput />
<FormDataConsumer subscription={{ values: true }}>
{BackendIdInput}
</FormDataConsumer>
<TextInput
source="endpointUrl"
validate={[required(), regex(/^https?:\/\/[^/]+/, "validation.url")]}
/>
<HttpMethodInput />
<ArrayInput source="headers">
<SimpleFormIterator>
<TextInput
source="header"
validate={[required(), regex(/^[\w-]+$/, "validation.headerName")]}
/>
<TextInput source="value" validate={[required()]} />
</SimpleFormIterator>
</ArrayInput>
</SimpleForm>
</Create>
);
export default WebhookCreate;

View file

@ -13,39 +13,34 @@ import { BackendTypeInput, BackendIdInput, HttpMethodInput } from "./shared";
const WebhookTitle = ({ record }: any) => {
let title = "";
if (record) title = record.name ? record.name : record.email;
if (record) title = record.name ?? record.email;
return <span>Webhook {title}</span>;
};
const WebhookEdit = (props: EditProps) => {
return (
<Edit title={<WebhookTitle />} {...props}>
<SimpleForm>
<TextInput source="name" validate={[required()]} />
<BackendTypeInput />
<FormDataConsumer subscription={{ values: true }}>
{BackendIdInput}
</FormDataConsumer>
<TextInput
source="endpointUrl"
validate={[required(), regex(/^https?:\/\/[^/]+/, "validation.url")]}
/>
<HttpMethodInput />
<ArrayInput source="headers">
<SimpleFormIterator>
<TextInput
source="header"
validate={[
required(),
regex(/^[\w-]+$/, "validation.headerName"),
]}
/>
<TextInput source="value" validate={[required()]} />
</SimpleFormIterator>
</ArrayInput>
</SimpleForm>
</Edit>
);
};
const WebhookEdit = (props: EditProps) => (
<Edit title={<WebhookTitle />} {...props}>
<SimpleForm>
<TextInput source="name" validate={[required()]} />
<BackendTypeInput />
<FormDataConsumer subscription={{ values: true }}>
{BackendIdInput}
</FormDataConsumer>
<TextInput
source="endpointUrl"
validate={[required(), regex(/^https?:\/\/[^/]+/, "validation.url")]}
/>
<HttpMethodInput />
<ArrayInput source="headers">
<SimpleFormIterator>
<TextInput
source="header"
validate={[required(), regex(/^[\w-]+$/, "validation.headerName")]}
/>
<TextInput source="value" validate={[required()]} />
</SimpleFormIterator>
</ArrayInput>
</SimpleForm>
</Edit>
);
export default WebhookEdit;

View file

@ -1,11 +1,4 @@
import {
List,
Datagrid,
DateField,
TextField,
ReferenceField,
ListProps,
} from "react-admin";
import { List, Datagrid, DateField, TextField, ListProps } from "react-admin";
import { BackendIdField } from "./shared";
const WebhookList = (props: ListProps) => (

View file

@ -145,6 +145,7 @@ const WhatsappBotShow = (props: ShowProps) => {
}, 10000);
return () => clearInterval(interval);
}
return undefined;
}, [refresh, data]);

View file

@ -1,3 +1,4 @@
/* eslint-disable react/display-name */
import {
SelectInput,
required,
@ -6,19 +7,25 @@ import {
TextField,
} from "react-admin";
export const WhatsAppBotSelectInput = (source: string) => () => (
<ReferenceInput
label="WhatsApp Bot"
reference="whatsappBots"
source={source}
validate={[required()]}
>
<SelectInput optionText="phoneNumber" />
</ReferenceInput>
);
export const WhatsAppBotSelectInput = (source: string) => () =>
(
<ReferenceInput
label="WhatsApp Bot"
reference="whatsappBots"
source={source}
validate={[required()]}
>
<SelectInput optionText="phoneNumber" />
</ReferenceInput>
);
export const WhatsAppBotField = (source: string) => () => (
<ReferenceField label="WhatsApp Bot" reference="whatsappBots" source={source}>
<TextField source="phoneNumber" />
</ReferenceField>
);
export const WhatsAppBotField = (source: string) => () =>
(
<ReferenceField
label="WhatsApp Bot"
reference="whatsappBots"
source={source}
>
<TextField source="phoneNumber" />
</ReferenceField>
);