Skip to content
This repository was archived by the owner on Jan 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2 from saleor/enable-action-dispatching
Browse files Browse the repository at this point in the history
Enable action dispatching
  • Loading branch information
jwm0 authored Aug 20, 2021
2 parents 66d728a + e6d937d commit b0d0630
Show file tree
Hide file tree
Showing 11 changed files with 445 additions and 114 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module.exports = {
extends: ["prettier/@typescript-eslint", "plugin:prettier/recommended"],
plugins: ["simple-import-sort"],
plugins: ["simple-import-sort", "eslint-plugin-tsdoc"],
rules: {
quotes: ["off"],
"simple-import-sort/imports": ["error"],
"sort-imports": "off", // imports are handled by simple-import-sort/sort
"tsdoc/syntax": "warn",
},
};
57 changes: 51 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,60 @@ Access app state:
const { token, domain, ready } = app.getState();
```

Subscribe to events:
## Events
Events are messages that originate in Saleor Dashboard.

### Available methods
**`subscribe(eventType, callback)`** - can be used to listen to particular event type. It returns an unsubscribe function, which unregisters the callback.

Example:
```js
const unsubscribe = app.subscribe("handshake", (state) => state.token);
const unsubscribe = app.subscribe("handshake", (payload) => {
setToken(payload.token); // do something with event payload
const { token } = app.getState(); // you can also get app's current state here
});

// unsubscribe when callback is no longer needed
unsubscribe();
```

### Available events
| Event name | Description |
| :--------- | :------------------------------------------------------------------------------- |
| `handshake` | Fired when iFrame containing the App is initialized or new token is assigned |
**`unsubscribeAll(eventType?)`** - unregisters all callbacks of provided type. If no type was provided, it will remove all event callbacks.

Example:
```js
app.unsubscribeAll("handshake"); // unsubscribe from all handshake events

app.unsubscribeAll(); // unsubscribe from all events
```

### Available event types
| Event type | Description |
| :---------- | :--------------------------------------------------------------------------- |
| `handshake` | Fired when iFrame containing the App is initialized or new token is assigned |
| `response` | Fired when Dashboard responds to an Action |


## Actions
Actions expose a high-level API to communicate with Saleor Dashboard.

### Available methods
**`dispatch(action)`** - dispatches an Action. Returns a promise which resolves when action is successfully completed.

Example:
```js
import { Redirect } from "@saleor/app-bridge/actions";

const handleRedirect = async () => {
await app.dispatch(Redirect({ to: "/orders" }));
console.log("Redirect complete!");
}

handleRedirect();
```

### Available actions
| Action | Arguments | Description |
| :--------- | :--------------------------------------------------------------- | :---------- |
| `Redirect` | `to` (string) - relative (inside Dashboard) or absolute URL path | |
| | `newContext` (boolean) - should open in a new browsing context | |

65 changes: 61 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,17 @@
"devDependencies": {
"@size-limit/preset-small-lib": "^5.0.2",
"@testing-library/dom": "^8.1.0",
"@types/uuid": "^8.3.1",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-tsdoc": "^0.2.14",
"husky": "^7.0.1",
"np": "^7.5.0",
"size-limit": "^5.0.2",
"tsdx": "^0.14.1",
"tslib": "^2.3.0",
"typescript": "^4.3.5"
},
"dependencies": {
"uuid": "^8.3.2"
}
}
65 changes: 52 additions & 13 deletions src/actions.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,55 @@
type HandshakeAction = {
payload: {
token: string;
};
type: "handshake";
import { v4 as uuidv4 } from "uuid";

import { Values } from "./helpers";

// Using constants over Enums, more info: https://fettblog.eu/tidy-typescript-avoid-enums/
export const ActionType = {
redirect: "redirect",
} as const;
export type ActionType = Values<typeof ActionType>;

type Action<Name extends ActionType, Payload extends {}> = {
payload: Payload;
type: Name;
};

type ActionWithId<Name extends ActionType, Payload extends {}> = {
payload: Payload & { actionId: string };
type: Name;
};

// type ThemeAction = {
// payload: {
// theme: "light" | "dark";
// }
// type: "theme"
// }
function withActionId<
Name extends ActionType,
Payload extends {},
T extends Action<Name, Payload>
>(action: T): ActionWithId<Name, Payload> {
const actionId = uuidv4();

return {
...action,
payload: {
...action.payload,
actionId,
},
};
}

export type RedirectPayload = {
/**
* Relative (inside Dashboard) or absolute URL path.
*/
to: string;
newContext?: boolean;
};
/**
* Redirects Dashboard user.
*/
export type RedirectAction = ActionWithId<"redirect", RedirectPayload>;
export function Redirect(payload: RedirectPayload): RedirectAction {
return withActionId({
payload,
type: "redirect",
});
}

export type Action = HandshakeAction;
export type ActionType = Action["type"];
export type Actions = RedirectAction;
Loading

0 comments on commit b0d0630

Please sign in to comment.