@skillcdn/console 0.0.0-stage → 0.1.1
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.md +21 -0
- package/README.md +79 -2
- package/dist/api.d.ts +7 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +11 -0
- package/dist/api.js.map +1 -0
- package/dist/cli/cli.d.ts +34 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +557 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/credentials.d.ts +16 -0
- package/dist/cli/credentials.d.ts.map +1 -0
- package/dist/cli/credentials.js +46 -0
- package/dist/cli/credentials.js.map +1 -0
- package/dist/cli/format.d.ts +16 -0
- package/dist/cli/format.d.ts.map +1 -0
- package/dist/cli/format.js +151 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/help.d.ts +16 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +181 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +32 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/terminal.d.ts +12 -0
- package/dist/cli/terminal.d.ts.map +1 -0
- package/dist/cli/terminal.js +68 -0
- package/dist/cli/terminal.js.map +1 -0
- package/dist/client.d.ts +92 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +117 -0
- package/dist/client.js.map +1 -0
- package/dist/components/board.d.ts +20 -0
- package/dist/components/board.d.ts.map +1 -0
- package/dist/components/board.js +19 -0
- package/dist/components/board.js.map +1 -0
- package/dist/components/decision-form.d.ts +13 -0
- package/dist/components/decision-form.d.ts.map +1 -0
- package/dist/components/decision-form.js +23 -0
- package/dist/components/decision-form.js.map +1 -0
- package/dist/components/decision-list.d.ts +22 -0
- package/dist/components/decision-list.d.ts.map +1 -0
- package/dist/components/decision-list.js +28 -0
- package/dist/components/decision-list.js.map +1 -0
- package/dist/components/event-feed.d.ts +13 -0
- package/dist/components/event-feed.d.ts.map +1 -0
- package/dist/components/event-feed.js +59 -0
- package/dist/components/event-feed.js.map +1 -0
- package/dist/components/markdown.d.ts +4 -0
- package/dist/components/markdown.d.ts.map +1 -0
- package/dist/components/markdown.js +34 -0
- package/dist/components/markdown.js.map +1 -0
- package/dist/components/people.d.ts +11 -0
- package/dist/components/people.d.ts.map +1 -0
- package/dist/components/people.js +7 -0
- package/dist/components/people.js.map +1 -0
- package/dist/components/runs.d.ts +27 -0
- package/dist/components/runs.d.ts.map +1 -0
- package/dist/components/runs.js +45 -0
- package/dist/components/runs.js.map +1 -0
- package/dist/components/shell.d.ts +22 -0
- package/dist/components/shell.d.ts.map +1 -0
- package/dist/components/shell.js +16 -0
- package/dist/components/shell.js.map +1 -0
- package/dist/components/sign-in.d.ts +11 -0
- package/dist/components/sign-in.d.ts.map +1 -0
- package/dist/components/sign-in.js +15 -0
- package/dist/components/sign-in.js.map +1 -0
- package/dist/components/skills.d.ts +7 -0
- package/dist/components/skills.d.ts.map +1 -0
- package/dist/components/skills.js +26 -0
- package/dist/components/skills.js.map +1 -0
- package/dist/components/task-form.d.ts +14 -0
- package/dist/components/task-form.d.ts.map +1 -0
- package/dist/components/task-form.js +34 -0
- package/dist/components/task-form.js.map +1 -0
- package/dist/components/task-view.d.ts +22 -0
- package/dist/components/task-view.d.ts.map +1 -0
- package/dist/components/task-view.js +32 -0
- package/dist/components/task-view.js.map +1 -0
- package/dist/components/tokens.d.ts +26 -0
- package/dist/components/tokens.d.ts.map +1 -0
- package/dist/components/tokens.js +42 -0
- package/dist/components/tokens.js.map +1 -0
- package/dist/components/ui.d.ts +61 -0
- package/dist/components/ui.d.ts.map +1 -0
- package/dist/components/ui.js +109 -0
- package/dist/components/ui.js.map +1 -0
- package/dist/console.css +1382 -0
- package/dist/console.d.ts +44 -0
- package/dist/console.d.ts.map +1 -0
- package/dist/console.js +181 -0
- package/dist/console.js.map +1 -0
- package/dist/data.d.ts +41 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +208 -0
- package/dist/data.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/limits.d.ts +37 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +40 -0
- package/dist/limits.js.map +1 -0
- package/dist/router.d.ts +37 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +55 -0
- package/dist/router.js.map +1 -0
- package/dist/routes.d.ts +47 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +53 -0
- package/dist/routes.js.map +1 -0
- package/dist/schemas.d.ts +789 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +341 -0
- package/dist/schemas.js.map +1 -0
- package/dist/text.d.ts +6 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +31 -0
- package/dist/text.js.map +1 -0
- package/dist/vocabulary.d.ts +35 -0
- package/dist/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary.js +57 -0
- package/dist/vocabulary.js.map +1 -0
- package/package.json +70 -3
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { type RestAnswerInput, type RestArtifactInput, type RestDecision, type RestDecisionInput, type RestDecisions, type RestEvents, type RestMe, type RestPeople, type RestPerson, type RestPersonPatch, type RestReportInput, type RestRun, type RestRunEndInput, type RestRunInput, type RestRuns, type RestSkills, type RestTask, type RestTaskInput, type RestTaskPatch, type RestTasks, type RestTokenCreated, type RestTokenInput, type RestTokens } from "./schemas.js";
|
|
2
|
+
import type { TaskState } from "./vocabulary.js";
|
|
3
|
+
export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
4
|
+
/** A file to hand in: its bytes, what to call it, and what it is. */
|
|
5
|
+
export interface FileUpload {
|
|
6
|
+
/** The file's name, without a path. */
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly bytes: Uint8Array | Blob;
|
|
9
|
+
/** The media type; `application/octet-stream` when left out. */
|
|
10
|
+
readonly contentType?: string | undefined;
|
|
11
|
+
readonly label?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface ClientOptions {
|
|
14
|
+
/** The origin of the console, without a path. Empty: the origin of the page. */
|
|
15
|
+
readonly baseUrl?: string;
|
|
16
|
+
/** The platform's `fetch` when left out. Tests hand in one that never leaves the process. */
|
|
17
|
+
readonly fetch?: FetchLike;
|
|
18
|
+
/**
|
|
19
|
+
* A token a person made, for an agent, a script or a console of their own: sent as
|
|
20
|
+
* `Authorization: Bearer`, and the browser's cookies left out. Left out, the session cookie of
|
|
21
|
+
* the page's own origin is what the console answers to.
|
|
22
|
+
*/
|
|
23
|
+
readonly token?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class ApiError extends Error {
|
|
26
|
+
/** HTTP status, or 0 when there was no response at all. */
|
|
27
|
+
readonly status: number;
|
|
28
|
+
/** The stable code from the error body, `network` or `invalid_response`. */
|
|
29
|
+
readonly code: string;
|
|
30
|
+
constructor(status: number, code: string, message: string);
|
|
31
|
+
}
|
|
32
|
+
export interface ConsoleClient {
|
|
33
|
+
me(signal?: AbortSignal): Promise<RestMe>;
|
|
34
|
+
people(signal?: AbortSignal): Promise<RestPeople>;
|
|
35
|
+
/** Changes what a person is; for an administrator. */
|
|
36
|
+
updatePerson(id: string, patch: RestPersonPatch): Promise<RestPerson>;
|
|
37
|
+
tasks(filter?: {
|
|
38
|
+
readonly state?: TaskState;
|
|
39
|
+
}, signal?: AbortSignal): Promise<RestTasks>;
|
|
40
|
+
/** One task, by its id or by its number. */
|
|
41
|
+
task(ref: string, signal?: AbortSignal): Promise<RestTask>;
|
|
42
|
+
createTask(input: RestTaskInput): Promise<RestTask>;
|
|
43
|
+
updateTask(id: string, patch: RestTaskPatch): Promise<RestTask>;
|
|
44
|
+
/** The decisions, or only those that wait, or only those about one task. */
|
|
45
|
+
decisions(filter?: {
|
|
46
|
+
readonly open?: boolean;
|
|
47
|
+
readonly task?: string;
|
|
48
|
+
}, signal?: AbortSignal): Promise<RestDecisions>;
|
|
49
|
+
decision(id: string, signal?: AbortSignal): Promise<RestDecision>;
|
|
50
|
+
/**
|
|
51
|
+
* One decision, after waiting up to `waitSeconds` for its answer: the server holds the request
|
|
52
|
+
* while the decision waits, for as long as it allows, and answers the decision as it stands.
|
|
53
|
+
*/
|
|
54
|
+
awaitDecision(id: string, waitSeconds: number, signal?: AbortSignal): Promise<RestDecision>;
|
|
55
|
+
raiseDecision(input: RestDecisionInput): Promise<RestDecision>;
|
|
56
|
+
answerDecision(id: string, input: RestAnswerInput): Promise<RestDecision>;
|
|
57
|
+
/** The runs, newest first; or only those on one task, only the open ones, only the asker's own. */
|
|
58
|
+
runs(filter?: {
|
|
59
|
+
readonly task?: string;
|
|
60
|
+
readonly open?: boolean;
|
|
61
|
+
readonly mine?: boolean;
|
|
62
|
+
}, signal?: AbortSignal): Promise<RestRuns>;
|
|
63
|
+
run(id: string, signal?: AbortSignal): Promise<RestRun>;
|
|
64
|
+
/** Takes a task: a run begins, for the person the asker is or acts for. */
|
|
65
|
+
startRun(input: RestRunInput): Promise<RestRun>;
|
|
66
|
+
/** Says how the work goes, on a run of the asker's. */
|
|
67
|
+
report(runId: string, input: RestReportInput): Promise<RestRun>;
|
|
68
|
+
/** Hands in a link, on a run of the asker's. */
|
|
69
|
+
handIn(runId: string, input: RestArtifactInput): Promise<RestRun>;
|
|
70
|
+
/** Hands in a file, on a run of the asker's: the console keeps the bytes. */
|
|
71
|
+
handInFile(runId: string, input: FileUpload): Promise<RestRun>;
|
|
72
|
+
/** Where the bytes of a file handed in are read, by the artifact's id. */
|
|
73
|
+
fileUrl(artifactId: string): string;
|
|
74
|
+
/** Ends a run: finished or failed by the agent; abandoned by the person it is for, or an administrator. */
|
|
75
|
+
endRun(runId: string, input: RestRunEndInput): Promise<RestRun>;
|
|
76
|
+
/** What happened after event number `after`; `0` for the beginning. */
|
|
77
|
+
events(after: number, signal?: AbortSignal): Promise<RestEvents>;
|
|
78
|
+
/** Where an `EventSource` subscribes to what happens after event number `after`. */
|
|
79
|
+
eventStreamUrl(after: number): string;
|
|
80
|
+
/** The organization's skills, as SkillCDN serves them at the console's address. */
|
|
81
|
+
skills(signal?: AbortSignal): Promise<RestSkills>;
|
|
82
|
+
/** The tokens of whoever asks. */
|
|
83
|
+
tokens(signal?: AbortSignal): Promise<RestTokens>;
|
|
84
|
+
/** Makes a token; the answer carries the secret, this once. */
|
|
85
|
+
createToken(input: RestTokenInput): Promise<RestTokenCreated>;
|
|
86
|
+
/** Takes a token away, whoever holds it. */
|
|
87
|
+
revokeToken(id: string): Promise<void>;
|
|
88
|
+
/** Ends the session on this browser. */
|
|
89
|
+
signOut(): Promise<void>;
|
|
90
|
+
}
|
|
91
|
+
export declare function createClient(options?: ClientOptions): ConsoleClient;
|
|
92
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,UAAU,EAehB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAOjD,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEjF,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAClC,gEAAgE;IAChE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAKxD;CACF;AAMD,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAClD,sDAAsD;IACtD,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtE,KAAK,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;KAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACzF,4CAA4C;IAC5C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChE,4EAA4E;IAC5E,SAAS,CACP,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAC5D,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClE;;;OAGG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5F,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/D,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1E,mGAAmG;IACnG,IAAI,CACF,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,EACrF,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,uDAAuD;IACvD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE,gDAAgD;IAChD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,6EAA6E;IAC7E,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,0EAA0E;IAC1E,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,2GAA2G;IAC3G,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE,uEAAuE;IACvE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACjE,oFAAoF;IACpF,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,mFAAmF;IACnF,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAClD,kCAAkC;IAClC,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAClD,+DAA+D;IAC/D,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9D,4CAA4C;IAC5C,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,wCAAwC;IACxC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAID,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,aAAa,CAsKvE"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { AUTH_ROUTES, REST_ROUTES, restPath } from "./routes.js";
|
|
2
|
+
import { restDecisionSchema, restDecisionsSchema, restErrorSchema, restEventsSchema, restMeSchema, restPeopleSchema, restPersonSchema, restRunSchema, restRunsSchema, restSkillsSchema, restTaskSchema, restTasksSchema, restTokenCreatedSchema, restTokensSchema, } from "./schemas.js";
|
|
3
|
+
export class ApiError extends Error {
|
|
4
|
+
/** HTTP status, or 0 when there was no response at all. */
|
|
5
|
+
status;
|
|
6
|
+
/** The stable code from the error body, `network` or `invalid_response`. */
|
|
7
|
+
code;
|
|
8
|
+
constructor(status, code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "ApiError";
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.code = code;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const INVALID = "The server answered unexpectedly.";
|
|
16
|
+
export function createClient(options = {}) {
|
|
17
|
+
const base = (options.baseUrl ?? "").replace(/\/+$/, "");
|
|
18
|
+
const send = options.fetch ?? ((input, init) => fetch(input, init));
|
|
19
|
+
const { token } = options;
|
|
20
|
+
const withQuery = (path, params) => {
|
|
21
|
+
const query = new URLSearchParams();
|
|
22
|
+
for (const [name, value] of Object.entries(params)) {
|
|
23
|
+
if (value !== undefined) {
|
|
24
|
+
query.set(name, value);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return query.size === 0 ? `${base}${path}` : `${base}${path}?${query}`;
|
|
28
|
+
};
|
|
29
|
+
/** What a response says when it is not what was asked for. */
|
|
30
|
+
const failure = async (response) => {
|
|
31
|
+
const parsed = restErrorSchema.safeParse(await response.json().catch(() => undefined));
|
|
32
|
+
return parsed.success
|
|
33
|
+
? new ApiError(response.status, parsed.data.error.code, parsed.data.error.message)
|
|
34
|
+
: new ApiError(response.status, "invalid_response", INVALID);
|
|
35
|
+
};
|
|
36
|
+
const request = async (method, url, body, schema, signal) => {
|
|
37
|
+
const form = body instanceof FormData;
|
|
38
|
+
let response;
|
|
39
|
+
try {
|
|
40
|
+
response = await send(url, {
|
|
41
|
+
method,
|
|
42
|
+
...(signal === undefined ? {} : { signal }),
|
|
43
|
+
// Same origin, so the session cookie goes with it; the browser names the origin of a
|
|
44
|
+
// request that changes something, which the server checks. With a token, the token is
|
|
45
|
+
// the credential and no cookie travels.
|
|
46
|
+
credentials: token === undefined ? "same-origin" : "omit",
|
|
47
|
+
headers: {
|
|
48
|
+
accept: "application/json",
|
|
49
|
+
// A form names its own type, boundary included; everything else is JSON.
|
|
50
|
+
...(body === undefined || form ? {} : { "content-type": "application/json" }),
|
|
51
|
+
...(token === undefined ? {} : { authorization: `Bearer ${token}` }),
|
|
52
|
+
},
|
|
53
|
+
...(body === undefined ? {} : { body: form ? body : JSON.stringify(body) }),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (signal?.aborted === true) {
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
throw new ApiError(0, "network", "The server could not be reached.");
|
|
61
|
+
}
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
throw await failure(response);
|
|
64
|
+
}
|
|
65
|
+
if (schema === undefined) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const parsed = schema.safeParse(await response.json().catch(() => undefined));
|
|
69
|
+
if (!parsed.success) {
|
|
70
|
+
throw new ApiError(response.status, "invalid_response", INVALID);
|
|
71
|
+
}
|
|
72
|
+
return parsed.data;
|
|
73
|
+
};
|
|
74
|
+
const flag = (value) => value === undefined ? undefined : String(value);
|
|
75
|
+
return {
|
|
76
|
+
me: (signal) => request("GET", `${base}${REST_ROUTES.me}`, undefined, restMeSchema, signal),
|
|
77
|
+
people: (signal) => request("GET", `${base}${REST_ROUTES.people}`, undefined, restPeopleSchema, signal),
|
|
78
|
+
updatePerson: (id, patch) => request("PATCH", `${base}${restPath("people", id)}`, patch, restPersonSchema),
|
|
79
|
+
tasks: (filter = {}, signal) => request("GET", withQuery(REST_ROUTES.tasks, { state: filter.state }), undefined, restTasksSchema, signal),
|
|
80
|
+
task: (ref, signal) => request("GET", `${base}${restPath("tasks", ref)}`, undefined, restTaskSchema, signal),
|
|
81
|
+
createTask: (input) => request("POST", `${base}${REST_ROUTES.tasks}`, input, restTaskSchema),
|
|
82
|
+
updateTask: (id, patch) => request("PATCH", `${base}${restPath("tasks", id)}`, patch, restTaskSchema),
|
|
83
|
+
decisions: (filter = {}, signal) => request("GET", withQuery(REST_ROUTES.decisions, { open: flag(filter.open), task: filter.task }), undefined, restDecisionsSchema, signal),
|
|
84
|
+
decision: (id, signal) => request("GET", `${base}${restPath("decisions", id)}`, undefined, restDecisionSchema, signal),
|
|
85
|
+
awaitDecision: (id, waitSeconds, signal) => request("GET", withQuery(restPath("decisions", id), { wait: String(waitSeconds) }), undefined, restDecisionSchema, signal),
|
|
86
|
+
raiseDecision: (input) => request("POST", `${base}${REST_ROUTES.decisions}`, input, restDecisionSchema),
|
|
87
|
+
answerDecision: (id, input) => request("POST", `${base}${restPath("decisions", id)}/answer`, input, restDecisionSchema),
|
|
88
|
+
runs: (filter = {}, signal) => request("GET", withQuery(REST_ROUTES.runs, {
|
|
89
|
+
task: filter.task,
|
|
90
|
+
open: flag(filter.open),
|
|
91
|
+
mine: flag(filter.mine),
|
|
92
|
+
}), undefined, restRunsSchema, signal),
|
|
93
|
+
run: (id, signal) => request("GET", `${base}${restPath("runs", id)}`, undefined, restRunSchema, signal),
|
|
94
|
+
startRun: (input) => request("POST", `${base}${REST_ROUTES.runs}`, input, restRunSchema),
|
|
95
|
+
report: (runId, input) => request("POST", `${base}${restPath("runs", runId)}/reports`, input, restRunSchema),
|
|
96
|
+
handIn: (runId, input) => request("POST", `${base}${restPath("runs", runId)}/artifacts`, input, restRunSchema),
|
|
97
|
+
handInFile: (runId, input) => {
|
|
98
|
+
const form = new FormData();
|
|
99
|
+
const bytes = input.bytes instanceof Blob ? input.bytes : new Blob([Uint8Array.from(input.bytes)]);
|
|
100
|
+
form.set("file", new File([bytes], input.name, { type: input.contentType ?? "application/octet-stream" }), input.name);
|
|
101
|
+
if (input.label !== undefined) {
|
|
102
|
+
form.set("label", input.label);
|
|
103
|
+
}
|
|
104
|
+
return request("POST", `${base}${restPath("runs", runId)}/files`, form, restRunSchema);
|
|
105
|
+
},
|
|
106
|
+
fileUrl: (artifactId) => `${base}${restPath("files", artifactId)}`,
|
|
107
|
+
endRun: (runId, input) => request("POST", `${base}${restPath("runs", runId)}/end`, input, restRunSchema),
|
|
108
|
+
events: (after, signal) => request("GET", withQuery(REST_ROUTES.events, { after: String(after) }), undefined, restEventsSchema, signal),
|
|
109
|
+
eventStreamUrl: (after) => withQuery(`${REST_ROUTES.events}/stream`, { after: String(after) }),
|
|
110
|
+
skills: (signal) => request("GET", `${base}${REST_ROUTES.skills}`, undefined, restSkillsSchema, signal),
|
|
111
|
+
tokens: (signal) => request("GET", `${base}${REST_ROUTES.tokens}`, undefined, restTokensSchema, signal),
|
|
112
|
+
createToken: (input) => request("POST", `${base}${REST_ROUTES.tokens}`, input, restTokenCreatedSchema),
|
|
113
|
+
revokeToken: (id) => request("DELETE", `${base}${restPath("tokens", id)}`, undefined, undefined),
|
|
114
|
+
signOut: () => request("POST", `${base}${AUTH_ROUTES.logout}`, undefined, undefined),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAwBL,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAiCtB,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,2DAA2D;IAClD,MAAM,CAAS;IACxB,4EAA4E;IACnE,IAAI,CAAS;IAEtB,YAAY,MAAc,EAAE,IAAY,EAAE,OAAe;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AA+DD,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,OAAO,GAAkB,EAAE;IACtD,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACpE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE1B,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,MAA0C,EAAU,EAAE;QACrF,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;IACzE,CAAC,CAAC;IAEF,8DAA8D;IAC9D,MAAM,OAAO,GAAG,KAAK,EAAE,QAAkB,EAAqB,EAAE;QAC9D,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACvF,OAAO,MAAM,CAAC,OAAO;YACnB,CAAC,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAClF,CAAC,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,EACnB,MAA2C,EAC3C,GAAW,EACX,IAAa,EACb,MAA6B,EAC7B,MAAoB,EACR,EAAE;QACd,MAAM,IAAI,GAAG,IAAI,YAAY,QAAQ,CAAC;QACtC,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE;gBACzB,MAAM;gBACN,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;gBAC3C,qFAAqF;gBACrF,sFAAsF;gBACtF,wCAAwC;gBACxC,WAAW,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM;gBACzD,OAAO,EAAE;oBACP,MAAM,EAAE,kBAAkB;oBAC1B,yEAAyE;oBACzE,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;oBAC7E,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;iBACrE;gBACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;aAC5E,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC7B,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,kCAAkC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,SAAc,CAAC;QACxB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,CAAC,KAA0B,EAAsB,EAAE,CAC9D,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAElD,OAAO;QACL,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC;QAC3F,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CACjB,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,CAAC;QACrF,YAAY,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAC1B,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,gBAAgB,CAAC;QAC/E,KAAK,EAAE,CAAC,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,CAC7B,OAAO,CACL,KAAK,EACL,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EACrD,SAAS,EACT,eAAe,EACf,MAAM,CACP;QACH,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CACpB,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,CAAC;QACvF,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC;QAC5F,UAAU,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CACxB,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC;QAC5E,SAAS,EAAE,CAAC,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,CACjC,OAAO,CACL,KAAK,EACL,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAChF,SAAS,EACT,mBAAmB,EACnB,MAAM,CACP;QACH,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CACvB,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,CAAC;QAC9F,aAAa,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CACzC,OAAO,CACL,KAAK,EACL,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,EACnE,SAAS,EACT,kBAAkB,EAClB,MAAM,CACP;QACH,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CACvB,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,kBAAkB,CAAC;QAC/E,cAAc,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAC5B,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,kBAAkB,CAAC;QAC1F,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,CAC5B,OAAO,CACL,KAAK,EACL,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE;YAC1B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACvB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;SACxB,CAAC,EACF,SAAS,EACT,cAAc,EACd,MAAM,CACP;QACH,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAClB,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,CAAC;QACpF,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC;QACxF,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACvB,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,CAAC;QACpF,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACvB,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,aAAa,CAAC;QACtF,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC3B,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,KAAK,GACT,KAAK,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACvF,IAAI,CAAC,GAAG,CACN,MAAM,EACN,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,IAAI,0BAA0B,EAAE,CAAC,EACxF,KAAK,CAAC,IAAI,CACX,CAAC;YACF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;QACzF,CAAC;QACD,OAAO,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE;QAClE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACvB,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC;QAChF,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CACxB,OAAO,CACL,KAAK,EACL,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EACvD,SAAS,EACT,gBAAgB,EAChB,MAAM,CACP;QACH,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,WAAW,CAAC,MAAM,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9F,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CACjB,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,CAAC;QACrF,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CACjB,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,CAAC;QACrF,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CACrB,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,sBAAsB,CAAC;QAChF,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAClB,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC;QAC7E,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC;KACrF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type RestTask, type TaskState } from "../api.js";
|
|
3
|
+
export interface BoardProps {
|
|
4
|
+
readonly tasks: readonly RestTask[];
|
|
5
|
+
/** The link to a task's own page, as the composition routes it. */
|
|
6
|
+
readonly taskHref: (task: RestTask) => string;
|
|
7
|
+
readonly onOpen: (task: RestTask) => void;
|
|
8
|
+
/** Called when a person moves a task to another column. Left out, the board is read-only. */
|
|
9
|
+
readonly onMove?: ((task: RestTask, state: TaskState) => void) | undefined;
|
|
10
|
+
/** What a column shows when it has nothing; the way to write the first task, for example. */
|
|
11
|
+
readonly empty?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export declare function TaskCard(props: {
|
|
14
|
+
readonly task: RestTask;
|
|
15
|
+
readonly href: string;
|
|
16
|
+
readonly onOpen: (task: RestTask) => void;
|
|
17
|
+
readonly onMove?: ((task: RestTask, state: TaskState) => void) | undefined;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
19
|
+
export declare function Board(props: BoardProps): import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=board.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../../src/components/board.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,KAAK,QAAQ,EAAe,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAMvE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3E,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC5E,+BAqDA;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,+BAgCtC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TASK_STATES } from "../api.js";
|
|
3
|
+
import { Avatar, Badge, cx, PriorityBadge, STATE_LABELS } from "./ui.js";
|
|
4
|
+
export function TaskCard(props) {
|
|
5
|
+
const { task } = props;
|
|
6
|
+
return (_jsxs("article", { className: "sc-card", "aria-label": `#${task.number} ${task.title}`, children: [_jsxs("a", { className: "sc-card-title", href: props.href, onClick: (event) => {
|
|
7
|
+
if (event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey) {
|
|
8
|
+
event.preventDefault();
|
|
9
|
+
props.onOpen(task);
|
|
10
|
+
}
|
|
11
|
+
}, children: [_jsxs("span", { className: "sc-card-number", children: ["#", task.number] }), " ", task.title] }), _jsxs("div", { className: "sc-card-meta", children: [_jsx(PriorityBadge, { priority: task.priority }), task.openDecisions > 0 && (_jsx(Badge, { tone: "warning", title: "Decisions waiting for a person", children: task.openDecisions === 1 ? "1 decision" : `${task.openDecisions} decisions` })), task.openRuns > 0 && (_jsx(Badge, { tone: "accent", title: "An agent is at work on it", children: "agent at work" })), task.links.length > 0 && (_jsx(Badge, { tone: "neutral", children: task.links.length === 1 ? "1 link" : `${task.links.length} links` })), _jsx("span", { className: "sc-card-spacer" }), task.assignee !== null && _jsx(Avatar, { person: task.assignee, size: "sm" })] }), props.onMove !== undefined && (_jsxs("label", { className: "sc-card-move", children: [_jsx("span", { className: "sc-visually-hidden", children: "Move to" }), _jsx("select", { value: task.state, onChange: (event) => props.onMove?.(task, event.target.value), children: TASK_STATES.map((state) => (_jsx("option", { value: state, children: STATE_LABELS[state] }, state))) })] }))] }));
|
|
12
|
+
}
|
|
13
|
+
export function Board(props) {
|
|
14
|
+
return (_jsx("div", { className: "sc-board", children: TASK_STATES.map((state) => {
|
|
15
|
+
const tasks = props.tasks.filter((task) => task.state === state);
|
|
16
|
+
return (_jsxs("section", { className: cx("sc-column", `sc-column-${state}`), "aria-label": STATE_LABELS[state], children: [_jsxs("header", { className: "sc-column-header", children: [_jsx("h2", { className: "sc-column-title", children: STATE_LABELS[state] }), _jsx("span", { className: "sc-column-count", children: tasks.length })] }), _jsxs("div", { className: "sc-column-body", children: [tasks.map((task) => (_jsx(TaskCard, { task: task, href: props.taskHref(task), onOpen: props.onOpen, onMove: props.onMove }, task.id))), tasks.length === 0 && state === "idea" && props.empty] })] }, state));
|
|
17
|
+
}) }));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=board.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.js","sourceRoot":"","sources":["../../src/components/board.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RestDecisionInput, type RestTask } from "../api.js";
|
|
2
|
+
export interface DecisionFormProps {
|
|
3
|
+
/** The tasks the decision may be about. */
|
|
4
|
+
readonly tasks: readonly RestTask[];
|
|
5
|
+
/** The task it is about from the start, when raised from a task's page. */
|
|
6
|
+
readonly taskId?: string | undefined;
|
|
7
|
+
readonly busy?: boolean | undefined;
|
|
8
|
+
readonly error?: string | undefined;
|
|
9
|
+
readonly onSubmit: (input: RestDecisionInput) => void;
|
|
10
|
+
readonly onCancel?: (() => void) | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function DecisionForm(props: DecisionFormProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=decision-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-form.d.ts","sourceRoot":"","sources":["../../src/components/decision-form.tsx"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACd,MAAM,WAAW,CAAC;AAKnB,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC9C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BA2GpD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { MAX_BODY_LENGTH, MAX_OPTION_LABEL_LENGTH, MAX_OPTIONS, MAX_QUESTION_LENGTH, MIN_OPTIONS, } from "../api.js";
|
|
4
|
+
import { Button } from "./ui.js";
|
|
5
|
+
export function DecisionForm(props) {
|
|
6
|
+
const [question, setQuestion] = useState("");
|
|
7
|
+
const [body, setBody] = useState("");
|
|
8
|
+
const [taskId, setTaskId] = useState(props.taskId ?? "");
|
|
9
|
+
const [options, setOptions] = useState(["", ""]);
|
|
10
|
+
const labels = options.map((option) => option.trim()).filter((option) => option.length > 0);
|
|
11
|
+
const ready = question.trim().length > 0 && labels.length >= MIN_OPTIONS;
|
|
12
|
+
const submit = (event) => {
|
|
13
|
+
event.preventDefault();
|
|
14
|
+
props.onSubmit({
|
|
15
|
+
question: question.trim(),
|
|
16
|
+
body,
|
|
17
|
+
options: labels.map((label) => ({ label })),
|
|
18
|
+
taskId: taskId === "" ? null : taskId,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs("form", { className: "sc-form", onSubmit: submit, children: [_jsxs("label", { className: "sc-field", children: [_jsx("span", { className: "sc-field-label", children: "Question" }), _jsx("input", { className: "sc-input", value: question, maxLength: MAX_QUESTION_LENGTH, required: true, onChange: (event) => setQuestion(event.target.value) })] }), _jsxs("label", { className: "sc-field", children: [_jsx("span", { className: "sc-field-label", children: "Context" }), _jsx("textarea", { className: "sc-input sc-textarea", value: body, maxLength: MAX_BODY_LENGTH, rows: 4, placeholder: "What a person needs to know to answer, in Markdown.", onChange: (event) => setBody(event.target.value) })] }), props.taskId === undefined && props.tasks.length > 0 && (_jsxs("label", { className: "sc-field", children: [_jsx("span", { className: "sc-field-label", children: "About" }), _jsxs("select", { className: "sc-input", value: taskId, onChange: (event) => setTaskId(event.target.value), children: [_jsx("option", { value: "", children: "No task in particular" }), props.tasks.map((task) => (_jsxs("option", { value: task.id, children: ["#", task.number, " ", task.title] }, task.id)))] })] })), _jsxs("fieldset", { className: "sc-field sc-options", children: [_jsx("legend", { className: "sc-field-label", children: "Options" }), options.map((option, index) => (_jsxs("div", { className: "sc-link-row", children: [_jsx("input", { className: "sc-input", value: option, maxLength: MAX_OPTION_LABEL_LENGTH, placeholder: `Option ${index + 1}`, onChange: (event) => setOptions(options.map((entry, at) => (at === index ? event.target.value : entry))) }), options.length > MIN_OPTIONS && (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setOptions(options.filter((_, at) => at !== index)), children: "Remove" }))] }, index))), options.length < MAX_OPTIONS && (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setOptions([...options, ""]), children: "Add an option" }))] }), props.error !== undefined && (_jsx("p", { className: "sc-form-error", role: "alert", children: props.error })), _jsxs("div", { className: "sc-form-actions", children: [_jsx(Button, { type: "submit", variant: "primary", disabled: props.busy === true || !ready, children: "Raise the decision" }), props.onCancel !== undefined && (_jsx(Button, { variant: "ghost", onClick: props.onCancel, children: "Cancel" }))] })] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=decision-form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-form.js","sourceRoot":"","sources":["../../src/components/decision-form.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,WAAW,GAGZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAejC,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAoB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,WAAW,CAAC;IAEzE,MAAM,MAAM,GAAG,CAAC,KAAgB,EAAE,EAAE;QAClC,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,QAAQ,CAAC;YACb,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;YACzB,IAAI;YACJ,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3C,MAAM,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;SACtC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,CACL,gBAAM,SAAS,EAAC,SAAS,EAAC,QAAQ,EAAE,MAAM,aACxC,iBAAO,SAAS,EAAC,UAAU,aACzB,eAAM,SAAS,EAAC,gBAAgB,yBAAgB,EAChD,gBACE,SAAS,EAAC,UAAU,EACpB,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,mBAAmB,EAC9B,QAAQ,QACR,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GACpD,IACI,EACR,iBAAO,SAAS,EAAC,UAAU,aACzB,eAAM,SAAS,EAAC,gBAAgB,wBAAe,EAC/C,mBACE,SAAS,EAAC,sBAAsB,EAChC,KAAK,EAAE,IAAI,EACX,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,CAAC,EACP,WAAW,EAAC,qDAAqD,EACjE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAChD,IACI,EACP,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CACvD,iBAAO,SAAS,EAAC,UAAU,aACzB,eAAM,SAAS,EAAC,gBAAgB,sBAAa,EAC7C,kBACE,SAAS,EAAC,UAAU,EACpB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,aAElD,iBAAQ,KAAK,EAAC,EAAE,sCAA+B,EAC9C,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzB,kBAAsB,KAAK,EAAE,IAAI,CAAC,EAAE,kBAChC,IAAI,CAAC,MAAM,OAAG,IAAI,CAAC,KAAK,KADf,IAAI,CAAC,EAAE,CAEX,CACV,CAAC,IACK,IACH,CACT,EACD,oBAAU,SAAS,EAAC,qBAAqB,aACvC,iBAAQ,SAAS,EAAC,gBAAgB,wBAAiB,EAClD,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAE9B,eAAiB,SAAS,EAAC,aAAa,aACtC,gBACE,SAAS,EAAC,UAAU,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,uBAAuB,EAClC,WAAW,EAAE,UAAU,KAAK,GAAG,CAAC,EAAE,EAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAErF,EACD,OAAO,CAAC,MAAM,GAAG,WAAW,IAAI,CAC/B,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,uBAG3D,CACV,KAlBO,KAAK,CAmBT,CACP,CAAC,EACD,OAAO,CAAC,MAAM,GAAG,WAAW,IAAI,CAC/B,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,CAAC,CAAC,8BAEpE,CACV,IACQ,EACV,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,CAC5B,YAAG,SAAS,EAAC,eAAe,EAAC,IAAI,EAAC,OAAO,YACtC,KAAK,CAAC,KAAK,GACV,CACL,EACD,eAAK,SAAS,EAAC,iBAAiB,aAC9B,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,SAAS,EAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK,mCAEtE,EACR,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,CAC/B,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,uBAEtC,CACV,IACG,IACD,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type RestAnswerInput, type RestDecision, type RestTask } from "../api.js";
|
|
2
|
+
export interface DecisionCardProps {
|
|
3
|
+
readonly decision: RestDecision;
|
|
4
|
+
/** The task the decision is about, when it is about one and the page knows it. */
|
|
5
|
+
readonly task?: RestTask | undefined;
|
|
6
|
+
readonly taskHref?: ((task: RestTask) => string) | undefined;
|
|
7
|
+
/** Called with the person's answer. Left out, a waiting decision cannot be answered here. */
|
|
8
|
+
readonly onAnswer?: ((decision: RestDecision, input: RestAnswerInput) => void) | undefined;
|
|
9
|
+
readonly busy?: boolean | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function DecisionCard(props: DecisionCardProps): import("react").JSX.Element;
|
|
12
|
+
export interface DecisionListProps {
|
|
13
|
+
readonly decisions: readonly RestDecision[];
|
|
14
|
+
/** The tasks the decisions may be about, by id, for the cards to name them. */
|
|
15
|
+
readonly tasks: ReadonlyMap<string, RestTask>;
|
|
16
|
+
readonly taskHref?: ((task: RestTask) => string) | undefined;
|
|
17
|
+
readonly onAnswer?: ((decision: RestDecision, input: RestAnswerInput) => void) | undefined;
|
|
18
|
+
readonly busy?: boolean | undefined;
|
|
19
|
+
readonly empty?: React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
export declare function DecisionList(props: DecisionListProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=decision-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-list.d.ts","sourceRoot":"","sources":["../../src/components/decision-list.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAOpG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,kFAAkF;IAClF,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;IAC7D,6FAA6F;IAC7F,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3F,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BAiGpD;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,YAAY,EAAE,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3F,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAClC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BA+BpD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { MAX_NOTE_LENGTH } from "../api.js";
|
|
4
|
+
import { Markdown } from "./markdown.js";
|
|
5
|
+
import { Button, cx, PersonChip, Time } from "./ui.js";
|
|
6
|
+
export function DecisionCard(props) {
|
|
7
|
+
const { decision, task } = props;
|
|
8
|
+
const [chosen, setChosen] = useState(undefined);
|
|
9
|
+
const [note, setNote] = useState("");
|
|
10
|
+
const answered = decision.answer !== null;
|
|
11
|
+
const chosenLabel = (id) => decision.options.find((option) => option.id === id)?.label ?? id;
|
|
12
|
+
return (_jsxs("article", { className: cx("sc-decision", answered && "sc-decision-answered"), children: [_jsxs("header", { className: "sc-decision-header", children: [_jsx("h3", { className: "sc-decision-question", children: decision.question }), _jsxs("p", { className: "sc-decision-meta", children: [_jsx(PersonChip, { person: decision.raisedBy }), " ", decision.run === null ? "asked" : `asked through ${decision.run.agent}`, " ", _jsx(Time, { iso: decision.createdAt }), task !== undefined && (_jsxs(_Fragment, { children: [" ", "about", " ", props.taskHref === undefined ? (_jsxs("span", { children: ["#", task.number, " ", task.title] })) : (_jsxs("a", { href: props.taskHref(task), children: ["#", task.number, " ", task.title] }))] }))] })] }), decision.body.length > 0 && _jsx(Markdown, { source: decision.body }), decision.answer !== null ? (_jsxs("div", { className: "sc-answer", children: [_jsx("p", { className: "sc-answer-option", children: chosenLabel(decision.answer.option) }), decision.answer.note !== null && (_jsx("p", { className: "sc-answer-note", children: decision.answer.note })), _jsxs("p", { className: "sc-decision-meta", children: [_jsx(PersonChip, { person: decision.answer.by }), " answered ", _jsx(Time, { iso: decision.answer.at })] })] })) : props.onAnswer === undefined ? (_jsx("p", { className: "sc-decision-waiting", children: "Waiting for a person." })) : (_jsxs("form", { className: "sc-answer-form", onSubmit: (event) => {
|
|
13
|
+
event.preventDefault();
|
|
14
|
+
if (chosen !== undefined) {
|
|
15
|
+
props.onAnswer?.(decision, {
|
|
16
|
+
option: chosen,
|
|
17
|
+
...(note.trim() === "" ? {} : { note: note.trim() }),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}, children: [_jsx("div", { className: "sc-options-list", role: "radiogroup", "aria-label": "Options", children: decision.options.map((option) => (_jsxs("label", { className: cx("sc-option", chosen === option.id && "sc-option-chosen"), children: [_jsx("input", { type: "radio", name: `decision-${decision.id}`, value: option.id, checked: chosen === option.id, onChange: () => setChosen(option.id) }), _jsx("span", { children: option.label })] }, option.id))) }), _jsx("input", { className: "sc-input", placeholder: "A word about it, if any", maxLength: MAX_NOTE_LENGTH, value: note, onChange: (event) => setNote(event.target.value) }), _jsx("div", { className: "sc-form-actions", children: _jsx(Button, { type: "submit", variant: "primary", size: "sm", disabled: chosen === undefined || props.busy === true, children: "Answer" }) })] }))] }));
|
|
21
|
+
}
|
|
22
|
+
export function DecisionList(props) {
|
|
23
|
+
const waiting = props.decisions.filter((decision) => decision.answer === null);
|
|
24
|
+
const answered = props.decisions.filter((decision) => decision.answer !== null);
|
|
25
|
+
const card = (decision) => (_jsx(DecisionCard, { decision: decision, task: decision.taskId === null ? undefined : props.tasks.get(decision.taskId), taskHref: props.taskHref, onAnswer: props.onAnswer, busy: props.busy }, decision.id));
|
|
26
|
+
return (_jsxs("div", { className: "sc-decisions", children: [_jsxs("section", { "aria-label": "Waiting", children: [_jsxs("h2", { className: "sc-section-title", children: ["Waiting ", _jsx("span", { className: "sc-column-count", children: waiting.length })] }), waiting.length === 0 ? (props.empty ?? null) : waiting.map(card)] }), answered.length > 0 && (_jsxs("section", { "aria-label": "Answered", children: [_jsxs("h2", { className: "sc-section-title", children: ["Answered ", _jsx("span", { className: "sc-column-count", children: answered.length })] }), answered.map(card)] }))] }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=decision-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-list.js","sourceRoot":"","sources":["../../src/components/decision-list.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { RestEvent } from "../api.js";
|
|
3
|
+
/** What an event says, without its actor: the words after the name. */
|
|
4
|
+
export declare function describeEvent(event: RestEvent): string;
|
|
5
|
+
export interface EventFeedProps {
|
|
6
|
+
/** Oldest first, as the API hands them over; the feed shows them newest first. */
|
|
7
|
+
readonly events: readonly RestEvent[];
|
|
8
|
+
/** Where the line of an event leads, when it is about a task or a decision. */
|
|
9
|
+
readonly href?: ((event: RestEvent) => string | undefined) | undefined;
|
|
10
|
+
readonly empty?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
export declare function EventFeed(props: EventFeedProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=event-feed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-feed.d.ts","sourceRoot":"","sources":["../../src/components/event-feed.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAkB3C,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAgCtD;AAED,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,+BA4B9C"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PersonChip, STATE_LABELS, Time } from "./ui.js";
|
|
3
|
+
// The feed: one line per event, newest first, as a sentence a person reads at a glance. It
|
|
4
|
+
// takes its data as props and nothing from the network.
|
|
5
|
+
const FIELD_WORDS = {
|
|
6
|
+
title: "the title",
|
|
7
|
+
body: "the body",
|
|
8
|
+
priority: "the priority",
|
|
9
|
+
assigneeId: "the assignee",
|
|
10
|
+
parentId: "what it is part of",
|
|
11
|
+
links: "the links",
|
|
12
|
+
};
|
|
13
|
+
/** "(as Claude Code)": what an agent did is said with what the agent calls itself. */
|
|
14
|
+
const as = (agent) => (agent === undefined ? "" : ` (as ${agent})`);
|
|
15
|
+
/** What an event says, without its actor: the words after the name. */
|
|
16
|
+
export function describeEvent(event) {
|
|
17
|
+
const { data } = event;
|
|
18
|
+
const task = data.number === undefined
|
|
19
|
+
? "a task"
|
|
20
|
+
: `#${data.number}${data.title === undefined ? "" : ` ${data.title}`}`;
|
|
21
|
+
switch (event.kind) {
|
|
22
|
+
case "person.joined":
|
|
23
|
+
return "joined the board";
|
|
24
|
+
case "person.role_changed":
|
|
25
|
+
return `made ${data.login ?? "someone"} ${data.role === "admin" ? "an administrator" : "a member"}`;
|
|
26
|
+
case "task.created":
|
|
27
|
+
return `wrote ${task}`;
|
|
28
|
+
case "task.moved":
|
|
29
|
+
return `moved ${task} from ${STATE_LABELS[data.from ?? "idea"]} to ${STATE_LABELS[data.to ?? "idea"]}`;
|
|
30
|
+
case "task.updated": {
|
|
31
|
+
const fields = (data.fields ?? []).map((field) => FIELD_WORDS[field] ?? field);
|
|
32
|
+
return `changed ${fields.length === 0 ? "something" : fields.join(", ")} of ${task}`;
|
|
33
|
+
}
|
|
34
|
+
case "decision.raised":
|
|
35
|
+
return `asked${as(data.agent)}: ${data.question ?? "a question"}`;
|
|
36
|
+
case "decision.answered":
|
|
37
|
+
return `answered "${data.question ?? "a question"}": ${data.option ?? ""}`;
|
|
38
|
+
case "run.started":
|
|
39
|
+
return `started on ${task}${as(data.agent)}`;
|
|
40
|
+
case "run.reported":
|
|
41
|
+
return `reported on ${task}${as(data.agent)}${data.excerpt === undefined ? "" : `: ${data.excerpt}`}`;
|
|
42
|
+
case "run.handed_in":
|
|
43
|
+
return `handed in ${data.label ?? "something"} on ${task}${as(data.agent)}`;
|
|
44
|
+
case "run.ended":
|
|
45
|
+
return `${data.status === "finished" ? "finished" : data.status === "failed" ? "failed on" : "gave up on"} ${task}${as(data.agent)}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function EventFeed(props) {
|
|
49
|
+
if (props.events.length === 0) {
|
|
50
|
+
return _jsx("div", { className: "sc-feed", children: props.empty ?? null });
|
|
51
|
+
}
|
|
52
|
+
const newestFirst = [...props.events].reverse();
|
|
53
|
+
return (_jsx("ol", { className: "sc-feed", "aria-label": "What happened", children: newestFirst.map((event) => {
|
|
54
|
+
const href = props.href?.(event);
|
|
55
|
+
const words = describeEvent(event);
|
|
56
|
+
return (_jsxs("li", { className: "sc-feed-item", children: [_jsx("span", { className: "sc-feed-actor", children: event.actor === null ? (_jsx("span", { className: "sc-person-login", children: "The console" })) : (_jsx(PersonChip, { person: event.actor })) }), _jsx("span", { className: "sc-feed-words", children: href === undefined ? words : _jsx("a", { href: href, children: words }) }), _jsx(Time, { iso: event.createdAt })] }, event.id));
|
|
57
|
+
}) }));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=event-feed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-feed.js","sourceRoot":"","sources":["../../src/components/event-feed.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/components/markdown.tsx"],"names":[],"mappings":"AAUA,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,+BA8C1D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import ReactMarkdown from "react-markdown";
|
|
3
|
+
import remarkGfm from "remark-gfm";
|
|
4
|
+
// What people and agents write is untrusted. It is rendered as React elements, never as HTML:
|
|
5
|
+
// raw HTML in the source stays text, links are limited to a few schemes and open elsewhere,
|
|
6
|
+
// and pictures come over https only, lazily and without a referrer.
|
|
7
|
+
const SAFE_LINK = /^(https?:|mailto:)/i;
|
|
8
|
+
const SAFE_IMAGE = /^https:\/\//i;
|
|
9
|
+
export function Markdown(props) {
|
|
10
|
+
return (_jsx("div", { className: "sc-prose", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm],
|
|
11
|
+
// Everything passes through here unchanged; the components below decide what a URL may do.
|
|
12
|
+
urlTransform: (url) => url, components: {
|
|
13
|
+
a({ href, children }) {
|
|
14
|
+
if (href === undefined || href === "") {
|
|
15
|
+
return _jsx("span", { children: children });
|
|
16
|
+
}
|
|
17
|
+
if (href.startsWith("#")) {
|
|
18
|
+
return _jsx("a", { href: href, children: children });
|
|
19
|
+
}
|
|
20
|
+
if (SAFE_LINK.test(href)) {
|
|
21
|
+
return (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer nofollow ugc", children: children }));
|
|
22
|
+
}
|
|
23
|
+
return _jsx("span", { children: children });
|
|
24
|
+
},
|
|
25
|
+
img({ src, alt, title }) {
|
|
26
|
+
const url = typeof src === "string" && SAFE_IMAGE.test(src) ? src : undefined;
|
|
27
|
+
if (url === undefined) {
|
|
28
|
+
return _jsx("span", { className: "sc-prose-image-text", children: alt ?? "" });
|
|
29
|
+
}
|
|
30
|
+
return (_jsx("img", { src: url, alt: alt ?? "", title: title, loading: "lazy", decoding: "async", referrerPolicy: "no-referrer" }));
|
|
31
|
+
},
|
|
32
|
+
}, children: props.source }) }));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/components/markdown.tsx"],"names":[],"mappings":";AAAA,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,8FAA8F;AAC9F,4FAA4F;AAC5F,oEAAoE;AAEpE,MAAM,SAAS,GAAG,qBAAqB,CAAC;AACxC,MAAM,UAAU,GAAG,cAAc,CAAC;AAElC,MAAM,UAAU,QAAQ,CAAC,KAAkC;IACzD,OAAO,CACL,cAAK,SAAS,EAAC,UAAU,YACvB,KAAC,aAAa,IACZ,aAAa,EAAE,CAAC,SAAS,CAAC;YAC1B,2FAA2F;YAC3F,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAC1B,UAAU,EAAE;gBACV,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAClB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;wBACtC,OAAO,yBAAO,QAAQ,GAAQ,CAAC;oBACjC,CAAC;oBACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACzB,OAAO,YAAG,IAAI,EAAE,IAAI,YAAG,QAAQ,GAAK,CAAC;oBACvC,CAAC;oBACD,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBACzB,OAAO,CACL,YAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,kCAAkC,YAClE,QAAQ,GACP,CACL,CAAC;oBACJ,CAAC;oBACD,OAAO,yBAAO,QAAQ,GAAQ,CAAC;gBACjC,CAAC;gBACD,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE;oBACrB,MAAM,GAAG,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC9E,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;wBACtB,OAAO,eAAM,SAAS,EAAC,qBAAqB,YAAE,GAAG,IAAI,EAAE,GAAQ,CAAC;oBAClE,CAAC;oBACD,OAAO,CACL,cACE,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,IAAI,EAAE,EACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAC,MAAM,EACd,QAAQ,EAAC,OAAO,EAChB,cAAc,EAAC,aAAa,GAC5B,CACH,CAAC;gBACJ,CAAC;aACF,YAEA,KAAK,CAAC,MAAM,GACC,GACZ,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PersonRole, RestPerson } from "../api.js";
|
|
2
|
+
export interface PeopleListProps {
|
|
3
|
+
readonly people: readonly RestPerson[];
|
|
4
|
+
/** Whoever is looking, so that their own row says so. */
|
|
5
|
+
readonly me?: RestPerson | undefined;
|
|
6
|
+
/** Called with the role an administrator chose. Left out, roles are read here, not changed. */
|
|
7
|
+
readonly onChangeRole?: ((person: RestPerson, role: PersonRole) => void) | undefined;
|
|
8
|
+
readonly busy?: boolean | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare function PeopleList(props: PeopleListProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=people.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"people.d.ts","sourceRoot":"","sources":["../../src/components/people.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAOxD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACrC,+FAA+F;IAC/F,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrF,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,+BAiChD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PERSON_ROLES } from "../vocabulary.js";
|
|
3
|
+
import { PersonChip, ROLE_LABELS, RoleBadge } from "./ui.js";
|
|
4
|
+
export function PeopleList(props) {
|
|
5
|
+
return (_jsx("ul", { className: "sc-people", "aria-label": "People", children: props.people.map((person) => (_jsxs("li", { className: "sc-person-row", children: [_jsx(PersonChip, { person: person, size: "md" }), _jsxs("span", { className: "sc-person-name", children: [person.name ?? "", props.me?.id === person.id && _jsx("span", { className: "sc-muted", children: " (you)" })] }), props.onChangeRole === undefined ? (_jsx(RoleBadge, { role: person.role })) : (_jsxs("label", { className: "sc-field sc-field-inline", children: [_jsxs("span", { className: "sc-visually-hidden", children: ["Role of ", person.login] }), _jsx("select", { className: "sc-input", value: person.role, disabled: props.busy === true, onChange: (event) => props.onChangeRole?.(person, event.target.value), children: PERSON_ROLES.map((role) => (_jsx("option", { value: role, children: ROLE_LABELS[role] }, role))) })] }))] }, person.id))) }));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=people.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"people.js","sourceRoot":"","sources":["../../src/components/people.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAc7D,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,OAAO,CACL,aAAI,SAAS,EAAC,WAAW,gBAAY,QAAQ,YAC1C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC5B,cAAoB,SAAS,EAAC,eAAe,aAC3C,KAAC,UAAU,IAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAC,IAAI,GAAG,EACxC,gBAAM,SAAS,EAAC,gBAAgB,aAC7B,MAAM,CAAC,IAAI,IAAI,EAAE,EACjB,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,MAAM,CAAC,EAAE,IAAI,eAAM,SAAS,EAAC,UAAU,uBAAc,IAClE,EACN,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,CAClC,KAAC,SAAS,IAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAI,CACjC,CAAC,CAAC,CAAC,CACF,iBAAO,SAAS,EAAC,0BAA0B,aACzC,gBAAM,SAAS,EAAC,oBAAoB,yBAAU,MAAM,CAAC,KAAK,IAAQ,EAClE,iBACE,SAAS,EAAC,UAAU,EACpB,KAAK,EAAE,MAAM,CAAC,IAAI,EAClB,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,EAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,KAAmB,CAAC,YAElF,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC1B,iBAAmB,KAAK,EAAE,IAAI,YAC3B,WAAW,CAAC,IAAI,CAAC,IADP,IAAI,CAER,CACV,CAAC,GACK,IACH,CACT,KAxBM,MAAM,CAAC,EAAE,CAyBb,CACN,CAAC,GACC,CACN,CAAC;AACJ,CAAC"}
|