added function to refresh the dataloader data (#143)
This commit is contained in:
parent
bfe6e2c236
commit
410c553ac0
10 changed files with 38 additions and 20 deletions
|
@ -63,7 +63,7 @@ export const PageNav: React.FunctionComponent = () => {
|
|||
<Nav onSelect={onSelect}>
|
||||
<NavList>
|
||||
<NavItem className="keycloak__page_nav__nav_item__realm-selector">
|
||||
<RealmSelector realmList={realmList || []} />
|
||||
<RealmSelector realmList={realmList.data || []} />
|
||||
</NavItem>
|
||||
</NavList>
|
||||
<NavGroup title={t("manage")}>
|
||||
|
|
|
@ -35,7 +35,7 @@ export const ClientScopesSection = () => {
|
|||
<DataLoader loader={loader}>
|
||||
{(scopes) => (
|
||||
<TableToolbar
|
||||
count={scopes!.length}
|
||||
count={scopes.data.length}
|
||||
first={first}
|
||||
max={max}
|
||||
onNextClick={setFirst}
|
||||
|
@ -50,7 +50,7 @@ export const ClientScopesSection = () => {
|
|||
</Button>
|
||||
}
|
||||
>
|
||||
<ClientScopeList clientScopes={scopes} />
|
||||
<ClientScopeList clientScopes={scopes.data} />
|
||||
</TableToolbar>
|
||||
)}
|
||||
</DataLoader>
|
||||
|
|
|
@ -20,6 +20,7 @@ import { exportClient } from "../util";
|
|||
|
||||
type ClientListProps = {
|
||||
clients?: ClientRepresentation[];
|
||||
refresh: () => void;
|
||||
baseUrl: string;
|
||||
};
|
||||
|
||||
|
@ -30,7 +31,7 @@ const columns: (keyof ClientRepresentation)[] = [
|
|||
"baseUrl",
|
||||
];
|
||||
|
||||
export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
||||
export const ClientList = ({ baseUrl, clients, refresh }: ClientListProps) => {
|
||||
const { t } = useTranslation("clients");
|
||||
const httpClient = useContext(HttpClientContext)!;
|
||||
const { realm } = useContext(RealmContext);
|
||||
|
@ -106,11 +107,12 @@ export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
|||
},
|
||||
{
|
||||
title: t("common:delete"),
|
||||
onClick: (_, rowId) => {
|
||||
onClick: async (_, rowId) => {
|
||||
try {
|
||||
httpClient.doDelete(
|
||||
await httpClient.doDelete(
|
||||
`/admin/realms/${realm}/clients/${data[rowId].client.id}`
|
||||
);
|
||||
refresh();
|
||||
add(t("clientDeletedSuccess"), AlertVariant.success);
|
||||
} catch (error) {
|
||||
add(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);
|
||||
|
|
|
@ -83,6 +83,7 @@ export const ClientsSection = () => {
|
|||
>
|
||||
<ClientList
|
||||
clients={clients}
|
||||
refresh={loader}
|
||||
baseUrl={keycloak!.authServerUrl()!}
|
||||
/>
|
||||
</TableToolbar>
|
||||
|
|
|
@ -8,7 +8,11 @@ import { ClientList } from "../ClientList";
|
|||
test("renders ClientList", () => {
|
||||
const container = render(
|
||||
<MemoryRouter>
|
||||
<ClientList clients={clientMock} baseUrl="http://blog.nerdin.ch" />
|
||||
<ClientList
|
||||
clients={clientMock}
|
||||
baseUrl="http://blog.nerdin.ch"
|
||||
refresh={() => {}}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
|
|
|
@ -4,24 +4,31 @@ import { Spinner } from "@patternfly/react-core";
|
|||
type DataLoaderProps<T> = {
|
||||
loader: () => Promise<T>;
|
||||
deps?: any[];
|
||||
children: ((arg: T) => any) | React.ReactNode;
|
||||
children: ((arg: Result<T>) => any) | React.ReactNode;
|
||||
};
|
||||
|
||||
type Result<T> = {
|
||||
data: T;
|
||||
refresh: () => void;
|
||||
};
|
||||
|
||||
export function DataLoader<T>(props: DataLoaderProps<T>) {
|
||||
const [data, setData] = useState<{ result: T } | undefined>(undefined);
|
||||
useEffect(() => {
|
||||
setData(undefined);
|
||||
const loadData = async () => {
|
||||
const result = await props.loader();
|
||||
setData({ result });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setData(undefined);
|
||||
loadData();
|
||||
}, [props]);
|
||||
|
||||
if (data) {
|
||||
if (props.children instanceof Function) {
|
||||
return props.children(data.result);
|
||||
return props.children({
|
||||
data: data.result,
|
||||
refresh: () => loadData(),
|
||||
});
|
||||
}
|
||||
return props.children;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ describe("<DataLoader />", () => {
|
|||
await act(async () => {
|
||||
render(
|
||||
<DataLoader loader={loader}>
|
||||
{(data) => (
|
||||
{(result) => (
|
||||
<div>
|
||||
{data.map((d, i) => (
|
||||
{result.data.map((d, i) => (
|
||||
<i key={i}>{d}</i>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -68,7 +68,7 @@ export const WhoAmIContextProvider = ({ children }: WhoAmIProviderProps) => {
|
|||
<DataLoader loader={whoAmILoader}>
|
||||
{(whoamirep) => (
|
||||
<WhoAmIContext.Provider
|
||||
value={new WhoAmI(keycloak?.realm(), whoamirep)}
|
||||
value={new WhoAmI(keycloak?.realm(), whoamirep.data)}
|
||||
>
|
||||
{children}
|
||||
</WhoAmIContext.Provider>
|
||||
|
|
|
@ -51,7 +51,7 @@ export const RealmRolesSection = () => {
|
|||
<Divider component="li" key={1} />
|
||||
<PageSection padding={{ default: "noPadding" }}>
|
||||
<TableToolbar
|
||||
count={roles!.length}
|
||||
count={roles.data.length}
|
||||
first={first}
|
||||
max={max}
|
||||
onNextClick={setFirst}
|
||||
|
@ -68,7 +68,7 @@ export const RealmRolesSection = () => {
|
|||
</>
|
||||
}
|
||||
>
|
||||
<RolesList roles={roles} />
|
||||
<RolesList roles={roles.data} />
|
||||
</TableToolbar>
|
||||
</PageSection>
|
||||
</>
|
||||
|
|
|
@ -10,5 +10,9 @@ export default {
|
|||
} as Meta;
|
||||
|
||||
export const ClientListExample = () => (
|
||||
<ClientList clients={clientMock} baseUrl="http://test.nl/" />
|
||||
<ClientList
|
||||
clients={clientMock}
|
||||
baseUrl="http://test.nl/"
|
||||
refresh={() => {}}
|
||||
/>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue