diff --git a/package.json b/package.json
index 73ad90d..f79d13e 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"@fullcalendar/interaction": "5.10.0",
"@fullcalendar/react": "5.10.0",
"@fullcalendar/timegrid": "5.10.0",
- "@kingsrook/qqq-frontend-core": "1.0.6",
+ "@kingsrook/qqq-frontend-core": "1.0.7",
"@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1",
"@mui/styled-engine": "5.4.1",
diff --git a/src/App.tsx b/src/App.tsx
index 2a64679..19baa15 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -38,9 +38,7 @@ import {useMaterialUIController, setMiniSidenav, setOpenConfigurator} from "cont
// Images
import nfLogo from "assets/images/nutrifresh_one_icon_white.png";
import {Md5} from "ts-md5/dist/md5";
-import AuthenticationButton from "qqq/components/buttons/AuthenticationButton";
import {useCookies} from "react-cookie";
-import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
import EntityCreate from "./qqq/pages/entity-create";
import EntityList from "./qqq/pages/entity-list";
import EntityView from "./qqq/pages/entity-view";
@@ -49,7 +47,6 @@ import ProcessRun from "./qqq/pages/process-run";
import MDAvatar from "./components/MDAvatar";
import ProfileOverview from "./layouts/pages/profile/profile-overview";
import Settings from "./layouts/pages/account/settings";
-import SignInBasic from "./layouts/authentication/sign-in/basic";
import Analytics from "./layouts/dashboards/analytics";
import Sales from "./layouts/dashboards/sales";
import QClient from "./qqq/utils/QClient";
@@ -86,14 +83,14 @@ function getStaticRoutes()
];
}
-const SESSION_ID_COOKIE_NAME = "sessionId";
+export const SESSION_ID_COOKIE_NAME = "sessionId";
LicenseInfo.setLicenseKey(process.env.REACT_APP_MATERIAL_UI_LICENSE_KEY);
export default function App()
{
const [, setCookie] = useCookies([SESSION_ID_COOKIE_NAME]);
const {
- user, getAccessTokenSilently, getIdTokenClaims, logout,
+ user, getAccessTokenSilently, getIdTokenClaims, logout, loginWithRedirect,
} = useAuth0();
const [loadingToken, setLoadingToken] = useState(false);
const [isFullyAuthenticated, setIsFullyAuthenticated] = useState(false);
@@ -110,7 +107,7 @@ export default function App()
try
{
console.log("Loading token...");
- const accessToken = await getAccessTokenSilently();
+ await getAccessTokenSilently();
const idToken = await getIdTokenClaims();
setCookie(SESSION_ID_COOKIE_NAME, idToken.__raw, {path: "/"});
setIsFullyAuthenticated(true);
@@ -131,8 +128,6 @@ export default function App()
layout,
openConfigurator,
sidenavColor,
- transparentSidenav,
- whiteSidenav,
darkMode,
} = controller;
const [onMouseEnter, setOnMouseEnter] = useState(false);
@@ -156,8 +151,7 @@ export default function App()
{
try
{
- console.log("ok now loading qqq things");
- const metaData = await QClient.loadMetaData();
+ const metaData = await QClient.getInstance().loadMetaData();
// get the keys sorted
const keys = [...metaData.tables.keys()].sort((a, b): number =>
@@ -203,12 +197,6 @@ export default function App()
route: "/pages/account/settings",
component: ,
},
- {
- name: "Logout",
- key: "logout",
- route: "/authentication/sign-in/basic",
- component: ,
- },
],
};
@@ -294,27 +282,6 @@ export default function App()
},
);
- const authButton = (
-
-
-
- );
-
const configsButton = (
{configsButton}
- {authButton}
>
)}
diff --git a/src/HandleAuthorizationError.tsx b/src/HandleAuthorizationError.tsx
new file mode 100644
index 0000000..99468c9
--- /dev/null
+++ b/src/HandleAuthorizationError.tsx
@@ -0,0 +1,29 @@
+import React, {
+ useState,
+ useEffect,
+ JSXElementConstructor,
+ Key,
+ ReactElement,
+} from "react";
+import {SESSION_ID_COOKIE_NAME} from "App";
+import {useCookies} from "react-cookie";
+import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
+
+interface Props
+{
+ errorMessage?: string;
+}
+
+export default function HandleAuthorizationError({errorMessage}: Props)
+{
+ const [, , removeCookie] = useCookies([SESSION_ID_COOKIE_NAME]);
+
+ useEffect(() =>
+ {
+ removeCookie(SESSION_ID_COOKIE_NAME, {path: "/"});
+ });
+
+ return (
+ {errorMessage}
+ );
+}
diff --git a/src/examples/Sidenav/index.tsx b/src/examples/Sidenav/index.tsx
index c6efb07..a756d09 100644
--- a/src/examples/Sidenav/index.tsx
+++ b/src/examples/Sidenav/index.tsx
@@ -44,6 +44,7 @@ import {
setTransparentSidenav,
setWhiteSidenav,
} from "context";
+import AuthenticationButton from "qqq/components/Buttons/AuthenticationButton";
// Declaring props types for Sidenav
interface Props {
@@ -314,6 +315,7 @@ function Sidenav({ color, brand, brandName, routes, ...rest }: Props): JSX.Eleme
}
/>
{renderRoutes}
+
);
}
diff --git a/src/index.tsx b/src/index.tsx
index 69ff9d7..4f978af 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,5 +1,5 @@
import ReactDOM from "react-dom";
-import {BrowserRouter, useNavigate} from "react-router-dom";
+import {BrowserRouter, useNavigate, useSearchParams} from "react-router-dom";
import {Auth0Provider} from "@auth0/auth0-react";
import App from "App";
@@ -8,39 +8,39 @@ import {MaterialUIControllerProvider} from "context";
import "./qqq/styles/qqq-override-styles.css";
import ProtectedRoute from "qqq/auth0/protected-route";
import React from "react";
+import HandleAuthorizationError from "HandleAuthorizationError";
// Auth0 params from env
const domain = process.env.REACT_APP_AUTH0_DOMAIN;
const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID;
-/*
-ReactDOM.render(
-
-
-
-
- ,
- document.getElementById("root"),
-);
- */
-
-console.log("what");
-
// @ts-ignore
function Auth0ProviderWithRedirectCallback({children, ...props})
{
const navigate = useNavigate();
+ const [searchParams] = useSearchParams();
+
// @ts-ignore
const onRedirectCallback = (appState) =>
{
navigate((appState && appState.returnTo) || window.location.pathname);
};
- return (
- // @ts-ignore
-
- {children}
-
- );
+ if (searchParams.get("error"))
+ {
+ return (
+ // @ts-ignore
+
+ );
+ }
+ else
+ {
+ return (
+ // @ts-ignore
+
+ {children}
+
+ );
+ }
}
ReactDOM.render(
@@ -57,5 +57,3 @@ ReactDOM.render(
,
document.getElementById("root"),
);
-
-export * from "components/MDButton";
diff --git a/src/qqq/components/buttons/AuthenticationButton/index.tsx b/src/qqq/components/Buttons/AuthenticationButton/index.tsx
similarity index 100%
rename from src/qqq/components/buttons/AuthenticationButton/index.tsx
rename to src/qqq/components/Buttons/AuthenticationButton/index.tsx
diff --git a/src/qqq/components/EntityForm/index.tsx b/src/qqq/components/EntityForm/index.tsx
index 41d8a3f..693b2a3 100644
--- a/src/qqq/components/EntityForm/index.tsx
+++ b/src/qqq/components/EntityForm/index.tsx
@@ -21,6 +21,7 @@ import {Alert} from "@mui/material";
import MDBox from "components/MDBox";
import MDTypography from "components/MDTypography";
import MDButton from "../../../components/MDButton";
+import QClient from "qqq/utils/QClient";
// Declaring props types for EntityForm
interface Props
@@ -30,7 +31,7 @@ interface Props
function EntityForm({id}: Props): JSX.Element
{
- const qController = new QController("");
+ const qController = QClient.getInstance();
const {tableName} = useParams();
const [validations, setValidations] = useState({});
diff --git a/src/qqq/components/Navbar/index.tsx b/src/qqq/components/Navbar/index.tsx
index 38606b7..4653d27 100644
--- a/src/qqq/components/Navbar/index.tsx
+++ b/src/qqq/components/Navbar/index.tsx
@@ -38,7 +38,6 @@ import {
} from "context";
// qqq
-import AuthenticationButton from "qqq/components/buttons/AuthenticationButton";
// Declaring prop types for Navbar
interface Props
@@ -159,14 +158,6 @@ function Navbar({absolute, light, isMini}: Props): JSX.Element
-
- { /*
-
-
- account_circle
-
-
- */ }
{
- const newTableMetaData = await QClient.loadTableMetaData(tableName);
+ const newTableMetaData = await qController.loadTableMetaData(tableName);
setTableMetaData(newTableMetaData);
if (columnSortModel.length === 0)
{
@@ -206,14 +207,14 @@ function EntityList({table}: Props): JSX.Element
const qFilter = buildQFilter();
- const count = await QClient.count(tableName, qFilter);
+ const count = await qController.count(tableName, qFilter);
setTotalRecords(count);
setButtonText(`new ${newTableMetaData.label}`);
setTableLabel(newTableMetaData.label);
const columns = [] as GridColDef[];
- const results = await QClient.query(
+ const results = await qController.query(
tableName,
qFilter,
rowsPerPage,
@@ -362,7 +363,7 @@ function EntityList({table}: Props): JSX.Element
setTableState(tableName);
setFilterModel(null);
setFiltersMenu(null);
- const metaData = await QClient.loadMetaData();
+ const metaData = await qController.loadMetaData();
setTableProcesses(QProcessUtils.getProcessesForTable(metaData, tableName));
diff --git a/src/qqq/pages/entity-view/components/ViewContents/index.tsx b/src/qqq/pages/entity-view/components/ViewContents/index.tsx
index ff1db94..8470b5c 100644
--- a/src/qqq/pages/entity-view/components/ViewContents/index.tsx
+++ b/src/qqq/pages/entity-view/components/ViewContents/index.tsx
@@ -38,8 +38,9 @@ import Icon from "@mui/material/Icon";
import MDAlert from "components/MDAlert";
import MDButton from "../../../../../components/MDButton";
import QProcessUtils from "../../../../utils/QProcessUtils";
+import QClient from "qqq/utils/QClient";
-const qController = new QController("");
+const qController = QClient.getInstance();
// Declaring props types for ViewForm
interface Props
diff --git a/src/qqq/utils/QClient.ts b/src/qqq/utils/QClient.ts
index a8153cb..960595d 100644
--- a/src/qqq/utils/QClient.ts
+++ b/src/qqq/utils/QClient.ts
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
import {QController} from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
-import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
+import {QException} from "@kingsrook/qqq-frontend-core/lib/exceptions/QException";
+import {useAuth0} from "@auth0/auth0-react";
/*******************************************************************************
** client wrapper of qqq backend
@@ -31,40 +31,25 @@ class QClient
{
private static qController: QController;
+ private static handleException(exception: QException)
+ {
+ console.log(`Caught Exception: ${JSON.stringify(exception)}`);
+ const {logout} = useAuth0();
+ if (exception.status === "401")
+ {
+ logout();
+ }
+ }
+
public static getInstance()
{
if (this.qController == null)
{
- this.qController = new QController("");
+ this.qController = new QController("", this.handleException);
}
return this.qController;
}
-
- public static loadTableMetaData(tableName: string)
- {
- return this.getInstance().loadTableMetaData(tableName);
- }
-
- public static loadMetaData()
- {
- return this.getInstance().loadMetaData();
- }
-
- public static query(tableName: string, filter: QQueryFilter, limit: number, skip: number)
- {
- return this.getInstance()
- .query(tableName, filter, limit, skip)
- .catch((error) =>
- {
- throw error;
- });
- }
-
- public static count(tableName: string, filter: QQueryFilter)
- {
- return this.getInstance().count(tableName, filter);
- }
}
export default QClient;