@signalcore/ui 1.0.0-beta.1 → 1.0.0-beta.3
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 +55 -22
- package/dist/AgentAbout.js +11 -4
- package/dist/AgentAbout.js.map +1 -1
- package/dist/AgentChat.d.ts +7 -1
- package/dist/AgentChat.js +154 -2
- package/dist/AgentChat.js.map +1 -1
- package/dist/AgentSpace.d.ts +12 -3
- package/dist/AgentSpace.js +53 -11
- package/dist/AgentSpace.js.map +1 -1
- package/dist/AgentTasks.js +2 -1
- package/dist/AgentTasks.js.map +1 -1
- package/dist/Threads.d.ts +73 -0
- package/dist/Threads.js +140 -0
- package/dist/Threads.js.map +1 -0
- package/dist/VoiceCall.js +1 -1
- package/dist/VoiceCall.js.map +1 -1
- package/dist/about.d.ts +34 -144
- package/dist/about.js +6 -8
- package/dist/about.js.map +1 -1
- package/dist/automation/cron.d.ts +1 -1
- package/dist/automation/cron.js.map +1 -1
- package/dist/automation/marks.js +13 -5
- package/dist/automation/marks.js.map +1 -1
- package/dist/automation/messages.d.ts +6 -0
- package/dist/automation/messages.js +7 -1
- package/dist/automation/messages.js.map +1 -1
- package/dist/automation/types.d.ts +25 -128
- package/dist/automation/types.js +36 -0
- package/dist/automation/types.js.map +1 -0
- package/dist/automation/when.d.ts +1 -1
- package/dist/automation/when.js +13 -1
- package/dist/automation/when.js.map +1 -1
- package/dist/blocks.d.ts +23 -1
- package/dist/browser.js +2 -2
- package/dist/browser.js.map +1 -1
- package/dist/call.d.ts +1 -1
- package/dist/call.js.map +1 -1
- package/dist/client.d.ts +14 -4
- package/dist/client.js +7 -2
- package/dist/client.js.map +1 -1
- package/dist/contract.d.ts +267 -0
- package/dist/credentials.js.map +1 -1
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/es.d.ts +2 -0
- package/dist/es.js +31 -4
- package/dist/es.js.map +1 -1
- package/dist/frames.d.ts +7 -1
- package/dist/frames.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +6 -4
- package/dist/kit/AudioPlayer.js +1 -1
- package/dist/kit/AudioPlayer.js.map +1 -1
- package/dist/kit/Choices.js +1 -1
- package/dist/kit/Choices.js.map +1 -1
- package/dist/kit/FileField.js +1 -1
- package/dist/kit/FileField.js.map +1 -1
- package/dist/kit/Popover.js.map +1 -1
- package/dist/kit/Tile.d.ts +1 -1
- package/dist/kit/Tile.js +1 -1
- package/dist/kit/Tile.js.map +1 -1
- package/dist/kit/messages.d.ts +13 -0
- package/dist/kit/messages.js +7 -1
- package/dist/kit/messages.js.map +1 -1
- package/dist/kit/uploads.d.ts +2 -1
- package/dist/kit/uploads.js +1 -1
- package/dist/kit/uploads.js.map +1 -1
- package/dist/kit/waveform.js.map +1 -1
- package/dist/markdown.js.map +1 -1
- package/dist/marks.js +2 -3
- package/dist/marks.js.map +1 -1
- package/dist/surface/Form.js +1 -1
- package/dist/surface/Markdown.js +1 -1
- package/dist/surface/Markdown.js.map +1 -1
- package/dist/surface/Surface.js +43 -4
- package/dist/surface/Surface.js.map +1 -1
- package/dist/surface/scope.d.ts +1 -1
- package/dist/surface/scope.js.map +1 -1
- package/dist/surface/values.js +1 -1
- package/dist/surface/values.js.map +1 -1
- package/dist/tint.d.ts +1 -1
- package/dist/tint.js +1 -1
- package/dist/tint.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.js.map +1 -1
- package/dist/useConversation.d.ts +2 -0
- package/dist/useConversation.js +16 -0
- package/dist/useConversation.js.map +1 -1
- package/dist/usePolled.js +1 -1
- package/dist/usePolled.js.map +1 -1
- package/dist/voice/webgl.js +1 -1
- package/dist/voice/webgl.js.map +1 -1
- package/dist/widget.js +17 -16
- package/package.json +1 -1
- package/src/AgentAbout.tsx +14 -3
- package/src/AgentChat.tsx +203 -1
- package/src/AgentSpace.tsx +89 -13
- package/src/AgentTasks.tsx +2 -2
- package/src/Threads.tsx +218 -0
- package/src/VoiceCall.tsx +1 -1
- package/src/about.ts +42 -144
- package/src/automation/cron.ts +1 -1
- package/src/automation/marks.tsx +13 -2
- package/src/automation/messages.ts +12 -0
- package/src/automation/types.ts +58 -118
- package/src/automation/when.ts +7 -1
- package/src/blocks.ts +25 -0
- package/src/browser.ts +4 -4
- package/src/call.ts +1 -1
- package/src/client.ts +26 -10
- package/src/contract.ts +1934 -0
- package/src/credentials.ts +2 -2
- package/src/dev.ts +1 -1
- package/src/es.ts +29 -0
- package/src/frames.ts +3 -1
- package/src/index.ts +10 -1
- package/src/kit/AudioPlayer.tsx +1 -1
- package/src/kit/Choices.tsx +1 -1
- package/src/kit/FileField.tsx +1 -1
- package/src/kit/Popover.tsx +1 -1
- package/src/kit/Tile.tsx +1 -1
- package/src/kit/messages.ts +20 -0
- package/src/kit/uploads.ts +2 -2
- package/src/kit/waveform.ts +1 -1
- package/src/markdown.ts +1 -1
- package/src/marks.tsx +3 -123
- package/src/styles.css +206 -0
- package/src/surface/Markdown.tsx +1 -1
- package/src/surface/Surface.tsx +53 -4
- package/src/surface/scope.ts +3 -1
- package/src/surface/values.ts +5 -5
- package/src/tint.ts +1 -1
- package/src/types.ts +11 -0
- package/src/useConversation.ts +10 -0
- package/src/usePolled.ts +2 -2
- package/src/voice/webgl.ts +1 -1
- package/src/widget/element.tsx +13 -4
- package/src/widget/widget.css +13 -0
package/src/credentials.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type Credentials =
|
|
|
27
27
|
| Alone<{ publishableKey: string; visitorId?: string | undefined }>;
|
|
28
28
|
|
|
29
29
|
/** What one request carries to say who calls, and how to have it anew once it is refused. */
|
|
30
|
-
|
|
30
|
+
interface Signed {
|
|
31
31
|
headers: Readonly<Record<string, string>>;
|
|
32
32
|
/** Lets go of a token the API refused, for the next request to ask for another; null: none. */
|
|
33
33
|
renew: (() => void) | null;
|
|
@@ -41,7 +41,7 @@ export interface Signed {
|
|
|
41
41
|
export type Speaker = "business" | "person";
|
|
42
42
|
|
|
43
43
|
/** How every request and socket of a client says who calls. */
|
|
44
|
-
|
|
44
|
+
interface Signer {
|
|
45
45
|
who: Speaker;
|
|
46
46
|
/** What `fetch` sends of the browser's own: the cookie on the page's origin, or nothing. */
|
|
47
47
|
credentials: RequestCredentials;
|
package/src/dev.ts
CHANGED
|
@@ -12,7 +12,7 @@ function development(): boolean {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const DEV = development();
|
|
16
16
|
|
|
17
17
|
/** A note for the developer of the page, in development only: what the package let pass, and why. */
|
|
18
18
|
export function note(...said: unknown[]): void {
|
package/src/es.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { TaskMessages } from "./AgentTasks";
|
|
|
10
10
|
import type { AutomationMessages, DayRef } from "./automation/messages";
|
|
11
11
|
import type { BrowserMessages } from "./BrowserView";
|
|
12
12
|
import type { KitMessages } from "./kit/messages";
|
|
13
|
+
import type { ThreadMessages } from "./Threads";
|
|
13
14
|
import type { VoiceCallMessages } from "./VoiceCall";
|
|
14
15
|
|
|
15
16
|
/** The article before a time: "la 1:00", "las 8:00". */
|
|
@@ -76,6 +77,9 @@ export const AUTOMATION_MESSAGES_ES: AutomationMessages = {
|
|
|
76
77
|
on: (often, when) => `${often}, ${when.charAt(0).toLowerCase()}${when.slice(1)}`,
|
|
77
78
|
custom: "Con un horario propio",
|
|
78
79
|
webhook: "Cuando otro sistema la llama",
|
|
80
|
+
manual: "Cuando alguien la inicia",
|
|
81
|
+
after: (automation) => (automation ? `Tras «${automation}»` : "Tras otra automatización"),
|
|
82
|
+
platform: "Cuando llega un mensaje",
|
|
79
83
|
event: (app, event) =>
|
|
80
84
|
event
|
|
81
85
|
? `Cuando pasa «${event}» en ${app ?? "una app"}`
|
|
@@ -114,8 +118,11 @@ export const AUTOMATION_MESSAGES_ES: AutomationMessages = {
|
|
|
114
118
|
schedule: "horario",
|
|
115
119
|
webhook: "webhook",
|
|
116
120
|
event: app ? `evento de ${app}` : "evento",
|
|
121
|
+
platform: "un mensaje",
|
|
117
122
|
agent: "se lo pidieron en el chat",
|
|
118
123
|
test: "prueba",
|
|
124
|
+
api: "tu app",
|
|
125
|
+
after: "tras otra",
|
|
119
126
|
})[by],
|
|
120
127
|
statuses: {
|
|
121
128
|
running: "En curso",
|
|
@@ -220,6 +227,12 @@ export const KIT_MESSAGES_ES: KitMessages = {
|
|
|
220
227
|
pause: "Pausar",
|
|
221
228
|
position: "Posición",
|
|
222
229
|
automation: AUTOMATION_MESSAGES_ES,
|
|
230
|
+
connect: {
|
|
231
|
+
authorize: (app) => `Autorizar en ${app}`,
|
|
232
|
+
connected: "Conectada",
|
|
233
|
+
failed: "No se ha podido conectar",
|
|
234
|
+
preparing: "Preparando la conexión",
|
|
235
|
+
},
|
|
223
236
|
};
|
|
224
237
|
|
|
225
238
|
export const BROWSER_MESSAGES_ES: BrowserMessages = {
|
|
@@ -302,6 +315,10 @@ export const CHAT_MESSAGES_ES: ChatMessages = {
|
|
|
302
315
|
inputs: {},
|
|
303
316
|
allow: "Aprobar",
|
|
304
317
|
decline: "Rechazar",
|
|
318
|
+
approvals: (count) => `${count} acciones esperan tu aprobación`,
|
|
319
|
+
approveAll: "Aprobar todo",
|
|
320
|
+
approveSome: (count) => `Aprobar ${count}`,
|
|
321
|
+
declineAll: "Rechazar todo",
|
|
305
322
|
confirming: "Esperando la confirmación del negocio",
|
|
306
323
|
handedOff: "Pasada a una persona",
|
|
307
324
|
handover: (holder, by, name) => {
|
|
@@ -409,6 +426,17 @@ export const TASK_MESSAGES_ES: TaskMessages = {
|
|
|
409
426
|
failed: "No se ha podido cambiar. Inténtalo de nuevo.",
|
|
410
427
|
};
|
|
411
428
|
|
|
429
|
+
export const THREAD_MESSAGES_ES: ThreadMessages = {
|
|
430
|
+
open: "Conversaciones",
|
|
431
|
+
title: "Tus conversaciones",
|
|
432
|
+
back: "Volver a la conversación",
|
|
433
|
+
new: "Nueva conversación",
|
|
434
|
+
untitled: "Conversación nueva",
|
|
435
|
+
unread: (count) => (count === 1 ? "1 mensaje sin leer" : `${count} mensajes sin leer`),
|
|
436
|
+
waiting: "Te espera",
|
|
437
|
+
empty: "Aún no hay nada aquí.",
|
|
438
|
+
};
|
|
439
|
+
|
|
412
440
|
export const SPACE_MESSAGES_ES: SpaceMessages = {
|
|
413
441
|
modes: { label: "Modo", text: "Texto", voice: "Voz" },
|
|
414
442
|
again: "Volver a llamar",
|
|
@@ -420,4 +448,5 @@ export const SPACE_MESSAGES_ES: SpaceMessages = {
|
|
|
420
448
|
chat: CHAT_MESSAGES_ES,
|
|
421
449
|
voice: VOICE_CALL_MESSAGES_ES,
|
|
422
450
|
tasks: TASK_MESSAGES_ES,
|
|
451
|
+
threads: THREAD_MESSAGES_ES,
|
|
423
452
|
};
|
package/src/frames.ts
CHANGED
|
@@ -52,13 +52,15 @@ export type Frame =
|
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Up: the person says something (words, files they uploaded to the conversation, or both), acts
|
|
55
|
-
* on a surface
|
|
55
|
+
* on a surface (several things at once: a yes or no on each call a reply waits on), or stops
|
|
56
|
+
* the reply on its way; takes the browser or gives it back, and acts on it
|
|
56
57
|
* while they hold it. And what a tool of the host's answered, run in the page: its output, or
|
|
57
58
|
* why it failed.
|
|
58
59
|
*/
|
|
59
60
|
export type UpFrame =
|
|
60
61
|
| { type: "say"; text: string; files?: string[] }
|
|
61
62
|
| ({ type: "action" } & Action)
|
|
63
|
+
| { type: "actions"; actions: ({ type: "action" } & Action)[] }
|
|
62
64
|
| { type: "stop" }
|
|
63
65
|
| { type: "browser.control"; to: BrowserControl }
|
|
64
66
|
| { type: "browser.close" }
|
package/src/index.ts
CHANGED
|
@@ -94,8 +94,17 @@ export type {
|
|
|
94
94
|
Trigger,
|
|
95
95
|
Use,
|
|
96
96
|
} from "./automation/types";
|
|
97
|
+
export { taskCard } from "./automation/types";
|
|
97
98
|
export { AgentTasks, TASK_MESSAGES, TASKS_POLL_MS, useTasks } from "./AgentTasks";
|
|
98
99
|
export type { AgentTasksProps, TaskMessages, TaskPart } from "./AgentTasks";
|
|
100
|
+
export { Conversation, THREAD_MESSAGES, THREADS_POLL_MS, Threads, useUnread } from "./Threads";
|
|
101
|
+
export type {
|
|
102
|
+
ConversationProps,
|
|
103
|
+
ThreadMessages,
|
|
104
|
+
ThreadPart,
|
|
105
|
+
ThreadsProps,
|
|
106
|
+
Unread,
|
|
107
|
+
} from "./Threads";
|
|
99
108
|
export { AgentCard } from "./AgentCard";
|
|
100
109
|
export type { AgentCardProps, CardField, CardPart } from "./AgentCard";
|
|
101
110
|
export { AgentChat, CHAT_MESSAGES } from "./AgentChat";
|
|
@@ -109,6 +118,7 @@ export {
|
|
|
109
118
|
KIT_MESSAGES_ES,
|
|
110
119
|
SPACE_MESSAGES_ES,
|
|
111
120
|
TASK_MESSAGES_ES,
|
|
121
|
+
THREAD_MESSAGES_ES,
|
|
112
122
|
VOICE_CALL_MESSAGES_ES,
|
|
113
123
|
} from "./es";
|
|
114
124
|
export { VOICE_CALL_MESSAGES, VoiceCall } from "./VoiceCall";
|
|
@@ -234,7 +244,6 @@ export type {
|
|
|
234
244
|
ChannelWeb,
|
|
235
245
|
ContactGlance,
|
|
236
246
|
ConversationPerson,
|
|
237
|
-
Conversation,
|
|
238
247
|
ConversationDetail,
|
|
239
248
|
ConversationFile,
|
|
240
249
|
Decides,
|
package/src/kit/AudioPlayer.tsx
CHANGED
|
@@ -120,7 +120,7 @@ export function AudioPlayer({ src, label, onError, compact, className }: AudioPl
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/** Seconds as a player says them: 0:07, 1:42, 1:02:05. */
|
|
123
|
-
|
|
123
|
+
function clock(seconds: number): string {
|
|
124
124
|
const whole = Math.max(0, Math.floor(seconds));
|
|
125
125
|
const hours = Math.floor(whole / 3600);
|
|
126
126
|
const minutes = Math.floor((whole % 3600) / 60);
|
package/src/kit/Choices.tsx
CHANGED
|
@@ -42,7 +42,7 @@ export function useRadios(count: number, checked: number, check: (index: number)
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/** Few short options with no hints sit side by side in one bar; any other few are cards. */
|
|
45
|
-
|
|
45
|
+
function segmented(options: Option[]): boolean {
|
|
46
46
|
const length = options.reduce((sum, option) => sum + option.label.length, 0);
|
|
47
47
|
return options.length <= 4 && length <= 32 && options.every((option) => !option.hint);
|
|
48
48
|
}
|
package/src/kit/FileField.tsx
CHANGED
|
@@ -188,7 +188,7 @@ export interface Uploads {
|
|
|
188
188
|
let picks = 0;
|
|
189
189
|
|
|
190
190
|
/** A file already in, by its id: what `useUploads` starts from. */
|
|
191
|
-
|
|
191
|
+
function uploaded(id: string, known: Attachment | undefined): Upload {
|
|
192
192
|
return {
|
|
193
193
|
key: ++picks,
|
|
194
194
|
name: known?.name ?? "",
|
package/src/kit/Popover.tsx
CHANGED
|
@@ -55,7 +55,7 @@ export function usePopover(
|
|
|
55
55
|
return { ...floating, ...interactions };
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
type PopoverState = ReturnType<typeof usePopover>;
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* Where the panel goes instead of the page's end: the host's dialog the trigger sits in (a modal
|
package/src/kit/Tile.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { joined, useParts } from "./context";
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Tiles in a grid that asks its own width, not the window's: two across, one when narrow, three
|
|
7
|
-
* when there is room. What an agent works with,
|
|
7
|
+
* when there is room. What an agent works with, the agents at a glance.
|
|
8
8
|
*/
|
|
9
9
|
export function Tiles({
|
|
10
10
|
label,
|
package/src/kit/messages.ts
CHANGED
|
@@ -95,6 +95,20 @@ export interface KitMessages {
|
|
|
95
95
|
position: string;
|
|
96
96
|
/** An automation and its runs: when it runs, how it stands, what each run did. */
|
|
97
97
|
automation: AutomationMessages;
|
|
98
|
+
/** An app for the person to connect, as its connection stands. */
|
|
99
|
+
connect: ConnectMessages;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** The words of an app's card: its button, and what it says where the button isn't. */
|
|
103
|
+
export interface ConnectMessages {
|
|
104
|
+
/** The button that opens the app's consent page, given the app's name. */
|
|
105
|
+
authorize: (app: string) => string;
|
|
106
|
+
/** It works. */
|
|
107
|
+
connected: string;
|
|
108
|
+
/** It failed, or the account was lost: the agent asks for it again. */
|
|
109
|
+
failed: string;
|
|
110
|
+
/** Before the platform has the consent page. */
|
|
111
|
+
preparing: string;
|
|
98
112
|
}
|
|
99
113
|
|
|
100
114
|
const FAMILIES: Readonly<Record<string, string>> = {
|
|
@@ -157,4 +171,10 @@ export const KIT_MESSAGES: KitMessages = {
|
|
|
157
171
|
pause: "Pause",
|
|
158
172
|
position: "Position",
|
|
159
173
|
automation: AUTOMATION_MESSAGES,
|
|
174
|
+
connect: {
|
|
175
|
+
authorize: (app) => `Authorize in ${app}`,
|
|
176
|
+
connected: "Connected",
|
|
177
|
+
failed: "It couldn't be connected",
|
|
178
|
+
preparing: "Getting it ready",
|
|
179
|
+
},
|
|
160
180
|
};
|
package/src/kit/uploads.ts
CHANGED
|
@@ -38,14 +38,14 @@ export interface FileHost {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/** A file as picked: its name, its type as the browser gave it ("" when none), its weight. */
|
|
41
|
-
|
|
41
|
+
interface Picked {
|
|
42
42
|
name: string;
|
|
43
43
|
type: string;
|
|
44
44
|
size: number;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/** A name's extension, lowercase, without its dot; "" for one without (`README`, `.env`). */
|
|
48
|
-
|
|
48
|
+
function extensionOf(name: string): string {
|
|
49
49
|
const dot = name.lastIndexOf(".");
|
|
50
50
|
return dot <= 0 ? "" : name.slice(dot + 1).toLowerCase();
|
|
51
51
|
}
|
package/src/kit/waveform.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
|
|
|
4
4
|
const MOST_BYTES = 8 * 1024 * 1024;
|
|
5
5
|
|
|
6
6
|
/** An audio as drawn: its bars' heights, and how long it is (what an Ogg doesn't say upfront). */
|
|
7
|
-
|
|
7
|
+
interface Waveform {
|
|
8
8
|
heights: number[];
|
|
9
9
|
seconds: number;
|
|
10
10
|
}
|
package/src/markdown.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type Inline =
|
|
|
8
8
|
| { kind: "text" | "strong" | "em" | "code"; text: string }
|
|
9
9
|
| { kind: "link"; text: string; href: string };
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
type Node =
|
|
12
12
|
| { kind: "heading"; level: number; inline: Inline[] }
|
|
13
13
|
| { kind: "paragraph"; inline: Inline[] }
|
|
14
14
|
| { kind: "list"; items: Inline[][] };
|
package/src/marks.tsx
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
ActionSource,
|
|
5
|
-
AutomationKind,
|
|
6
|
-
ChannelKind,
|
|
7
|
-
DeviceKind,
|
|
8
|
-
Icon,
|
|
9
|
-
Provider,
|
|
10
|
-
} from "./about";
|
|
3
|
+
import type { ActionSource, ChannelKind, DeviceKind, Provider } from "./about";
|
|
11
4
|
|
|
12
5
|
/**
|
|
13
|
-
* The marks Qué puede draws, each a 16-unit stroke glyph in `currentColor`: the
|
|
14
|
-
*
|
|
15
|
-
* glyph of each app, channel and device. No icon library: a host reads nothing but this package.
|
|
6
|
+
* The marks Qué puede draws, each a 16-unit stroke glyph in `currentColor`: the shipped actions'
|
|
7
|
+
* marks and the simplest faithful glyph of each app, channel and device. No icon library: a host reads nothing but this package.
|
|
16
8
|
*/
|
|
17
9
|
|
|
18
10
|
const STROKE = {
|
|
@@ -49,36 +41,12 @@ const mail = (
|
|
|
49
41
|
<path d="m2.5 5.5 5.5 3.7 5.5-3.7" />
|
|
50
42
|
</>
|
|
51
43
|
);
|
|
52
|
-
const calendar = (
|
|
53
|
-
<>
|
|
54
|
-
<rect x="2.5" y="3.5" width="11" height="10" rx="1.5" />
|
|
55
|
-
<path d="M2.5 7h11M5.5 2v3M10.5 2v3" />
|
|
56
|
-
</>
|
|
57
|
-
);
|
|
58
|
-
const clock = (
|
|
59
|
-
<>
|
|
60
|
-
<circle cx="8" cy="8" r="5.75" />
|
|
61
|
-
<path d="M8 4.75V8l2.2 1.4" />
|
|
62
|
-
</>
|
|
63
|
-
);
|
|
64
44
|
const search = (
|
|
65
45
|
<>
|
|
66
46
|
<circle cx="7" cy="7" r="4.25" />
|
|
67
47
|
<path d="m10.2 10.2 3.3 3.3" />
|
|
68
48
|
</>
|
|
69
49
|
);
|
|
70
|
-
const file = (
|
|
71
|
-
<>
|
|
72
|
-
<path d="M4 2.5h5l3.5 3.5v7.5a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-10a1 1 0 0 1 1-1z" />
|
|
73
|
-
<path d="M9 2.5V6h3.5" />
|
|
74
|
-
</>
|
|
75
|
-
);
|
|
76
|
-
const table = (
|
|
77
|
-
<>
|
|
78
|
-
<rect x="2.5" y="3" width="11" height="10" rx="1.5" />
|
|
79
|
-
<path d="M2.5 6.5h11M6.5 6.5V13" />
|
|
80
|
-
</>
|
|
81
|
-
);
|
|
82
50
|
const bell = (
|
|
83
51
|
<>
|
|
84
52
|
<path d="M4 11V7.5a4 4 0 0 1 8 0V11l1 1.5H3z" />
|
|
@@ -91,12 +59,6 @@ const hand = (
|
|
|
91
59
|
<path d="M5.5 8.2 4.4 7a1 1 0 0 0-1.6 1.2L5 11.6a3.6 3.6 0 0 0 3.1 1.9H9a2.5 2.5 0 0 0 2.5-2.5V9.1" />
|
|
92
60
|
</>
|
|
93
61
|
);
|
|
94
|
-
const user = (
|
|
95
|
-
<>
|
|
96
|
-
<circle cx="8" cy="5.5" r="2.75" />
|
|
97
|
-
<path d="M3 13.5a5 5 0 0 1 10 0" />
|
|
98
|
-
</>
|
|
99
|
-
);
|
|
100
62
|
const globe = (
|
|
101
63
|
<>
|
|
102
64
|
<circle cx="8" cy="8" r="5.75" />
|
|
@@ -104,71 +66,6 @@ const globe = (
|
|
|
104
66
|
</>
|
|
105
67
|
);
|
|
106
68
|
const code = <path d="m5.5 5-3 3 3 3M10.5 5l3 3-3 3M9.3 3.5 6.7 12.5" />;
|
|
107
|
-
const lock = (
|
|
108
|
-
<>
|
|
109
|
-
<rect x="3.5" y="7" width="9" height="6.5" rx="1.5" />
|
|
110
|
-
<path d="M5.5 7V5a2.5 2.5 0 0 1 5 0v2" />
|
|
111
|
-
</>
|
|
112
|
-
);
|
|
113
|
-
const cart = (
|
|
114
|
-
<>
|
|
115
|
-
<path d="M2 3h1.8l1.4 7h7.3l1.3-5H4.4" />
|
|
116
|
-
<circle cx="6" cy="12.8" r=".9" fill="currentColor" stroke="none" />
|
|
117
|
-
<circle cx="11.5" cy="12.8" r=".9" fill="currentColor" stroke="none" />
|
|
118
|
-
</>
|
|
119
|
-
);
|
|
120
|
-
const card = (
|
|
121
|
-
<>
|
|
122
|
-
<rect x="2" y="3.5" width="12" height="9" rx="1.5" />
|
|
123
|
-
<path d="M2 6.5h12M4.5 10h3" />
|
|
124
|
-
</>
|
|
125
|
-
);
|
|
126
|
-
const map = (
|
|
127
|
-
<>
|
|
128
|
-
<path d="m2.5 4.5 3.5-1.5 4 1.5 3.5-1.5v9l-3.5 1.5-4-1.5-3.5 1.5z" />
|
|
129
|
-
<path d="M6 3v9M10 4.5v9" />
|
|
130
|
-
</>
|
|
131
|
-
);
|
|
132
|
-
const check = <path d="m3.5 8.5 3 3 6-7" />;
|
|
133
|
-
const warning = (
|
|
134
|
-
<>
|
|
135
|
-
<path d="M8 2.5 14 13H2z" />
|
|
136
|
-
<path d="M8 6.5v3" />
|
|
137
|
-
<circle cx="8" cy="11.3" r=".8" fill="currentColor" stroke="none" />
|
|
138
|
-
</>
|
|
139
|
-
);
|
|
140
|
-
const sparkle = (
|
|
141
|
-
<>
|
|
142
|
-
<path d="M7 2.5c.4 2.9 1.5 4 4.4 4.4-2.9.4-4 1.5-4.4 4.4-.4-2.9-1.5-4-4.4-4.4C5.5 6.5 6.6 5.4 7 2.5z" />
|
|
143
|
-
<path d="M12.3 10.5c.2 1 .5 1.3 1.5 1.5-1 .2-1.3.5-1.5 1.5-.2-1-.5-1.3-1.5-1.5 1-.2 1.3-.5 1.5-1.5z" />
|
|
144
|
-
</>
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
const ICONS: Readonly<Record<Icon, ReactNode>> = {
|
|
148
|
-
message,
|
|
149
|
-
phone,
|
|
150
|
-
mail,
|
|
151
|
-
calendar,
|
|
152
|
-
clock,
|
|
153
|
-
search,
|
|
154
|
-
file,
|
|
155
|
-
table,
|
|
156
|
-
bell,
|
|
157
|
-
hand,
|
|
158
|
-
user,
|
|
159
|
-
globe,
|
|
160
|
-
code,
|
|
161
|
-
lock,
|
|
162
|
-
cart,
|
|
163
|
-
card,
|
|
164
|
-
map,
|
|
165
|
-
check,
|
|
166
|
-
warning,
|
|
167
|
-
sparkle,
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
/** The mark of a generated line. */
|
|
171
|
-
export const iconOf = (icon: Icon): ReactNode => <Glyph>{ICONS[icon]}</Glyph>;
|
|
172
69
|
|
|
173
70
|
const pane = (
|
|
174
71
|
<>
|
|
@@ -211,23 +108,6 @@ export const actionMark = (name: string, source: ActionSource): ReactNode => (
|
|
|
211
108
|
<Glyph>{source === "own" ? code : (ACTIONS[name] ?? bolt)}</Glyph>
|
|
212
109
|
);
|
|
213
110
|
|
|
214
|
-
const hook = (
|
|
215
|
-
<>
|
|
216
|
-
<path d="M2.5 8h7M7 5.5 9.5 8 7 10.5" />
|
|
217
|
-
<path d="M11 3.5h1.5a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H11" />
|
|
218
|
-
</>
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
const AUTOMATIONS: Readonly<Record<AutomationKind, ReactNode>> = {
|
|
222
|
-
schedule: clock,
|
|
223
|
-
webhook: hook,
|
|
224
|
-
event: bolt,
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
export const automationMark = (kind: AutomationKind): ReactNode => (
|
|
228
|
-
<Glyph>{AUTOMATIONS[kind]}</Glyph>
|
|
229
|
-
);
|
|
230
|
-
|
|
231
111
|
/** A letter alone: the simplest monogram of an app. */
|
|
232
112
|
function Monogram({ letter }: { letter: string }) {
|
|
233
113
|
return (
|
package/src/styles.css
CHANGED
|
@@ -633,6 +633,45 @@
|
|
|
633
633
|
line-height: 1.375;
|
|
634
634
|
}
|
|
635
635
|
|
|
636
|
+
/* Several actions waiting for the person's leave, in one card: a row for each, its box ticked
|
|
637
|
+
and what it would take under it, editable; one button at the foot. */
|
|
638
|
+
.sc-chat__requests > ul {
|
|
639
|
+
display: flex;
|
|
640
|
+
flex-direction: column;
|
|
641
|
+
margin: 0;
|
|
642
|
+
padding: 0;
|
|
643
|
+
list-style: none;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.sc-chat__ask {
|
|
647
|
+
display: flex;
|
|
648
|
+
flex-direction: column;
|
|
649
|
+
gap: calc(var(--_space) * 2.5);
|
|
650
|
+
padding: calc(var(--_space) * 3) calc(var(--_space) * 4);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
.sc-chat__ask + .sc-chat__ask {
|
|
654
|
+
border-top: 1px solid var(--_line);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.sc-chat__ask > .sc-check > span {
|
|
658
|
+
font-weight: var(--_font-weight-medium);
|
|
659
|
+
line-height: 1.375;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
.sc-chat__ask-fields {
|
|
663
|
+
display: grid;
|
|
664
|
+
gap: calc(var(--_space) * 2.5);
|
|
665
|
+
padding-left: calc(var(--_space) * 6.5);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.sc-chat__requests > footer {
|
|
669
|
+
display: flex;
|
|
670
|
+
justify-content: flex-end;
|
|
671
|
+
padding: calc(var(--_space) * 3) calc(var(--_space) * 4);
|
|
672
|
+
border-top: 1px solid var(--_line);
|
|
673
|
+
}
|
|
674
|
+
|
|
636
675
|
/* On a person's page, in place of the approval card: what waits for the business's yes, a quiet
|
|
637
676
|
line under the steps; the person has nothing to press. */
|
|
638
677
|
.sc-chat__confirming {
|
|
@@ -5157,6 +5196,21 @@ button.sc-attachment__main:focus-visible {
|
|
|
5157
5196
|
font-size: var(--_font-size-sm);
|
|
5158
5197
|
}
|
|
5159
5198
|
|
|
5199
|
+
/* An app's card, where its button isn't: a quiet word (on its way, failed); once it works, in
|
|
5200
|
+
the ink, after a check. */
|
|
5201
|
+
.sc-surface__connect {
|
|
5202
|
+
display: flex;
|
|
5203
|
+
align-items: center;
|
|
5204
|
+
gap: 6px;
|
|
5205
|
+
margin: 0;
|
|
5206
|
+
color: var(--_muted);
|
|
5207
|
+
font-size: var(--_font-size-sm);
|
|
5208
|
+
}
|
|
5209
|
+
|
|
5210
|
+
.sc-surface__connect--done {
|
|
5211
|
+
color: var(--_fg);
|
|
5212
|
+
}
|
|
5213
|
+
|
|
5160
5214
|
/* An automation that is not there any more: a quiet line in a dashed box where it would be. */
|
|
5161
5215
|
.sc-automation--gone {
|
|
5162
5216
|
margin: 0;
|
|
@@ -6412,6 +6466,158 @@ button.sc-attachment__main:focus-visible {
|
|
|
6412
6466
|
outline-offset: -2px;
|
|
6413
6467
|
}
|
|
6414
6468
|
|
|
6469
|
+
/* Over the chat, one line: the way to the person's threads (a dot when another has something
|
|
6470
|
+
for them) and, at its end, their tasks. */
|
|
6471
|
+
.sc-space__bar {
|
|
6472
|
+
display: flex;
|
|
6473
|
+
flex-shrink: 0;
|
|
6474
|
+
align-items: stretch;
|
|
6475
|
+
border-bottom: 1px solid var(--_line);
|
|
6476
|
+
}
|
|
6477
|
+
|
|
6478
|
+
.sc-space__bar > .sc-space__threads,
|
|
6479
|
+
.sc-space__bar > .sc-space__tasks {
|
|
6480
|
+
width: auto;
|
|
6481
|
+
border-bottom: 0;
|
|
6482
|
+
}
|
|
6483
|
+
|
|
6484
|
+
.sc-space__bar > .sc-space__tasks:not(:only-child) {
|
|
6485
|
+
margin-left: auto;
|
|
6486
|
+
text-align: right;
|
|
6487
|
+
}
|
|
6488
|
+
|
|
6489
|
+
/* The way to the person's threads; a dot when another thread has something for them. */
|
|
6490
|
+
.sc-space__threads {
|
|
6491
|
+
display: flex;
|
|
6492
|
+
flex-shrink: 0;
|
|
6493
|
+
align-items: center;
|
|
6494
|
+
gap: calc(var(--_space) * 1.5);
|
|
6495
|
+
width: 100%;
|
|
6496
|
+
padding: calc(var(--_space) * 2) calc(var(--_space) * 3.5);
|
|
6497
|
+
border: 0;
|
|
6498
|
+
border-bottom: 1px solid var(--_line);
|
|
6499
|
+
background: transparent;
|
|
6500
|
+
color: var(--_muted);
|
|
6501
|
+
font: inherit;
|
|
6502
|
+
font-size: var(--_font-size-xs);
|
|
6503
|
+
font-weight: var(--_font-weight-medium);
|
|
6504
|
+
text-align: left;
|
|
6505
|
+
cursor: pointer;
|
|
6506
|
+
transition:
|
|
6507
|
+
background-color 0.12s,
|
|
6508
|
+
color 0.12s;
|
|
6509
|
+
}
|
|
6510
|
+
|
|
6511
|
+
.sc-space__threads:hover {
|
|
6512
|
+
background: var(--_wash);
|
|
6513
|
+
color: var(--_fg);
|
|
6514
|
+
}
|
|
6515
|
+
|
|
6516
|
+
.sc-space__threads:focus-visible {
|
|
6517
|
+
outline: 2px solid var(--_accent);
|
|
6518
|
+
outline-offset: -2px;
|
|
6519
|
+
}
|
|
6520
|
+
|
|
6521
|
+
.sc-space__dot,
|
|
6522
|
+
.sc-threads__dot {
|
|
6523
|
+
flex-shrink: 0;
|
|
6524
|
+
width: 7px;
|
|
6525
|
+
height: 7px;
|
|
6526
|
+
border-radius: var(--_radius-full);
|
|
6527
|
+
background: var(--_accent);
|
|
6528
|
+
}
|
|
6529
|
+
|
|
6530
|
+
/* The person's threads in the chat's place: the way back, their title and another to start, then
|
|
6531
|
+
each by its title with what is unread. */
|
|
6532
|
+
.sc-threads {
|
|
6533
|
+
display: flex;
|
|
6534
|
+
flex: 1;
|
|
6535
|
+
flex-direction: column;
|
|
6536
|
+
min-height: 0;
|
|
6537
|
+
overflow-y: auto;
|
|
6538
|
+
}
|
|
6539
|
+
|
|
6540
|
+
.sc-threads__head {
|
|
6541
|
+
display: flex;
|
|
6542
|
+
flex-shrink: 0;
|
|
6543
|
+
align-items: center;
|
|
6544
|
+
gap: calc(var(--_space) * 1.5);
|
|
6545
|
+
padding: calc(var(--_space) * 2) calc(var(--_space) * 3);
|
|
6546
|
+
border-bottom: 1px solid var(--_line);
|
|
6547
|
+
}
|
|
6548
|
+
|
|
6549
|
+
.sc-threads__title {
|
|
6550
|
+
flex: 1;
|
|
6551
|
+
margin: 0;
|
|
6552
|
+
font-size: var(--_font-size);
|
|
6553
|
+
font-weight: var(--_font-weight-bold);
|
|
6554
|
+
}
|
|
6555
|
+
|
|
6556
|
+
.sc-threads__list {
|
|
6557
|
+
display: flex;
|
|
6558
|
+
flex-direction: column;
|
|
6559
|
+
margin: 0;
|
|
6560
|
+
padding: calc(var(--_space) * 1.5);
|
|
6561
|
+
list-style: none;
|
|
6562
|
+
}
|
|
6563
|
+
|
|
6564
|
+
.sc-threads__item {
|
|
6565
|
+
display: flex;
|
|
6566
|
+
align-items: center;
|
|
6567
|
+
gap: calc(var(--_space) * 2);
|
|
6568
|
+
width: 100%;
|
|
6569
|
+
padding: calc(var(--_space) * 2.5) calc(var(--_space) * 2.5);
|
|
6570
|
+
border: 0;
|
|
6571
|
+
border-radius: var(--_radius);
|
|
6572
|
+
background: transparent;
|
|
6573
|
+
color: var(--_fg);
|
|
6574
|
+
font: inherit;
|
|
6575
|
+
text-align: left;
|
|
6576
|
+
cursor: pointer;
|
|
6577
|
+
transition: background-color 0.12s;
|
|
6578
|
+
}
|
|
6579
|
+
|
|
6580
|
+
.sc-threads__item:hover {
|
|
6581
|
+
background: var(--_wash);
|
|
6582
|
+
}
|
|
6583
|
+
|
|
6584
|
+
.sc-threads__item:focus-visible {
|
|
6585
|
+
outline: 2px solid var(--_accent);
|
|
6586
|
+
outline-offset: -2px;
|
|
6587
|
+
}
|
|
6588
|
+
|
|
6589
|
+
.sc-threads__item--current {
|
|
6590
|
+
background: var(--_wash);
|
|
6591
|
+
font-weight: var(--_font-weight-medium);
|
|
6592
|
+
}
|
|
6593
|
+
|
|
6594
|
+
.sc-threads__name {
|
|
6595
|
+
flex: 1;
|
|
6596
|
+
min-width: 0;
|
|
6597
|
+
overflow: hidden;
|
|
6598
|
+
text-overflow: ellipsis;
|
|
6599
|
+
white-space: nowrap;
|
|
6600
|
+
}
|
|
6601
|
+
|
|
6602
|
+
.sc-threads__badge {
|
|
6603
|
+
flex-shrink: 0;
|
|
6604
|
+
min-width: 20px;
|
|
6605
|
+
padding: 1px calc(var(--_space) * 1.5);
|
|
6606
|
+
border-radius: var(--_radius-full);
|
|
6607
|
+
background: var(--_accent);
|
|
6608
|
+
color: var(--_accent-fg);
|
|
6609
|
+
font-size: var(--_font-size-xs);
|
|
6610
|
+
font-variant-numeric: tabular-nums;
|
|
6611
|
+
font-weight: var(--_font-weight-medium);
|
|
6612
|
+
text-align: center;
|
|
6613
|
+
}
|
|
6614
|
+
|
|
6615
|
+
.sc-threads__empty {
|
|
6616
|
+
margin: 0;
|
|
6617
|
+
padding: calc(var(--_space) * 4) calc(var(--_space) * 3.5);
|
|
6618
|
+
color: var(--_muted);
|
|
6619
|
+
}
|
|
6620
|
+
|
|
6415
6621
|
/* The tasks in the chat's place: the way back and their title, then each as an automation
|
|
6416
6622
|
reads, a hairline between them. */
|
|
6417
6623
|
.sc-tasks {
|
package/src/surface/Markdown.tsx
CHANGED
|
@@ -33,7 +33,7 @@ export function Markdown({ text }: { text: string }) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/** One line's words, its bold, italic, code and links drawn; a link opens apart, never in place. */
|
|
36
|
-
|
|
36
|
+
function Words({ inline }: { inline: Inline[] }) {
|
|
37
37
|
return inline.map((part, index) => {
|
|
38
38
|
switch (part.kind) {
|
|
39
39
|
case "text":
|