@eintrek/erp-shell 0.1.52 → 0.1.54
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/README.md +4 -1
- package/dist/help/help-api.d.ts +53 -3
- package/dist/help/help-attach.d.ts +145 -0
- package/dist/help/help-dialog.d.ts +4 -2
- package/dist/help/help-images.d.ts +42 -0
- package/dist/help/help-link.d.ts +15 -0
- package/dist/help/help-store.d.ts +13 -1
- package/dist/http/platform-api.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +1661 -818
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1663 -815
- package/dist/index.js.map +1 -1
- package/dist/navigation/my-roles.d.ts +41 -0
- package/dist/navigation/nav-user.d.ts +12 -1
- package/dist/navigation/use-my-roles.d.ts +15 -0
- package/dist/version.d.ts +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -100,7 +100,10 @@ the data in as props:
|
|
|
100
100
|
|
|
101
101
|
- `NavUser` — accepts `organization?`, `profileHref?`,
|
|
102
102
|
`selectOrganizationHref?`, `signInRedirectHref?`. Reads `useSession`
|
|
103
|
-
+ `useTheme` internally.
|
|
103
|
+
+ `useTheme` internally. From 0.1.53 the card shows the person's roles
|
|
104
|
+
in the current organisation (platform-api `GET /organizations/:id/my-roles`,
|
|
105
|
+
via `useMyRoles`); `showRoles?` (default: `showSelectOrganization`) and
|
|
106
|
+
`organizationId?` (default: the X-Organization-ID the API client sends).
|
|
104
107
|
- `NavMain` — accepts `items`, `orgCode?`, `closeOnNavigation?`,
|
|
105
108
|
`approvalCounts?` (HR uses the last one for queue badges).
|
|
106
109
|
- `OrganizationSwitcher` — accepts `activeOrganization`, `organizations`,
|
package/dist/help/help-api.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { HelpAppId } from "./help-store";
|
|
2
2
|
import type { HelpContext } from "./help-context";
|
|
3
|
+
import { type HelpUploader } from "./help-attach";
|
|
4
|
+
/**
|
|
5
|
+
* The help channel lives on platform-api (POST /support/messages). The shared
|
|
6
|
+
* axios instance carries the user's token and the organisation header, and
|
|
7
|
+
* refreshes a stale token.
|
|
8
|
+
*/
|
|
3
9
|
export declare function helpApiBase(app: HelpAppId | "other"): string;
|
|
4
10
|
export type HelpKind = "help" | "problem" | "feedback";
|
|
5
11
|
export interface HelpSent {
|
|
@@ -8,6 +14,22 @@ export interface HelpSent {
|
|
|
8
14
|
status: string;
|
|
9
15
|
created_at: string;
|
|
10
16
|
}
|
|
17
|
+
/** An image on a message or a follow-up; url works for a few minutes. */
|
|
18
|
+
export interface HelpImage {
|
|
19
|
+
id: string;
|
|
20
|
+
file_name: string;
|
|
21
|
+
content_type: string;
|
|
22
|
+
size: number;
|
|
23
|
+
url?: string;
|
|
24
|
+
}
|
|
25
|
+
/** One step of a thread after the message: a staff answer or the author's follow-up. */
|
|
26
|
+
export interface HelpThreadEntry {
|
|
27
|
+
id: string;
|
|
28
|
+
author: "customer" | "staff";
|
|
29
|
+
body: string;
|
|
30
|
+
created_at: string;
|
|
31
|
+
images: HelpImage[];
|
|
32
|
+
}
|
|
11
33
|
export interface MyHelpMessage {
|
|
12
34
|
id: string;
|
|
13
35
|
ref: string;
|
|
@@ -16,20 +38,48 @@ export interface MyHelpMessage {
|
|
|
16
38
|
message: string;
|
|
17
39
|
status: "new" | "answered" | "closed";
|
|
18
40
|
created_at: string;
|
|
41
|
+
/** The message's own images (platform-api before images: absent). */
|
|
42
|
+
images?: HelpImage[];
|
|
43
|
+
/** Staff answers only. */
|
|
19
44
|
replies: Array<{
|
|
20
45
|
body: string;
|
|
21
46
|
created_at: string;
|
|
22
47
|
}>;
|
|
48
|
+
/** Answers and follow-ups in order (platform-api before follow-ups: absent). */
|
|
49
|
+
thread?: HelpThreadEntry[];
|
|
23
50
|
}
|
|
24
|
-
/**
|
|
51
|
+
/** The thread of m, oldest first, from whichever shape platform-api sent. */
|
|
52
|
+
export declare function helpThread(m: MyHelpMessage): HelpThreadEntry[];
|
|
53
|
+
/** A failure the dialog shows as is; attachmentId names the image it is about. */
|
|
25
54
|
export declare class HelpSendError extends Error {
|
|
26
|
-
readonly status?: number
|
|
27
|
-
|
|
55
|
+
readonly status?: number;
|
|
56
|
+
readonly attachmentId?: string;
|
|
57
|
+
constructor(message: string, status?: number, attachmentId?: string);
|
|
28
58
|
}
|
|
29
59
|
export declare function sendHelpMessage(input: {
|
|
30
60
|
app: HelpAppId | "other";
|
|
31
61
|
kind: HelpKind;
|
|
32
62
|
message: string;
|
|
33
63
|
context: HelpContext;
|
|
64
|
+
attachmentIds?: string[];
|
|
34
65
|
}): Promise<HelpSent>;
|
|
66
|
+
/** One of the caller's messages by id or reference number ("H1004"). */
|
|
67
|
+
export declare function getMyHelpMessage(app: HelpAppId | "other", key: string): Promise<MyHelpMessage>;
|
|
68
|
+
/** The author writes again on their own message. */
|
|
69
|
+
export declare function sendHelpFollowUp(input: {
|
|
70
|
+
app: HelpAppId | "other";
|
|
71
|
+
key: string;
|
|
72
|
+
message: string;
|
|
73
|
+
attachmentIds?: string[];
|
|
74
|
+
}): Promise<{
|
|
75
|
+
id: string;
|
|
76
|
+
ref: string;
|
|
77
|
+
status: string;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* The uploader the dialog uses: an upload URL from platform-api, the bytes
|
|
81
|
+
* straight to the bucket, then platform-api reads them to say whether they
|
|
82
|
+
* are an image it will take.
|
|
83
|
+
*/
|
|
84
|
+
export declare function helpUploader(app: HelpAppId | "other"): HelpUploader;
|
|
35
85
|
export declare function listMyHelpMessages(app: HelpAppId | "other"): Promise<MyHelpMessage[]>;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The images on a help message (and on a follow-up): what was added, what is
|
|
3
|
+
* uploading, what is ready to send, and what was refused and why.
|
|
4
|
+
*
|
|
5
|
+
* Plain state with no React and no network of its own — the uploader is
|
|
6
|
+
* handed in — so the rules are tested on their own (help-attach.test.ts):
|
|
7
|
+
* PNG, JPEG, WebP or GIF; at most 5 MB each; at most three; a paste or a drop
|
|
8
|
+
* adds the same way the file picker does; ส่ง waits for what is uploading.
|
|
9
|
+
*
|
|
10
|
+
* Kept free of imports: the tests load it straight from source.
|
|
11
|
+
*/
|
|
12
|
+
export declare const HELP_IMAGE_TYPES: readonly ["image/png", "image/jpeg", "image/webp", "image/gif"];
|
|
13
|
+
export declare const HELP_IMAGE_ACCEPT: string;
|
|
14
|
+
export declare const HELP_IMAGE_MAX_BYTES: number;
|
|
15
|
+
export declare const HELP_IMAGE_MAX_COUNT = 3;
|
|
16
|
+
/** The words for each refusal, per file. */
|
|
17
|
+
export declare const HELP_IMAGE_ERRORS: {
|
|
18
|
+
readonly tooLarge: "ใหญ่เกิน 5 MB";
|
|
19
|
+
readonly notImage: "ไม่ใช่ไฟล์รูปภาพ (PNG, JPEG, WebP หรือ GIF)";
|
|
20
|
+
readonly tooMany: "แนบได้ไม่เกิน 3 รูป";
|
|
21
|
+
readonly failed: "อัปโหลดไม่สำเร็จ";
|
|
22
|
+
};
|
|
23
|
+
/** What the rules need to know about a file (a File is one). */
|
|
24
|
+
export interface FileLike {
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly size: number;
|
|
27
|
+
readonly type: string;
|
|
28
|
+
}
|
|
29
|
+
export type AttachStatus = "uploading" | "ready" | "failed";
|
|
30
|
+
export interface AttachItem {
|
|
31
|
+
/** This dialog's own key for the item. */
|
|
32
|
+
key: string;
|
|
33
|
+
name: string;
|
|
34
|
+
size: number;
|
|
35
|
+
/** A URL the thumbnail shows (an object URL of the file). */
|
|
36
|
+
preview: string;
|
|
37
|
+
status: AttachStatus;
|
|
38
|
+
/** 0…1 while uploading. */
|
|
39
|
+
progress: number;
|
|
40
|
+
/** platform-api's upload id, once it has given one. */
|
|
41
|
+
id: string | null;
|
|
42
|
+
error: string | null;
|
|
43
|
+
}
|
|
44
|
+
/** A file that was not added, and why. */
|
|
45
|
+
export interface AttachRejection {
|
|
46
|
+
name: string;
|
|
47
|
+
message: string;
|
|
48
|
+
}
|
|
49
|
+
export interface UploadHooks {
|
|
50
|
+
onProgress(fraction: number): void;
|
|
51
|
+
/** Called as soon as platform-api has named the upload. */
|
|
52
|
+
onId(id: string): void;
|
|
53
|
+
signal: AbortSignal;
|
|
54
|
+
}
|
|
55
|
+
/** Puts one file where platform-api can claim it; resolves when it was checked. */
|
|
56
|
+
export interface HelpUploader {
|
|
57
|
+
upload(file: FileLike, hooks: UploadHooks): Promise<{
|
|
58
|
+
id: string;
|
|
59
|
+
}>;
|
|
60
|
+
/** Forget an upload that will not be sent (best effort). */
|
|
61
|
+
discard?(id: string): void;
|
|
62
|
+
}
|
|
63
|
+
export interface AttachOptions {
|
|
64
|
+
preview?(file: FileLike): string;
|
|
65
|
+
revoke?(url: string): void;
|
|
66
|
+
max?: number;
|
|
67
|
+
}
|
|
68
|
+
/** The declared type, as one of the four, or "". */
|
|
69
|
+
export declare function helpImageType(type: string): string;
|
|
70
|
+
/** Why a file cannot be attached, or null when it can. */
|
|
71
|
+
export declare function checkHelpImage(file: FileLike): string | null;
|
|
72
|
+
interface ClipboardLike {
|
|
73
|
+
readonly files?: ArrayLike<FileLike> | null;
|
|
74
|
+
readonly items?: ArrayLike<{
|
|
75
|
+
kind: string;
|
|
76
|
+
type: string;
|
|
77
|
+
getAsFile(): FileLike | null;
|
|
78
|
+
}> | null;
|
|
79
|
+
getData?(format: string): string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The files a paste carries, when it is a paste of a picture: a screenshot
|
|
83
|
+
* or a copied image. A paste that carries text is text — copying a cell from
|
|
84
|
+
* a spreadsheet also puts a picture of it on the clipboard, and that is not
|
|
85
|
+
* an attachment.
|
|
86
|
+
*/
|
|
87
|
+
export declare function filesFromPaste(data: ClipboardLike | null | undefined): FileLike[];
|
|
88
|
+
interface DataTransferLike {
|
|
89
|
+
readonly files?: ArrayLike<FileLike> | null;
|
|
90
|
+
readonly types?: ArrayLike<string> | null;
|
|
91
|
+
}
|
|
92
|
+
/** True while what is dragged over the dialog includes files. */
|
|
93
|
+
export declare function dragHasFiles(dt: DataTransferLike | null | undefined): boolean;
|
|
94
|
+
/** The files a drop carries. */
|
|
95
|
+
export declare function filesFromDrop(dt: DataTransferLike | null | undefined): FileLike[];
|
|
96
|
+
/**
|
|
97
|
+
* The images being attached to one message. Subscribe to redraw; every
|
|
98
|
+
* change replaces items and rejections with new arrays.
|
|
99
|
+
*/
|
|
100
|
+
export declare class HelpAttachments {
|
|
101
|
+
private list;
|
|
102
|
+
private refused;
|
|
103
|
+
private readonly listeners;
|
|
104
|
+
private readonly running;
|
|
105
|
+
private readonly uploader;
|
|
106
|
+
private readonly opts;
|
|
107
|
+
constructor(uploader: HelpUploader, opts?: AttachOptions);
|
|
108
|
+
get items(): readonly AttachItem[];
|
|
109
|
+
/** The files the last add, paste or drop refused, each with its reason. */
|
|
110
|
+
get rejections(): readonly AttachRejection[];
|
|
111
|
+
get max(): number;
|
|
112
|
+
/** True while any image is still uploading. */
|
|
113
|
+
get uploading(): boolean;
|
|
114
|
+
/** How many more can be added. */
|
|
115
|
+
get room(): number;
|
|
116
|
+
subscribe(fn: () => void): () => void;
|
|
117
|
+
private emit;
|
|
118
|
+
private patch;
|
|
119
|
+
/**
|
|
120
|
+
* Adds files: each is checked, the first ones that fit are uploaded at
|
|
121
|
+
* once, and every one refused is named with its reason.
|
|
122
|
+
*/
|
|
123
|
+
add(files: Iterable<FileLike>): void;
|
|
124
|
+
private start;
|
|
125
|
+
/** Takes an image off: stops its upload and forgets it on the server. */
|
|
126
|
+
remove(key: string): void;
|
|
127
|
+
/** Marks the image platform-api refused on sending (it names it by id). */
|
|
128
|
+
refuse(id: string, message: string): void;
|
|
129
|
+
dismissRejections(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Waits until nothing is uploading, then says what can be sent: the ids
|
|
132
|
+
* of the ready images in the order they are shown, and the ones that
|
|
133
|
+
* failed. ส่ง calls this, so a send never leaves without its images.
|
|
134
|
+
*/
|
|
135
|
+
settled(): Promise<{
|
|
136
|
+
ids: string[];
|
|
137
|
+
failed: AttachItem[];
|
|
138
|
+
}>;
|
|
139
|
+
/**
|
|
140
|
+
* Empties the list. sent: the images went with a message — nothing to
|
|
141
|
+
* forget on the server. Otherwise every upload made is discarded.
|
|
142
|
+
*/
|
|
143
|
+
clear(sent?: boolean): void;
|
|
144
|
+
}
|
|
145
|
+
export {};
|
|
@@ -7,7 +7,9 @@ export interface HelpDialogHostProps {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* The ช่วยเหลือ dialog. AppLayoutShell mounts one; the top-bar button and
|
|
10
|
-
* the user menu open it with openHelp()
|
|
11
|
-
*
|
|
10
|
+
* the user menu open it with openHelp(), and a page address with
|
|
11
|
+
* ?help=H1004 (the ตอบกลับ button in a staff answer) opens it on that
|
|
12
|
+
* message. It sends to platform-api, which puts the message in the back
|
|
13
|
+
* office's queue on admin.antniti.com.
|
|
12
14
|
*/
|
|
13
15
|
export declare function HelpDialogHost({ app, orgCode }: HelpDialogHostProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { HelpAttachments, type AttachItem, type AttachRejection } from "./help-attach";
|
|
3
|
+
import { type HelpImage } from "./help-api";
|
|
4
|
+
import type { HelpAppId } from "./help-store";
|
|
5
|
+
export interface HelpAttachState {
|
|
6
|
+
attach: HelpAttachments;
|
|
7
|
+
items: readonly AttachItem[];
|
|
8
|
+
rejections: readonly AttachRejection[];
|
|
9
|
+
}
|
|
10
|
+
/** One message's images, uploading as they are added. */
|
|
11
|
+
export declare function useHelpAttachments(app: HelpAppId | "other"): HelpAttachState;
|
|
12
|
+
/**
|
|
13
|
+
* Paste and drop for a form that takes images: spread onto the form. A
|
|
14
|
+
* pasted screenshot or a dropped file is added like a picked one.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useHelpImageDrop(attach: HelpAttachments, enabled: boolean): {
|
|
17
|
+
over: boolean;
|
|
18
|
+
props: {
|
|
19
|
+
onPaste: (e: React.ClipboardEvent) => void;
|
|
20
|
+
onDragEnter: (e: React.DragEvent) => void;
|
|
21
|
+
onDragOver: (e: React.DragEvent) => void;
|
|
22
|
+
onDragLeave: (e: React.DragEvent) => void;
|
|
23
|
+
onDrop: (e: React.DragEvent) => void;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export interface HelpAttachFieldProps {
|
|
27
|
+
state: HelpAttachState;
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
/** Ties the hidden file input to the button, for tests and labels. */
|
|
30
|
+
id: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* แนบรูป: the button that opens the file picker (on a phone, the photo
|
|
34
|
+
* library or the camera), the thumbnails with their progress and a remove
|
|
35
|
+
* button each, and a line per file that was refused.
|
|
36
|
+
*/
|
|
37
|
+
export declare function HelpAttachField({ state, disabled, id }: HelpAttachFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
/** Images already sent: thumbnails that open the full image. */
|
|
39
|
+
export declare function HelpImageStrip({ images, size }: {
|
|
40
|
+
images?: HelpImage[];
|
|
41
|
+
size?: "sm" | "md";
|
|
42
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ตอบกลับ link in a staff answer e-mail opens the app with ?help=H1004:
|
|
3
|
+
* the shell's ช่วยเหลือ dialog then opens on that message. Any app page
|
|
4
|
+
* with the shell's layout works; the e-mail uses Platform.
|
|
5
|
+
*
|
|
6
|
+
* Kept free of imports: the tests load it straight from source.
|
|
7
|
+
*/
|
|
8
|
+
export declare const HELP_LINK_PARAM = "help";
|
|
9
|
+
/** The message a page address asks the dialog to open, or null. */
|
|
10
|
+
export declare function helpRefFromSearch(search: string | null | undefined): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* The same address without ?help=, so a reload or a shared link does not
|
|
13
|
+
* open the dialog again. Everything else in it is kept.
|
|
14
|
+
*/
|
|
15
|
+
export declare function withoutHelpParam(href: string): string;
|
|
@@ -8,8 +8,20 @@ export type HelpAppId = "platform" | "accounx" | "invenx" | "plannex" | "peoplx"
|
|
|
8
8
|
/** Opens the dialog — a no-op when no layout has mounted one. */
|
|
9
9
|
export declare function openHelp(): void;
|
|
10
10
|
export declare function closeHelp(): void;
|
|
11
|
-
/**
|
|
11
|
+
/** Opens the dialog on one of the person's messages, by id or "H1004". */
|
|
12
|
+
export declare function openHelpOn(ref: string): void;
|
|
13
|
+
/** The message the dialog was asked to open on, if it has not been left. */
|
|
14
|
+
export declare function pendingHelpRef(): string | null;
|
|
15
|
+
/** The dialog moved on from the message it was opened on. */
|
|
16
|
+
export declare function clearPendingHelpRef(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Called by the dialog host on mount; returns its unmount. A host that
|
|
19
|
+
* mounts while a message is waiting to be shown (a page that mounted its
|
|
20
|
+
* layout twice) opens the dialog again.
|
|
21
|
+
*/
|
|
12
22
|
export declare function registerHelpHost(): () => void;
|
|
23
|
+
/** Whether the dialog is open now (outside React). */
|
|
24
|
+
export declare function isHelpOpen(): boolean;
|
|
13
25
|
export declare function useHelpOpen(): boolean;
|
|
14
26
|
/** True while a dialog host is mounted, i.e. the ช่วยเหลือ entry works. */
|
|
15
27
|
export declare function useHelpAvailable(): boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export { TapMenu } from "./navigation/tap-menu";
|
|
|
14
14
|
export { NavTools } from "./navigation/nav-tools";
|
|
15
15
|
export { AppBreadcrumb } from "./navigation/app-breadcrumb";
|
|
16
16
|
export { NavUser, type NavUserProps, type NavUserSystemLink } from "./navigation/nav-user";
|
|
17
|
+
export { useMyRoles, myRolesQueryKey } from "./navigation/use-my-roles";
|
|
18
|
+
export { parseMyRoles, roleSummary, OWNER_CHIP, type MyRole, type MyRoles, } from "./navigation/my-roles";
|
|
17
19
|
export { buildSystemLinks, type BuildSystemLinksOptions, type ErpAppId, } from "./navigation/app-registry";
|
|
18
20
|
export { PLAN_FEATURES, hasPlanFeature, type PlanFeatureKey, } from "./lib/plan-features";
|
|
19
21
|
export { NavMain, type NavMainProps } from "./navigation/nav-main";
|