@adatechnology/conversations-ui 0.1.0-rc.21 → 0.1.0-rc.23

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.
@@ -1,6 +1,7 @@
1
1
  import { G as MessagePayload, o as ConversationSummary, m as ConversationEventSource, q as ConversationsApi, L as ListConversationsParams, n as ConversationPage, S as SSEProvider, k as ConversationDocument, N as ResolveMediaUrl } from '../types-C6A_9edv.js';
2
2
  export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS } from '../types-C6A_9edv.js';
3
3
  import * as react from 'react';
4
+ import { ReactNode } from 'react';
4
5
  import { InteractiveReplyOption, InboundMediaType } from '@adatechnology/meta-whatsapp-contracts/testing';
5
6
  export { PREVIEW_MEDIA_ID_PREFIX } from '@adatechnology/meta-whatsapp-contracts';
6
7
 
@@ -296,6 +297,27 @@ type PreviewUploadedMedia = {
296
297
  declare function mediaTypeOf(mimeType: string): SendPreviewMediaParams['mediaType'];
297
298
  declare function ConversationPreview({ client, sse, conversationId, loadMessages, placeholder, pollIntervalMs, uploadMedia, }: ConversationPreviewProps): react.JSX.Element;
298
299
 
300
+ type ConversationSimulatorPanelLabels = {
301
+ readonly title: string;
302
+ /** Complementa o telefone no subtítulo, explicando para onde a mensagem realmente vai. */
303
+ readonly destinationHint: string;
304
+ readonly close: string;
305
+ readonly placeholder: string;
306
+ };
307
+ declare const DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS: ConversationSimulatorPanelLabels;
308
+ type ConversationSimulatorPanelProps = Omit<ConversationPreviewProps, 'placeholder'> & {
309
+ readonly onClose: () => void;
310
+ /**
311
+ * Telefone já formatado para leitura. É o host que formata: máscara de telefone é convenção
312
+ * regional, e o pacote não tem como saber a do produto.
313
+ */
314
+ readonly displayNumber?: string;
315
+ readonly labels?: Partial<ConversationSimulatorPanelLabels>;
316
+ /** Ações extras no cabeçalho — roteiro automático, limpar conversa, trocar de contato. */
317
+ readonly headerActions?: ReactNode;
318
+ };
319
+ declare function ConversationSimulatorPanel({ onClose, displayNumber, labels, headerActions, ...previewProps }: ConversationSimulatorPanelProps): react.JSX.Element;
320
+
299
321
  /**
300
322
  * Cliente do preview que NÃO carrega segredo: em vez de montar e assinar o payload da Meta no
301
323
  * navegador, manda um comando semântico (`{ kind: 'text', text }`) para uma rota do próprio host,
@@ -467,4 +489,4 @@ type MediaTypesPreviewProps = {
467
489
  };
468
490
  declare function MediaTypesPreview({ conversationId, className, }: MediaTypesPreviewProps): react.JSX.Element;
469
491
 
470
- export { type AppendMessageParams, ConversationPreview, type ConversationPreviewProps, type CreateMockConversationsApiParams, type CreateMockSSEProviderParams, type CreatePreviewBridgeClientParams, type CreatePreviewMediaUploaderParams, type CreatePreviewStoreParams, type CreatePreviewWebhookClientParams, DEFAULT_MEDIA_UPLOAD_PATH, DEFAULT_PREVIEW_SCRIPT, GLOBAL_CHANNEL, type ListConversationsFilters, MEDIA_TYPES_CONVERSATION_ID, MediaTypesPreview, type MediaTypesPreviewProps, type MockEventSource, PREVIEW_CONVERSATIONS, PREVIEW_DOCUMENTS, PREVIEW_FILE_SAMPLES, PREVIEW_MESSAGES, PreviewBridgeRejectedError, type PreviewEmission, PreviewInProductionError, type PreviewInboundCommand, PreviewMediaUploadRejectedError, type PreviewMediaUploadRequest, type PreviewScriptStep, type PreviewStore, type PreviewStoreListener, type PreviewUploadedMedia, type PreviewWebhookClient, PreviewWebhookRejectedError, type SendPreviewInboundCommand, type SendPreviewMediaParams, type SetModeParams, type StartPreviewScriptParams, assertPreviewEnvironment, conversationChannel, createMockConversationsApi, createMockEventSource, createMockSSEProvider, createPreviewBridgeClient, createPreviewMediaPoster, createPreviewMediaResolver, createPreviewMediaUploader, createPreviewStore, createPreviewWebhookClient, mediaTypeOf, previewFileBase64, previewFileUrl, resolvePreviewFileSample, signPreviewPayload, startPreviewScript };
492
+ export { type AppendMessageParams, ConversationPreview, type ConversationPreviewProps, ConversationSimulatorPanel, type ConversationSimulatorPanelLabels, type ConversationSimulatorPanelProps, type CreateMockConversationsApiParams, type CreateMockSSEProviderParams, type CreatePreviewBridgeClientParams, type CreatePreviewMediaUploaderParams, type CreatePreviewStoreParams, type CreatePreviewWebhookClientParams, DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS, DEFAULT_MEDIA_UPLOAD_PATH, DEFAULT_PREVIEW_SCRIPT, GLOBAL_CHANNEL, type ListConversationsFilters, MEDIA_TYPES_CONVERSATION_ID, MediaTypesPreview, type MediaTypesPreviewProps, type MockEventSource, PREVIEW_CONVERSATIONS, PREVIEW_DOCUMENTS, PREVIEW_FILE_SAMPLES, PREVIEW_MESSAGES, PreviewBridgeRejectedError, type PreviewEmission, PreviewInProductionError, type PreviewInboundCommand, PreviewMediaUploadRejectedError, type PreviewMediaUploadRequest, type PreviewScriptStep, type PreviewStore, type PreviewStoreListener, type PreviewUploadedMedia, type PreviewWebhookClient, PreviewWebhookRejectedError, type SendPreviewInboundCommand, type SendPreviewMediaParams, type SetModeParams, type StartPreviewScriptParams, assertPreviewEnvironment, conversationChannel, createMockConversationsApi, createMockEventSource, createMockSSEProvider, createPreviewBridgeClient, createPreviewMediaPoster, createPreviewMediaResolver, createPreviewMediaUploader, createPreviewStore, createPreviewWebhookClient, mediaTypeOf, previewFileBase64, previewFileUrl, resolvePreviewFileSample, signPreviewPayload, startPreviewScript };
@@ -1034,6 +1034,38 @@ function ConversationPreview({
1034
1034
  ] });
1035
1035
  }
1036
1036
 
1037
+ // src/preview/ConversationSimulatorPanel.tsx
1038
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1039
+ var DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS = {
1040
+ title: "Simulador do cliente",
1041
+ destinationHint: "entrega no webhook real",
1042
+ close: "Fechar simulador",
1043
+ placeholder: "Escreva como o cliente\u2026"
1044
+ };
1045
+ function ConversationSimulatorPanel({
1046
+ onClose,
1047
+ displayNumber,
1048
+ labels,
1049
+ headerActions,
1050
+ ...previewProps
1051
+ }) {
1052
+ const text = { ...DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS, ...labels };
1053
+ const subtitle = [displayNumber ?? previewProps.conversationId, text.destinationHint].join(" \xB7 ");
1054
+ return /* @__PURE__ */ jsxs2("aside", { className: "cv-simulator-panel", "aria-label": text.title, children: [
1055
+ /* @__PURE__ */ jsxs2("header", { className: "cv-simulator-panel__header", children: [
1056
+ /* @__PURE__ */ jsxs2("div", { className: "cv-simulator-panel__heading", children: [
1057
+ /* @__PURE__ */ jsx2("h2", { className: "cv-simulator-panel__title", children: text.title }),
1058
+ /* @__PURE__ */ jsx2("p", { className: "cv-simulator-panel__subtitle", children: subtitle })
1059
+ ] }),
1060
+ /* @__PURE__ */ jsxs2("div", { className: "cv-simulator-panel__actions", children: [
1061
+ headerActions,
1062
+ /* @__PURE__ */ jsx2("button", { type: "button", onClick: onClose, title: text.close, "aria-label": text.close, className: "cv-simulator-panel__close", children: /* @__PURE__ */ jsx2("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("path", { d: "M18 6 6 18M6 6l12 12" }) }) })
1063
+ ] })
1064
+ ] }),
1065
+ /* @__PURE__ */ jsx2("div", { className: "cv-simulator-panel__body", children: /* @__PURE__ */ jsx2(ConversationPreview, { ...previewProps, placeholder: text.placeholder }) })
1066
+ ] });
1067
+ }
1068
+
1037
1069
  // src/preview/createPreviewWebhookClient.ts
1038
1070
  import {
1039
1071
  buildInboundAudioPayload,
@@ -1244,7 +1276,7 @@ function startPreviewScript(params) {
1244
1276
 
1245
1277
  // src/preview/MediaTypesPreview.tsx
1246
1278
  import { useMemo as useMemo2 } from "react";
1247
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1279
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1248
1280
  var MEDIA_TYPES_CONVERSATION_ID = "5511944443333";
1249
1281
  function MediaTypesPreview({
1250
1282
  conversationId = MEDIA_TYPES_CONVERSATION_ID,
@@ -1259,26 +1291,26 @@ function MediaTypesPreview({
1259
1291
  const messages = PREVIEW_MESSAGES[conversationId] ?? [];
1260
1292
  const documents = PREVIEW_DOCUMENTS[conversationId] ?? [];
1261
1293
  const mimeTypes = [...new Set(documents.map((document) => document.mimeType))];
1262
- return /* @__PURE__ */ jsx2(ConversationsProvider, { api, sse, children: /* @__PURE__ */ jsxs2("div", { className, children: [
1263
- /* @__PURE__ */ jsxs2("header", { className: "border-b px-4 py-3 dark:border-gray-700", children: [
1264
- /* @__PURE__ */ jsx2("h1", { className: "text-lg font-semibold", children: "Teste manual de m\xEDdia" }),
1265
- /* @__PURE__ */ jsxs2("p", { className: "text-sm text-gray-500", children: [
1294
+ return /* @__PURE__ */ jsx3(ConversationsProvider, { api, sse, children: /* @__PURE__ */ jsxs3("div", { className, children: [
1295
+ /* @__PURE__ */ jsxs3("header", { className: "border-b px-4 py-3 dark:border-gray-700", children: [
1296
+ /* @__PURE__ */ jsx3("h1", { className: "text-lg font-semibold", children: "Teste manual de m\xEDdia" }),
1297
+ /* @__PURE__ */ jsxs3("p", { className: "text-sm text-gray-500", children: [
1266
1298
  documents.length,
1267
1299
  " arquivos, ",
1268
1300
  mimeTypes.length,
1269
1301
  " tipos. Clique no olho para abrir em aba nova e no bot\xE3o da bolha para carregar a m\xEDdia na thread \u2014 \xE9 o que teste automatizado n\xE3o v\xEA."
1270
1302
  ] })
1271
1303
  ] }),
1272
- /* @__PURE__ */ jsxs2("div", { className: "grid gap-4 p-4 lg:grid-cols-2", children: [
1273
- /* @__PURE__ */ jsxs2("section", { className: "space-y-3", children: [
1274
- /* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Biblioteca da empresa" }),
1275
- /* @__PURE__ */ jsx2(DocumentsLibrary, { perPage: documents.length || 20 })
1304
+ /* @__PURE__ */ jsxs3("div", { className: "grid gap-4 p-4 lg:grid-cols-2", children: [
1305
+ /* @__PURE__ */ jsxs3("section", { className: "space-y-3", children: [
1306
+ /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Biblioteca da empresa" }),
1307
+ /* @__PURE__ */ jsx3(DocumentsLibrary, { perPage: documents.length || 20 })
1276
1308
  ] }),
1277
- /* @__PURE__ */ jsxs2("section", { className: "space-y-3", children: [
1278
- /* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Painel da conversa" }),
1279
- /* @__PURE__ */ jsx2(ConversationDocumentsPanel, { conversationId, open: true, perPage: documents.length || 20 }),
1280
- /* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Bolhas na thread" }),
1281
- /* @__PURE__ */ jsx2(ConversationWallpaper, { className: "max-h-[70vh] overflow-y-auto rounded-lg px-3 py-2", children: messages.map((message, index) => /* @__PURE__ */ jsx2(
1309
+ /* @__PURE__ */ jsxs3("section", { className: "space-y-3", children: [
1310
+ /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Painel da conversa" }),
1311
+ /* @__PURE__ */ jsx3(ConversationDocumentsPanel, { conversationId, open: true, perPage: documents.length || 20 }),
1312
+ /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Bolhas na thread" }),
1313
+ /* @__PURE__ */ jsx3(ConversationWallpaper, { className: "max-h-[70vh] overflow-y-auto rounded-lg px-3 py-2", children: messages.map((message, index) => /* @__PURE__ */ jsx3(
1282
1314
  MessageBubble,
1283
1315
  {
1284
1316
  message,
@@ -1294,7 +1326,9 @@ function MediaTypesPreview({
1294
1326
  export {
1295
1327
  AudioRecorderButton,
1296
1328
  ConversationPreview,
1329
+ ConversationSimulatorPanel,
1297
1330
  DEFAULT_AUDIO_RECORDER_BUTTON_LABELS,
1331
+ DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS,
1298
1332
  DEFAULT_MEDIA_UPLOAD_PATH,
1299
1333
  DEFAULT_PREVIEW_SCRIPT,
1300
1334
  GLOBAL_CHANNEL,
package/dist/styles.css CHANGED
@@ -237,3 +237,562 @@
237
237
  :where(button:not(:disabled), [role=button]:not(:disabled), summary) {
238
238
  cursor: pointer;
239
239
  }
240
+ .cv-simulator-panel {
241
+ display: flex;
242
+ flex-direction: column;
243
+ width: 24rem;
244
+ flex-shrink: 0;
245
+ border-left: 1px solid rgb(229 231 235);
246
+ background: #fff;
247
+ }
248
+ .cv-simulator-panel__header {
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: space-between;
252
+ gap: 0.5rem;
253
+ padding: 0.75rem 1rem;
254
+ border-bottom: 1px solid rgb(229 231 235);
255
+ }
256
+ .cv-simulator-panel__heading {
257
+ min-width: 0;
258
+ }
259
+ .cv-simulator-panel__title {
260
+ font-size: 0.875rem;
261
+ font-weight: 600;
262
+ color: rgb(17 24 39);
263
+ overflow: hidden;
264
+ text-overflow: ellipsis;
265
+ white-space: nowrap;
266
+ }
267
+ .cv-simulator-panel__subtitle {
268
+ font-size: 0.75rem;
269
+ color: rgb(156 163 175);
270
+ overflow: hidden;
271
+ text-overflow: ellipsis;
272
+ white-space: nowrap;
273
+ }
274
+ .cv-simulator-panel__actions {
275
+ display: flex;
276
+ align-items: center;
277
+ gap: 0.25rem;
278
+ }
279
+ .cv-simulator-panel__close {
280
+ display: inline-flex;
281
+ padding: 0.375rem;
282
+ border: 0;
283
+ border-radius: 0.5rem;
284
+ background: transparent;
285
+ color: rgb(156 163 175);
286
+ transition: color 150ms, background-color 150ms;
287
+ }
288
+ .cv-simulator-panel__close:hover {
289
+ color: rgb(55 65 81);
290
+ background: rgb(243 244 246);
291
+ }
292
+ .cv-simulator-panel__body {
293
+ flex: 1;
294
+ min-height: 0;
295
+ }
296
+ .dark .cv-simulator-panel {
297
+ border-left-color: rgb(31 41 55);
298
+ background: rgb(17 24 39);
299
+ }
300
+ .dark .cv-simulator-panel__header {
301
+ border-bottom-color: rgb(31 41 55);
302
+ }
303
+ .dark .cv-simulator-panel__title {
304
+ color: rgb(243 244 246);
305
+ }
306
+ .dark .cv-simulator-panel__subtitle {
307
+ color: rgb(107 114 128);
308
+ }
309
+ .dark .cv-simulator-panel__close:hover {
310
+ color: rgb(229 231 235);
311
+ background: rgb(31 41 55);
312
+ }
313
+ @media (max-width: 1023px) {
314
+ .cv-simulator-panel {
315
+ position: fixed;
316
+ inset: 0;
317
+ width: 100%;
318
+ z-index: 40;
319
+ border-left: 0;
320
+ }
321
+ }
322
+ .cv-workspace {
323
+ display: flex;
324
+ flex-direction: column;
325
+ height: 100%;
326
+ min-height: 0;
327
+ }
328
+ .cv-workspace-header {
329
+ display: flex;
330
+ align-items: center;
331
+ justify-content: space-between;
332
+ gap: 0.5rem;
333
+ padding: 0.75rem 1rem;
334
+ border-bottom: 1px solid rgb(229 231 235);
335
+ }
336
+ .dark .cv-workspace-header {
337
+ border-color: rgb(51 65 85);
338
+ }
339
+ .cv-workspace-header__titles {
340
+ min-width: 0;
341
+ }
342
+ .cv-workspace-header__titles h1 {
343
+ font-size: 1.125rem;
344
+ font-weight: 600;
345
+ overflow: hidden;
346
+ text-overflow: ellipsis;
347
+ white-space: nowrap;
348
+ }
349
+ .cv-workspace-header__titles p {
350
+ display: flex;
351
+ flex-wrap: wrap;
352
+ gap: 0.25rem 0.75rem;
353
+ font-size: 0.875rem;
354
+ color: rgb(107 114 128);
355
+ }
356
+ .cv-workspace-header__waiting {
357
+ color: rgb(217 119 6);
358
+ }
359
+ .dark .cv-workspace-header__waiting {
360
+ color: rgb(251 191 36);
361
+ }
362
+ .cv-workspace-header__actions {
363
+ display: flex;
364
+ flex-shrink: 0;
365
+ align-items: center;
366
+ gap: 0.5rem;
367
+ }
368
+ .cv-workspace-toggle {
369
+ border: 1px solid rgb(229 231 235);
370
+ border-radius: 0.375rem;
371
+ padding: 0.5rem 0.75rem;
372
+ font-size: 0.875rem;
373
+ min-height: 2.75rem;
374
+ }
375
+ .cv-workspace-toggle:disabled {
376
+ opacity: 0.5;
377
+ }
378
+ .cv-workspace-toggle--on {
379
+ background: rgb(37 99 235);
380
+ color: #fff;
381
+ border-color: rgb(37 99 235);
382
+ }
383
+ .dark .cv-workspace-toggle {
384
+ border-color: rgb(71 85 105);
385
+ color: rgb(226 232 240);
386
+ }
387
+ .cv-workspace-failure {
388
+ border-bottom: 1px solid rgb(253 230 138);
389
+ background: rgb(255 251 235);
390
+ padding: 0.5rem 1rem;
391
+ font-size: 0.875rem;
392
+ color: rgb(146 64 14);
393
+ }
394
+ .dark .cv-workspace-failure {
395
+ background: rgb(69 26 3);
396
+ color: rgb(253 230 138);
397
+ border-color: rgb(120 53 15);
398
+ }
399
+ .cv-workspace-grid {
400
+ display: grid;
401
+ flex: 1;
402
+ min-height: 0;
403
+ grid-template-columns: minmax(0, 1fr);
404
+ gap: 0.75rem;
405
+ padding: 0.75rem;
406
+ background: rgb(243 244 246);
407
+ }
408
+ .dark .cv-workspace-grid {
409
+ background: rgb(17 24 39);
410
+ }
411
+ .cv-workspace-list,
412
+ .cv-workspace-detail,
413
+ .cv-workspace-simulator {
414
+ display: flex;
415
+ flex-direction: column;
416
+ min-height: 0;
417
+ min-width: 0;
418
+ overflow: hidden;
419
+ border: 1px solid rgb(229 231 235);
420
+ border-radius: 0.75rem;
421
+ background: #fff;
422
+ }
423
+ .dark .cv-workspace-list,
424
+ .dark .cv-workspace-detail,
425
+ .dark .cv-workspace-simulator {
426
+ background: rgb(31 41 55);
427
+ border-color: rgb(51 65 85);
428
+ }
429
+ .cv-workspace-simulator {
430
+ flex-direction: row;
431
+ }
432
+ @media (max-width: 1023px) {
433
+ .cv-workspace-grid[data-detail=open] .cv-workspace-list {
434
+ display: none;
435
+ }
436
+ .cv-workspace-grid[data-detail=closed] .cv-workspace-detail {
437
+ display: none;
438
+ }
439
+ }
440
+ @media (min-width: 1024px) {
441
+ .cv-workspace-grid {
442
+ grid-template-columns: 360px minmax(0, 1fr);
443
+ }
444
+ .cv-workspace-grid--with-simulator {
445
+ grid-template-columns: minmax(0, 1fr) 24rem;
446
+ }
447
+ .cv-workspace-grid--with-simulator .cv-workspace-list {
448
+ display: none;
449
+ }
450
+ }
451
+ @media (min-width: 1280px) {
452
+ .cv-workspace-grid--with-simulator {
453
+ grid-template-columns: 320px minmax(0, 1fr) 24rem;
454
+ }
455
+ .cv-workspace-grid--with-simulator .cv-workspace-list {
456
+ display: flex;
457
+ }
458
+ }
459
+ .cv-workspace-pane {
460
+ display: flex;
461
+ flex-direction: column;
462
+ height: 100%;
463
+ min-height: 0;
464
+ }
465
+ .cv-workspace-transcript {
466
+ position: relative;
467
+ flex: 1;
468
+ min-height: 0;
469
+ overflow-y: auto;
470
+ padding: 0.75rem 1rem;
471
+ }
472
+ .cv-workspace-failure__link {
473
+ text-decoration: underline;
474
+ }
475
+ .cv-workspace-selection {
476
+ display: flex;
477
+ align-items: center;
478
+ justify-content: space-between;
479
+ gap: 0.5rem;
480
+ border-top: 1px solid #bfdbfe;
481
+ background: #eff6ff;
482
+ padding: 0.5rem 0.75rem;
483
+ font-size: 0.8125rem;
484
+ color: #1d4ed8;
485
+ }
486
+ .cv-workspace-selection__actions {
487
+ display: flex;
488
+ gap: 0.5rem;
489
+ }
490
+ .cv-workspace-selection__actions button {
491
+ min-height: 2.75rem;
492
+ border-radius: 0.375rem;
493
+ border: 1px solid #bfdbfe;
494
+ padding: 0 0.625rem;
495
+ }
496
+ .dark .cv-workspace-selection {
497
+ border-color: #1e40af;
498
+ background: rgb(23 37 84 / 40%);
499
+ color: #93c5fd;
500
+ }
501
+ .dark .cv-workspace-selection__actions button {
502
+ border-color: #1e40af;
503
+ }
504
+ .cv-workspace-notice {
505
+ border-top: 1px solid var(--cv-border, #e5e7eb);
506
+ background: #f3f4f6;
507
+ padding: 0.75rem 1rem;
508
+ text-align: center;
509
+ font-size: 0.875rem;
510
+ color: #6b7280;
511
+ }
512
+ .dark .cv-workspace-notice {
513
+ border-top-color: #374151;
514
+ background: #1f2937;
515
+ color: #9ca3af;
516
+ }
517
+ .cv-workspace-alert {
518
+ border-top: 1px solid rgb(254 202 202);
519
+ background: rgb(254 242 242);
520
+ padding: 0.5rem 1rem;
521
+ font-size: 0.875rem;
522
+ color: rgb(185 28 28);
523
+ }
524
+ .dark .cv-workspace-alert {
525
+ background: rgb(69 10 10);
526
+ color: rgb(252 165 165);
527
+ border-color: rgb(127 29 29);
528
+ }
529
+ .cv-workspace-filters {
530
+ display: flex;
531
+ flex-direction: column;
532
+ gap: 0.5rem;
533
+ padding: 0.75rem;
534
+ border-bottom: 1px solid rgb(229 231 235);
535
+ }
536
+ .dark .cv-workspace-filters {
537
+ border-color: rgb(51 65 85);
538
+ }
539
+ .cv-workspace-search {
540
+ width: 100%;
541
+ border: 1px solid rgb(229 231 235);
542
+ border-radius: 0.375rem;
543
+ padding: 0.5rem 0.75rem;
544
+ font-size: 0.875rem;
545
+ background: transparent;
546
+ }
547
+ .dark .cv-workspace-search {
548
+ border-color: rgb(71 85 105);
549
+ color: rgb(226 232 240);
550
+ }
551
+ .cv-workspace-chips {
552
+ display: flex;
553
+ flex-wrap: wrap;
554
+ align-items: center;
555
+ gap: 0.5rem;
556
+ font-size: 0.75rem;
557
+ }
558
+ .cv-workspace-chips__legend {
559
+ color: rgb(107 114 128);
560
+ }
561
+ .cv-workspace-chip {
562
+ display: flex;
563
+ align-items: center;
564
+ gap: 0.25rem;
565
+ border-radius: 0.375rem;
566
+ padding: 0.25rem 0.5rem;
567
+ }
568
+ .cv-workspace-chip--on {
569
+ background: rgb(229 231 235);
570
+ }
571
+ .dark .cv-workspace-chip--on {
572
+ background: rgb(51 65 85);
573
+ }
574
+ .cv-workspace-dot {
575
+ width: 0.5rem;
576
+ height: 0.5rem;
577
+ border-radius: 9999px;
578
+ }
579
+ .cv-workspace-selectall {
580
+ display: flex;
581
+ align-items: center;
582
+ gap: 0.5rem;
583
+ font-size: 0.75rem;
584
+ }
585
+ .cv-workspace-rows {
586
+ flex: 1;
587
+ min-height: 0;
588
+ overflow-y: auto;
589
+ }
590
+ .cv-workspace-empty {
591
+ padding: 1rem;
592
+ font-size: 0.875rem;
593
+ color: rgb(107 114 128);
594
+ }
595
+ .cv-workspace-bulk {
596
+ display: flex;
597
+ flex-wrap: wrap;
598
+ align-items: center;
599
+ justify-content: space-between;
600
+ gap: 0.5rem;
601
+ padding: 0.5rem 0.75rem;
602
+ border-bottom: 1px solid rgb(191 219 254);
603
+ background: rgb(239 246 255);
604
+ font-size: 0.75rem;
605
+ }
606
+ .dark .cv-workspace-bulk {
607
+ background: rgb(23 37 84);
608
+ border-color: rgb(30 58 138);
609
+ }
610
+ .cv-workspace-bulk__count {
611
+ font-weight: 500;
612
+ color: rgb(29 78 216);
613
+ }
614
+ .dark .cv-workspace-bulk__count {
615
+ color: rgb(147 197 253);
616
+ }
617
+ .cv-workspace-bulk__actions {
618
+ display: flex;
619
+ flex-wrap: wrap;
620
+ gap: 0.5rem;
621
+ }
622
+ .cv-workspace-bulk__actions button {
623
+ border: 1px solid rgb(191 219 254);
624
+ border-radius: 0.375rem;
625
+ padding: 0.25rem 0.5rem;
626
+ }
627
+ .cv-workspace-bulk__actions button:disabled {
628
+ opacity: 0.5;
629
+ }
630
+ .cv-workspace-pager {
631
+ display: flex;
632
+ align-items: center;
633
+ justify-content: space-between;
634
+ gap: 0.5rem;
635
+ border-top: 1px solid rgb(229 231 235);
636
+ padding: 0.5rem 0.75rem;
637
+ font-size: 0.75rem;
638
+ color: rgb(107 114 128);
639
+ }
640
+ .dark .cv-workspace-pager {
641
+ border-color: rgb(51 65 85);
642
+ }
643
+ .cv-workspace-pager__buttons {
644
+ display: flex;
645
+ align-items: center;
646
+ gap: 0.25rem;
647
+ }
648
+ .cv-workspace-pager__buttons button {
649
+ padding: 0 0.5rem;
650
+ }
651
+ .cv-workspace-pager__buttons button:disabled {
652
+ opacity: 0.4;
653
+ }
654
+ .cv-workspace-modal {
655
+ position: fixed;
656
+ inset: 0;
657
+ z-index: 50;
658
+ display: flex;
659
+ align-items: center;
660
+ justify-content: center;
661
+ padding: 1rem;
662
+ background: rgb(0 0 0 / 50%);
663
+ }
664
+ .cv-workspace-modal__box {
665
+ display: flex;
666
+ width: 100%;
667
+ max-width: 28rem;
668
+ max-height: 80vh;
669
+ flex-direction: column;
670
+ overflow: hidden;
671
+ border-radius: 0.75rem;
672
+ border: 1px solid #e5e7eb;
673
+ background: #fff;
674
+ box-shadow: 0 20px 25px -5px rgb(0 0 0 / 25%);
675
+ }
676
+ .cv-workspace-modal__header {
677
+ display: flex;
678
+ align-items: flex-start;
679
+ justify-content: space-between;
680
+ gap: 0.75rem;
681
+ border-bottom: 1px solid #e5e7eb;
682
+ padding: 1rem 1.25rem;
683
+ }
684
+ .cv-workspace-modal__header h3 {
685
+ font-weight: 600;
686
+ }
687
+ .cv-workspace-modal__header p {
688
+ margin-top: 0.125rem;
689
+ font-size: 0.75rem;
690
+ color: #6b7280;
691
+ }
692
+ .cv-workspace-modal__search {
693
+ border-bottom: 1px solid #f3f4f6;
694
+ padding: 0.75rem 1rem;
695
+ }
696
+ .cv-workspace-modal__search input {
697
+ width: 100%;
698
+ border-radius: 0.5rem;
699
+ border: 1px solid #e5e7eb;
700
+ padding: 0.5rem 0.75rem;
701
+ font-size: 0.875rem;
702
+ }
703
+ .cv-workspace-modal__list {
704
+ flex: 1;
705
+ overflow-y: auto;
706
+ padding: 0.5rem;
707
+ }
708
+ .cv-workspace-modal__item {
709
+ display: flex;
710
+ width: 100%;
711
+ flex-direction: column;
712
+ gap: 0.125rem;
713
+ border: 1px solid transparent;
714
+ border-radius: 0.5rem;
715
+ padding: 0.625rem 0.75rem;
716
+ text-align: left;
717
+ font-size: 0.875rem;
718
+ }
719
+ .cv-workspace-modal__item:hover {
720
+ background: #f9fafb;
721
+ }
722
+ .cv-workspace-modal__item--on {
723
+ border-color: #bfdbfe;
724
+ background: #eff6ff;
725
+ color: #1d4ed8;
726
+ }
727
+ .cv-workspace-modal__item-name {
728
+ overflow: hidden;
729
+ text-overflow: ellipsis;
730
+ white-space: nowrap;
731
+ font-weight: 500;
732
+ }
733
+ .cv-workspace-modal__item-meta {
734
+ font-size: 0.75rem;
735
+ color: #9ca3af;
736
+ }
737
+ .cv-workspace-modal__warning {
738
+ border-top: 1px solid #fde68a;
739
+ background: #fffbeb;
740
+ padding: 0.5rem 1rem;
741
+ font-size: 0.75rem;
742
+ color: #b45309;
743
+ }
744
+ .cv-workspace-modal__footer {
745
+ display: flex;
746
+ justify-content: flex-end;
747
+ gap: 0.5rem;
748
+ border-top: 1px solid #e5e7eb;
749
+ padding: 0.75rem 1rem;
750
+ }
751
+ .cv-workspace-modal__footer button {
752
+ min-height: 2.75rem;
753
+ border-radius: 0.5rem;
754
+ border: 1px solid #e5e7eb;
755
+ padding: 0 0.875rem;
756
+ font-size: 0.875rem;
757
+ }
758
+ .cv-workspace-modal__footer button:last-child {
759
+ border-color: transparent;
760
+ background: #2563eb;
761
+ color: #fff;
762
+ }
763
+ .cv-workspace-modal__footer button:disabled {
764
+ opacity: 0.5;
765
+ }
766
+ .dark .cv-workspace-modal__box {
767
+ border-color: #374151;
768
+ background: #1f2937;
769
+ }
770
+ .dark .cv-workspace-modal__header,
771
+ .dark .cv-workspace-modal__footer {
772
+ border-color: #374151;
773
+ }
774
+ .dark .cv-workspace-modal__search {
775
+ border-color: #374151;
776
+ }
777
+ .dark .cv-workspace-modal__search input {
778
+ border-color: #4b5563;
779
+ background: #374151;
780
+ color: #f3f4f6;
781
+ }
782
+ .dark .cv-workspace-modal__item:hover {
783
+ background: rgb(55 65 81 / 50%);
784
+ }
785
+ .dark .cv-workspace-modal__item--on {
786
+ border-color: #1e40af;
787
+ background: rgb(23 37 84 / 40%);
788
+ color: #93c5fd;
789
+ }
790
+ .dark .cv-workspace-modal__warning {
791
+ border-color: #92400e;
792
+ background: rgb(69 26 3 / 40%);
793
+ color: #fbbf24;
794
+ }
795
+ .dark .cv-workspace-modal__footer button {
796
+ border-color: #4b5563;
797
+ color: #f3f4f6;
798
+ }