Skip to content

Commit

Permalink
Refactor admin app to prepare v5 migration
Browse files Browse the repository at this point in the history
  • Loading branch information
fzaninotto committed Jul 11, 2024
1 parent f9accb4 commit adf1a06
Show file tree
Hide file tree
Showing 31 changed files with 577 additions and 421 deletions.
99 changes: 43 additions & 56 deletions pwa/components/admin/Admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,37 @@

import Head from "next/head";
import { useContext, useRef, useState } from "react";
import { type DataProvider, Layout, type LayoutProps, localStorageStore, resolveBrowserLocale } from "react-admin";
import { type DataProvider, localStorageStore } from "react-admin";
import { signIn, useSession } from "next-auth/react";
import SyncLoader from "react-spinners/SyncLoader";
import polyglotI18nProvider from "ra-i18n-polyglot";
import englishMessages from "ra-language-english";
import frenchMessages from "ra-language-french";
import { fetchHydra, HydraAdmin, hydraDataProvider, OpenApiAdmin, ResourceGuesser } from "@api-platform/admin";
import {
fetchHydra,
HydraAdmin,
hydraDataProvider,
OpenApiAdmin,
ResourceGuesser,
} from "@api-platform/admin";
import { parseHydraDocumentation } from "@api-platform/api-doc-parser";

import { type Session } from "../../app/auth";
import DocContext from "../../components/admin/DocContext";
import authProvider from "../../components/admin/authProvider";
import AppBar from "../../components/admin/AppBar";
import Menu from "../../components/admin/Menu";
import Layout from "./layout/Layout";
import { ENTRYPOINT } from "../../config/entrypoint";
import { List as BooksList } from "../../components/admin/book/List";
import { Create as BooksCreate } from "../../components/admin/book/Create";
import { Edit as BooksEdit } from "../../components/admin/book/Edit";
import { List as ReviewsList } from "../../components/admin/review/List";
import { Show as ReviewsShow } from "../../components/admin/review/Show";
import { Edit as ReviewsEdit } from "../../components/admin/review/Edit";
import { type Book } from "../../types/Book";
import { type Review } from "../../types/Review";
import bookResourceProps from "./book";
import reviewResourceProps from "./review";
import i18nProvider from "./i18nProvider";

const apiDocumentationParser = (session: Session) => async () => {
try {
return await parseHydraDocumentation(ENTRYPOINT, {
headers: {
Authorization: `Bearer ${session?.accessToken}`,
},
headers: {
Authorization: `Bearer ${session?.accessToken}`,
},
});
} catch (result) {
// @ts-ignore
const {api, response, status} = result;
const { api, response, status } = result;
if (status !== 401 || !response) {
throw result;
}
Expand All @@ -48,31 +45,26 @@ const apiDocumentationParser = (session: Session) => async () => {
}
};

const messages = {
fr: frenchMessages,
en: englishMessages,
};
const i18nProvider = polyglotI18nProvider(
// @ts-ignore
(locale) => (messages[locale] ? messages[locale] : messages.en),
resolveBrowserLocale(),
);

const MyLayout = (props: React.JSX.IntrinsicAttributes & LayoutProps) => <Layout {...props} appBar={AppBar} menu={Menu}/>;

const AdminUI = ({ session, children }: { session: Session, children?: React.ReactNode | undefined }) => {
const AdminAdapter = ({
session,
children,
}: {
session: Session;
children?: React.ReactNode | undefined;
}) => {
// @ts-ignore
const dataProvider = useRef<DataProvider>();
const { docType } = useContext(DocContext);

dataProvider.current = hydraDataProvider({
entrypoint: ENTRYPOINT,
httpClient: (url: URL, options = {}) => fetchHydra(url, {
...options,
headers: {
Authorization: `Bearer ${session?.accessToken}`,
},
}),
httpClient: (url: URL, options = {}) =>
fetchHydra(url, {
...options,
headers: {
Authorization: `Bearer ${session?.accessToken}`,
},
}),
apiDocumentationParser: apiDocumentationParser(session),
});

Expand All @@ -84,7 +76,7 @@ const AdminUI = ({ session, children }: { session: Session, children?: React.Rea
dataProvider={dataProvider.current}
entrypoint={window.origin}
i18nProvider={i18nProvider}
layout={MyLayout}
layout={Layout}
>
{!!children && children}
</HydraAdmin>
Expand All @@ -97,31 +89,26 @@ const AdminUI = ({ session, children }: { session: Session, children?: React.Rea
entrypoint={window.origin}
docEntrypoint={`${window.origin}/docs.json`}
i18nProvider={i18nProvider}
layout={MyLayout}
layout={Layout}
>
{!!children && children}
</OpenApiAdmin>
);
};

const store = localStorageStore();

const AdminWithContext = ({ session }: { session: Session }) => {
const [docType, setDocType] = useState(
store.getItem<string>("docType", "hydra"),
store.getItem<string>("docType", "hydra")
);

return (
<DocContext.Provider
value={{
docType,
setDocType,
}}>
<AdminUI session={session}>
<ResourceGuesser name="admin/books" list={BooksList} create={BooksCreate} edit={BooksEdit} hasShow={false}
recordRepresentation={(record: Book) => `${record.title} - ${record.author}`}/>
<ResourceGuesser name="admin/reviews" list={ReviewsList} show={ReviewsShow} edit={ReviewsEdit} hasCreate={false}
recordRepresentation={(record: Review) => record.user.name}/>
</AdminUI>
<DocContext.Provider value={{ docType, setDocType }}>
<AdminAdapter session={session}>
<ResourceGuesser name="admin/books" {...bookResourceProps} />
<ResourceGuesser name="admin/reviews" {...reviewResourceProps} />
</AdminAdapter>
</DocContext.Provider>
);
};
Expand All @@ -131,18 +118,18 @@ const AdminWithOIDC = () => {
const { data: session, status } = useSession();

if (status === "loading") {
return <SyncLoader size={8} color="#46B6BF"/>;
return <SyncLoader size={8} color="#46B6BF" />;
}

// @ts-ignore
if (!session || session?.error === "RefreshAccessTokenError") {
(async() => await signIn("keycloak"))();
(async () => await signIn("keycloak"))();

return;
}

// @ts-ignore
return <AdminWithContext session={session}/>;
return <AdminWithContext session={session} />;
};

const Admin = () => (
Expand All @@ -152,7 +139,7 @@ const Admin = () => (
</Head>

{/*@ts-ignore*/}
<AdminWithOIDC/>
<AdminWithOIDC />
</>
);

Expand Down
121 changes: 0 additions & 121 deletions pwa/components/admin/AppBar.tsx

This file was deleted.

13 changes: 0 additions & 13 deletions pwa/components/admin/Menu.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { required } from "react-admin";
import { ConditionInput } from "./ConditionInput";
import { BookInput } from "./BookInput";

export const Form = () => (
export const BookForm = () => (
<>
<BookInput source="book" validate={required()}/>
<ConditionInput source="condition" validate={required()}/>
<BookInput validate={required()} />
<ConditionInput validate={required()} />
</>
);
Loading

0 comments on commit adf1a06

Please sign in to comment.