Add routing changing actions and RoutePropagator (#110)

This commit is contained in:
Lukasz Ostrowski 2022-11-21 11:32:18 +01:00 committed by GitHub
parent 4ba2ada75c
commit b4e0a053cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 1 deletions

View file

@ -106,6 +106,11 @@
"import": "./app-bridge/index.mjs", "import": "./app-bridge/index.mjs",
"require": "./app-bridge/index.js" "require": "./app-bridge/index.js"
}, },
"./app-bridge/next": {
"types": "./app-bridge/next/index.d.ts",
"import": "./app-bridge/next/index.mjs",
"require": "./app-bridge/next/index.js"
},
"./util": { "./util": {
"types": "./util/index.d.ts", "types": "./util/index.d.ts",
"import": "./util/index.mjs", "import": "./util/index.mjs",

View file

@ -6,6 +6,7 @@ import { Values } from "./helpers";
export const ActionType = { export const ActionType = {
redirect: "redirect", redirect: "redirect",
notification: "notification", notification: "notification",
updateRouting: "updateRouting",
} as const; } as const;
export type ActionType = Values<typeof ActionType>; export type ActionType = Values<typeof ActionType>;
@ -74,9 +75,24 @@ function createNotificationAction(payload: NotificationPayload): NotificationAct
}); });
} }
export type Actions = RedirectAction | NotificationAction; export type UpdateRoutingPayload = {
newRoute: string;
strategy: "replace" | "push";
};
export type UpdateRouting = ActionWithId<"updateRouting", UpdateRoutingPayload>;
function createUpdateRoutingAction(payload: UpdateRoutingPayload): UpdateRouting {
return withActionId({
type: "updateRouting",
payload,
});
}
export type Actions = RedirectAction | NotificationAction | UpdateRouting;
export const actions = { export const actions = {
Redirect: createRedirectAction, Redirect: createRedirectAction,
Notification: createNotificationAction, Notification: createNotificationAction,
UpdateRouting: createUpdateRoutingAction,
}; };

View file

@ -0,0 +1 @@
export * from "./route-propagator";

View file

@ -0,0 +1,43 @@
import { useRouter } from "next/router";
import { useEffect } from "react";
import { actions } from "../actions";
import { useAppBridge } from "../app-bridge-provider";
/**
* Synchronizes app inner state (inside iframe) with dashboard routing, so app's route can be restored after refresh
*/
export const useRoutePropagator = () => {
const { appBridge, appBridgeState } = useAppBridge();
const router = useRouter();
useEffect(() => {
if (!appBridgeState?.ready ?? !appBridge) {
return;
}
router.events.on("routeChangeComplete", (url) => {
appBridge
?.dispatch(
actions.UpdateRouting({
newRoute: url,
strategy: "replace",
})
)
.catch(() => {
console.error("Error dispatching action");
});
});
}, [appBridgeState, appBridge]);
};
/**
* Synchronizes app inner state (inside iframe) with dashboard routing, so app's route can be restored after refresh
*
* Component uses useRoutePropagator(), but it can consume context in the same component where provider was used (e.g. _app.tsx)
*/
export function RoutePropagator() {
useRoutePropagator();
return null;
}

View file

@ -10,6 +10,7 @@ export default defineConfig({
"src/infer-webhooks.ts", "src/infer-webhooks.ts",
"src/APL/index.ts", "src/APL/index.ts",
"src/app-bridge/index.ts", "src/app-bridge/index.ts",
"src/app-bridge/next/index.ts",
"src/handlers/next/index.ts", "src/handlers/next/index.ts",
"src/middleware/index.ts", "src/middleware/index.ts",
"src/settings-manager/index.ts", "src/settings-manager/index.ts",