@webority/support-react 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/README.md +120 -0
- package/dist/support-react.js +1225 -0
- package/dist/types/ReportIssue.d.ts +23 -0
- package/dist/types/SupportCenter.d.ts +15 -0
- package/dist/types/SupportContact.d.ts +10 -0
- package/dist/types/SupportProvider.d.ts +11 -0
- package/dist/types/client.d.ts +102 -0
- package/dist/types/components/AttachmentField.d.ts +22 -0
- package/dist/types/components/AttachmentThumb.d.ts +16 -0
- package/dist/types/components/MessageThread.d.ts +17 -0
- package/dist/types/components/NewTicketModal.d.ts +19 -0
- package/dist/types/components/RatingPanel.d.ts +20 -0
- package/dist/types/components/ReplyBox.d.ts +16 -0
- package/dist/types/components/TicketDetail.d.ts +13 -0
- package/dist/types/components/TicketForm.d.ts +28 -0
- package/dist/types/components/TicketList.d.ts +17 -0
- package/dist/types/context.d.ts +54 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/lib/files.d.ts +31 -0
- package/dist/types/lib/format.d.ts +13 -0
- package/dist/types/lib/status.d.ts +5 -0
- package/dist/types/lib/url.d.ts +20 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Copyright (c) Webority Technologies. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software and its source code are proprietary and confidential to
|
|
4
|
+
Webority Technologies. Use is restricted to Webority products and teams under
|
|
5
|
+
internal license. Redistribution outside Webority Technologies is prohibited.
|
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# @webority/support-react
|
|
2
|
+
|
|
3
|
+
Customer support for a React portal: a ticket centre, a report-an-issue button that attaches a
|
|
4
|
+
screenshot of the page, and support contact details. It talks to the Webority Support API that
|
|
5
|
+
the product's backend hosts, and it is built on `@webority/ui-react` and `@webority/theme`, so it
|
|
6
|
+
looks like the rest of the portal with no extra CSS.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @webority/support-react @webority/ui-react react-bootstrap bootstrap@5.3.3
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`@webority/ui-react`, `react`, `react-dom`, `react-bootstrap` and `bootstrap` are peer
|
|
15
|
+
dependencies: the portal already has them. Pin `@webority/support-react` to the same exact
|
|
16
|
+
version as `@webority/ui-react`. The screenshot uses `html-to-image`, which installs with the
|
|
17
|
+
package.
|
|
18
|
+
|
|
19
|
+
## Set up the provider
|
|
20
|
+
|
|
21
|
+
Give the provider a client built on the portal's own HTTP instance. That instance already
|
|
22
|
+
carries the bearer token and refreshes it, so the support calls sign in the same way as every
|
|
23
|
+
other call. Attachments are fetched through it too, so private files never need a public URL.
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
import { createSupportClient, SupportProvider } from "@webority/support-react";
|
|
27
|
+
import { userClient } from "./services/api/clients";
|
|
28
|
+
|
|
29
|
+
const supportClient = createSupportClient(userClient, "/api/support");
|
|
30
|
+
|
|
31
|
+
export function App() {
|
|
32
|
+
return (
|
|
33
|
+
<SupportProvider client={supportClient}>
|
|
34
|
+
<Routes />
|
|
35
|
+
</SupportProvider>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`createSupportClient(http, basePath = "/api/support")` accepts any axios-like instance with
|
|
41
|
+
`get(url, config)` and `post(url, data, config)` that resolve to `{ data }`. Every method
|
|
42
|
+
rejects with a `SupportApiError` carrying `code`, `status` and a `message` written for the
|
|
43
|
+
person, which the components show as-is.
|
|
44
|
+
|
|
45
|
+
| Method | Request |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `getConfig()` | `GET {base}/config` |
|
|
48
|
+
| `listTickets()` | `GET {base}/tickets` |
|
|
49
|
+
| `getTicket(id)` | `GET {base}/tickets/{id}` |
|
|
50
|
+
| `createTicket({ category, subject, body, pageUrl, userAgent, appVersion, files, screenshots })` | `POST {base}/tickets`, multipart |
|
|
51
|
+
| `reply(id, { body, files, screenshots })` | `POST {base}/tickets/{id}/replies`, multipart |
|
|
52
|
+
| `reopen(id)` | `POST {base}/tickets/{id}/reopen` |
|
|
53
|
+
| `rate(id, { satisfaction, comment })` | `POST {base}/tickets/{id}/rating`, JSON |
|
|
54
|
+
| `fetchAttachment(id)` | `GET {base}/attachments/{id}`, returns a `Blob` |
|
|
55
|
+
|
|
56
|
+
## Components
|
|
57
|
+
|
|
58
|
+
### `<SupportCenter />`
|
|
59
|
+
|
|
60
|
+
The support page: the customer's tickets with status tabs and a search box, one ticket's
|
|
61
|
+
conversation, and a New ticket dialog.
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
<SupportCenter appVersion={import.meta.env.VITE_APP_VERSION} defaultCategory="Question" />
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Prop | What it does |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `initialTicketId` | Open this ticket first. |
|
|
70
|
+
| `defaultCategory` | Preselected in the New ticket form when the config lists it. |
|
|
71
|
+
| `appVersion` | Recorded on new tickets so support knows which build you were on. |
|
|
72
|
+
|
|
73
|
+
Support emails link to the support page with `?ticket=<id>`. The centre opens that ticket and
|
|
74
|
+
keeps the parameter in step as tickets open and close, so a refresh stays on the same ticket.
|
|
75
|
+
In a ticket the customer can reply with files (pasting an image into the message attaches it),
|
|
76
|
+
reopen a settled ticket, and say whether it solved their problem. Files are checked against the
|
|
77
|
+
config's type, size and count limits before anything uploads.
|
|
78
|
+
|
|
79
|
+
### `<ReportIssue />`
|
|
80
|
+
|
|
81
|
+
A button that takes a screenshot of the current page, then opens a dialog to describe the
|
|
82
|
+
problem. The person can remove the screenshot and add more images by picking, dropping or
|
|
83
|
+
pasting them. The ticket records the page address, the browser and the product version.
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
<ReportIssue floating appVersion={version} getTicketHref={(id) => `/support?ticket=${id}`} />
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
| Prop | What it does |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `label` | Button text. Default "Report an issue". |
|
|
92
|
+
| `floating` | Pin the button to the bottom corner of the screen. |
|
|
93
|
+
| `defaultCategory` | Preselected when the config lists it. Default "Bug report". |
|
|
94
|
+
| `appVersion` | Recorded on the ticket. |
|
|
95
|
+
| `getTicketHref(id)` | Shows a View ticket link to the new ticket. |
|
|
96
|
+
| `onOpenTicket(ticket)` | Called by the View ticket button when there is no href. |
|
|
97
|
+
| `onCreated(ticket)` | Called once the ticket is raised. |
|
|
98
|
+
|
|
99
|
+
The screenshot is taken before the dialog opens, and the button itself is left out of it.
|
|
100
|
+
Anything else the page marks with `data-support-capture="exclude"` is left out too.
|
|
101
|
+
|
|
102
|
+
### `<SupportContact />`
|
|
103
|
+
|
|
104
|
+
The support email with a copy button, the phone number as a call link, and the hours, from the
|
|
105
|
+
support config. A field the product has not set is left out, and nothing renders when none is.
|
|
106
|
+
|
|
107
|
+
```jsx
|
|
108
|
+
<SupportContact />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Hooks
|
|
112
|
+
|
|
113
|
+
`useSupportConfig()`, `useSupportTickets()` and `useSupportTicket(id)` return the data with
|
|
114
|
+
`loading`, `error` and `reload`. `useSupportTicket` also returns `reply`, `reopen` and `rate`,
|
|
115
|
+
each resolving to the updated ticket. `useSupportClient()` returns the client itself.
|
|
116
|
+
|
|
117
|
+
## Display rules
|
|
118
|
+
|
|
119
|
+
Status text always comes from the API's `statusLabel`. Times show in the viewer's own time zone
|
|
120
|
+
with the zone named.
|