@wakastellar/ui 3.3.3 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/badge-BbwO7QeZ.js +1 -0
- package/dist/badge-BfiocODp.mjs +23 -0
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.es.js +1 -1
- package/dist/chunk-14q5BKub.js +1 -0
- package/dist/{chunk-BH6uBOac.mjs → chunk-Cr9pTUWm.mjs} +5 -5
- package/dist/cn-DEtaFQsA.js +1 -0
- package/dist/cn-DUn6aSIQ.mjs +24 -0
- package/dist/doc.cjs.js +2 -2
- package/dist/doc.es.js +19 -19
- package/dist/editor.cjs.js +48 -0
- package/dist/editor.d.ts +1 -0
- package/dist/editor.es.js +6551 -0
- package/dist/{exceljs.min-DG9M8IZ1.mjs → exceljs.min-DL1XYDll.mjs} +1 -1
- package/dist/{exceljs.min-BuefmDRS.js → exceljs.min-qeIfSCbF.js} +1 -1
- package/dist/export.cjs.js +1 -1
- package/dist/export.es.js +1 -1
- package/dist/index.cjs.js +150 -150
- package/dist/index.es.js +26782 -27591
- package/dist/input-BfaSAGVw.js +1 -0
- package/dist/input-DVr_Qkl8.mjs +14 -0
- package/dist/rich-text.cjs.js +1 -1
- package/dist/rich-text.es.js +1 -1
- package/dist/security-CyBpuklN.mjs +122 -0
- package/dist/security-bFWwDrlg.js +1 -0
- package/dist/separator-NrkltulH.js +1 -0
- package/dist/separator-ibN2mycs.mjs +51 -0
- package/dist/src/components/editor/blocks/index.d.ts +51 -0
- package/dist/src/components/editor/blocks/waka-acceptance-criteria-block.d.ts +60 -0
- package/dist/src/components/editor/blocks/waka-ai-assist-block.d.ts +58 -0
- package/dist/src/components/editor/blocks/waka-api-endpoint-block.d.ts +63 -0
- package/dist/src/components/editor/blocks/waka-code-playground-block.d.ts +61 -0
- package/dist/src/components/editor/blocks/waka-comment-thread-block.d.ts +85 -0
- package/dist/src/components/editor/blocks/waka-diagram-block.d.ts +52 -0
- package/dist/src/components/editor/blocks/waka-embed-block.d.ts +58 -0
- package/dist/src/components/editor/blocks/waka-slash-menu-block.d.ts +67 -0
- package/dist/src/components/editor/blocks/waka-user-story-block.d.ts +79 -0
- package/dist/src/components/editor/blocks/waka-version-diff-block.d.ts +73 -0
- package/dist/src/components/editor/index.d.ts +66 -0
- package/dist/src/components/editor/waka-ai-writer.d.ts +80 -0
- package/dist/src/components/editor/waka-collaborative-editor.d.ts +93 -0
- package/dist/src/components/editor/waka-diff-viewer.d.ts +71 -0
- package/dist/src/components/editor/waka-dnd-editor.d.ts +64 -0
- package/dist/src/components/editor/waka-document-editor.d.ts +92 -0
- package/dist/src/components/editor/waka-editor-elements.d.ts +79 -0
- package/dist/src/components/editor/waka-editor-leaves.d.ts +39 -0
- package/dist/src/components/editor/waka-editor-plugins.d.ts +41 -0
- package/dist/src/components/editor/waka-editor-toolbar.d.ts +20 -0
- package/dist/src/components/editor/waka-editor.d.ts +59 -0
- package/dist/src/components/editor/waka-floating-toolbar.d.ts +47 -0
- package/dist/src/components/editor/waka-markdown-editor.d.ts +60 -0
- package/dist/src/components/editor/waka-mention-editor.d.ts +125 -0
- package/dist/src/components/editor/waka-slash-menu.d.ts +70 -0
- package/dist/src/components/editor/waka-spec-editor.d.ts +88 -0
- package/dist/src/components/index.d.ts +1 -15
- package/dist/src/editor.d.ts +26 -0
- package/dist/textarea-CdQWggYG.js +1 -0
- package/dist/textarea-DJDXJ3nd.mjs +23 -0
- package/dist/types-C2St0wOW.js +1 -0
- package/dist/{types-B6GVaSIP.mjs → types-JnqoLyuv.mjs} +214 -211
- package/dist/{useDataTableImport-BPvfo--2.mjs → useDataTableImport-BWUFesPi.mjs} +3 -3
- package/dist/{useDataTableImport-Cm_pCKnO.js → useDataTableImport-T7ddpN5k.js} +3 -3
- package/dist/waka-doc-renderer-CTxC7Trf.js +3 -0
- package/dist/{waka-doc-renderer-BkIvas3z.mjs → waka-doc-renderer-Cw-Xnyen.mjs} +264 -281
- package/dist/waka-editor-plugins-DR6tpsUC.mjs +135 -0
- package/dist/waka-editor-plugins-sGSh9hn2.js +1 -0
- package/dist/waka-rich-text-editor-BlIdtknG.js +1 -0
- package/dist/waka-rich-text-editor-D1uA3zbB.js +1 -0
- package/dist/waka-rich-text-editor-DgSWiXMW.mjs +342 -0
- package/dist/waka-rich-text-editor-DndVJuDw.mjs +2 -0
- package/package.json +87 -2
- package/src/blocks/footer/index.tsx +1 -6
- package/src/blocks/login/index.tsx +1 -7
- package/src/blocks/profile/index.tsx +3 -5
- package/src/components/editor/blocks/index.ts +182 -0
- package/src/components/editor/blocks/waka-acceptance-criteria-block.tsx +326 -0
- package/src/components/editor/blocks/waka-ai-assist-block.tsx +284 -0
- package/src/components/editor/blocks/waka-api-endpoint-block.tsx +382 -0
- package/src/components/editor/blocks/waka-code-playground-block.tsx +331 -0
- package/src/components/editor/blocks/waka-comment-thread-block.tsx +448 -0
- package/src/components/editor/blocks/waka-diagram-block.tsx +293 -0
- package/src/components/editor/blocks/waka-embed-block.tsx +416 -0
- package/src/components/editor/blocks/waka-slash-menu-block.tsx +432 -0
- package/src/components/editor/blocks/waka-user-story-block.tsx +295 -0
- package/src/components/editor/blocks/waka-version-diff-block.tsx +426 -0
- package/src/components/editor/index.ts +279 -0
- package/src/components/editor/waka-ai-writer.tsx +434 -0
- package/src/components/editor/waka-collaborative-editor.tsx +426 -0
- package/src/components/editor/waka-diff-viewer.tsx +352 -0
- package/src/components/editor/waka-dnd-editor.tsx +284 -0
- package/src/components/editor/waka-document-editor.tsx +502 -0
- package/src/components/editor/waka-editor-elements.tsx +312 -0
- package/src/components/editor/waka-editor-leaves.tsx +101 -0
- package/src/components/editor/waka-editor-plugins.ts +207 -0
- package/src/components/editor/waka-editor-toolbar.tsx +358 -0
- package/src/components/editor/waka-editor.tsx +431 -0
- package/src/components/editor/waka-floating-toolbar.tsx +268 -0
- package/src/components/editor/waka-markdown-editor.tsx +395 -0
- package/src/components/editor/waka-mention-editor.tsx +459 -0
- package/src/components/editor/waka-slash-menu.tsx +392 -0
- package/src/components/editor/waka-spec-editor.tsx +657 -0
- package/src/components/index.ts +1 -18
- package/dist/chunk-BDDJmn7V.js +0 -1
- package/dist/cn-DnPbmOCy.js +0 -1
- package/dist/cn-DpLcAzrf.mjs +0 -22
- package/dist/separator-BDReXBvI.mjs +0 -59
- package/dist/separator-BKjNl9sI.js +0 -1
- package/dist/src/components/waka-actor-badge/index.d.ts +0 -8
- package/dist/src/components/waka-actors-list/index.d.ts +0 -18
- package/dist/src/components/waka-ai-assistant-button/index.d.ts +0 -8
- package/dist/src/components/waka-document-flyover/index.d.ts +0 -10
- package/dist/src/components/waka-document-preview-popup/index.d.ts +0 -26
- package/dist/src/components/waka-hour-balance-badge/index.d.ts +0 -8
- package/dist/src/components/waka-hour-consumption-table/index.d.ts +0 -15
- package/dist/src/components/waka-hour-pack-dialog/index.d.ts +0 -8
- package/dist/src/components/waka-project-stats-header/index.d.ts +0 -15
- package/dist/src/components/waka-step-comment-bubble/index.d.ts +0 -13
- package/dist/src/components/waka-step-comment-panel/index.d.ts +0 -20
- package/dist/src/components/waka-step-permission-matrix/index.d.ts +0 -12
- package/dist/src/components/waka-time-entry-dialog/index.d.ts +0 -16
- package/dist/src/components/waka-time-tracking-flyover/index.d.ts +0 -11
- package/dist/types-BH9cQRqZ.js +0 -1
- package/dist/waka-doc-renderer-BZ2-SqyT.js +0 -3
- package/dist/waka-rich-text-editor-BJGlQgpq.js +0 -1
- package/dist/waka-rich-text-editor-BJzzxeP1.mjs +0 -361
- package/dist/waka-rich-text-editor-wnXLwvUo.js +0 -1
- package/src/components/waka-actor-badge/index.tsx +0 -34
- package/src/components/waka-actors-list/index.tsx +0 -125
- package/src/components/waka-ai-assistant-button/index.tsx +0 -31
- package/src/components/waka-document-flyover/index.tsx +0 -36
- package/src/components/waka-document-preview-popup/index.tsx +0 -103
- package/src/components/waka-hour-balance-badge/index.tsx +0 -43
- package/src/components/waka-hour-consumption-table/index.tsx +0 -72
- package/src/components/waka-hour-pack-dialog/index.tsx +0 -72
- package/src/components/waka-project-stats-header/index.tsx +0 -69
- package/src/components/waka-step-comment-bubble/index.tsx +0 -71
- package/src/components/waka-step-comment-panel/index.tsx +0 -106
- package/src/components/waka-step-permission-matrix/index.tsx +0 -65
- package/src/components/waka-time-entry-dialog/index.tsx +0 -131
- package/src/components/waka-time-tracking-flyover/index.tsx +0 -41
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import {
|
|
5
|
+
BookOpen,
|
|
6
|
+
CheckCircle2,
|
|
7
|
+
GitBranch,
|
|
8
|
+
Users,
|
|
9
|
+
AlertTriangle,
|
|
10
|
+
Shield,
|
|
11
|
+
Zap,
|
|
12
|
+
Database,
|
|
13
|
+
type LucideIcon,
|
|
14
|
+
} from "lucide-react"
|
|
15
|
+
import { cn } from "../../utils/cn"
|
|
16
|
+
import { Label } from "../label"
|
|
17
|
+
import { Textarea } from "../textarea"
|
|
18
|
+
|
|
19
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
type SlateNode = any
|
|
23
|
+
|
|
24
|
+
/** A predefined spec block template */
|
|
25
|
+
export interface SpecBlockTemplate {
|
|
26
|
+
/** Unique key */
|
|
27
|
+
key: string
|
|
28
|
+
/** Display label */
|
|
29
|
+
label: string
|
|
30
|
+
/** Description for the slash menu */
|
|
31
|
+
description: string
|
|
32
|
+
/** Lucide icon */
|
|
33
|
+
icon: LucideIcon
|
|
34
|
+
/** Category for grouping */
|
|
35
|
+
category: string
|
|
36
|
+
/** Generates the Slate nodes for this block */
|
|
37
|
+
createNodes: () => SlateNode[]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface WakaSpecEditorProps {
|
|
41
|
+
/** Initial Slate content */
|
|
42
|
+
value?: SlateNode[]
|
|
43
|
+
/** Change callback */
|
|
44
|
+
onChange?: (value: SlateNode[]) => void
|
|
45
|
+
/** Read-only mode */
|
|
46
|
+
readOnly?: boolean
|
|
47
|
+
/** Placeholder */
|
|
48
|
+
placeholder?: string
|
|
49
|
+
/** CSS class */
|
|
50
|
+
className?: string
|
|
51
|
+
/** Editor CSS class */
|
|
52
|
+
editorClassName?: string
|
|
53
|
+
/** Minimum height in px */
|
|
54
|
+
minHeight?: number
|
|
55
|
+
/** Label */
|
|
56
|
+
label?: string
|
|
57
|
+
/** Description */
|
|
58
|
+
description?: string
|
|
59
|
+
/** Error */
|
|
60
|
+
error?: string
|
|
61
|
+
/** Custom spec block templates (merged with defaults) */
|
|
62
|
+
customTemplates?: SpecBlockTemplate[]
|
|
63
|
+
/** Show the template insertion sidebar */
|
|
64
|
+
showTemplateSidebar?: boolean
|
|
65
|
+
/** Enable AI features for spec generation */
|
|
66
|
+
enableAI?: boolean
|
|
67
|
+
/** AI endpoint */
|
|
68
|
+
aiEndpoint?: string
|
|
69
|
+
/** Document title */
|
|
70
|
+
title?: string
|
|
71
|
+
/** Title change callback */
|
|
72
|
+
onTitleChange?: (title: string) => void
|
|
73
|
+
/** Extra Plate plugins */
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
|
+
extraPlugins?: any[]
|
|
76
|
+
/** Ref to editor instance */
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
editorRef?: React.MutableRefObject<any>
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ─── Default spec block templates ────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
/** Default specification block templates for WakaStart projects */
|
|
84
|
+
export const DEFAULT_SPEC_TEMPLATES: SpecBlockTemplate[] = [
|
|
85
|
+
{
|
|
86
|
+
key: "user-story",
|
|
87
|
+
label: "User Story",
|
|
88
|
+
description: "En tant que [role], je veux [action] afin de [benefice]",
|
|
89
|
+
icon: Users,
|
|
90
|
+
category: "Fonctionnel",
|
|
91
|
+
createNodes: () => [
|
|
92
|
+
{ type: "callout", variant: "info", children: [{ text: "" }] },
|
|
93
|
+
{ type: "h3", children: [{ text: "User Story" }] },
|
|
94
|
+
{ type: "p", children: [
|
|
95
|
+
{ text: "En tant que ", bold: true },
|
|
96
|
+
{ text: "[role]" },
|
|
97
|
+
]},
|
|
98
|
+
{ type: "p", children: [
|
|
99
|
+
{ text: "Je veux ", bold: true },
|
|
100
|
+
{ text: "[action]" },
|
|
101
|
+
]},
|
|
102
|
+
{ type: "p", children: [
|
|
103
|
+
{ text: "Afin de ", bold: true },
|
|
104
|
+
{ text: "[benefice attendu]" },
|
|
105
|
+
]},
|
|
106
|
+
{ type: "p", children: [{ text: "" }] },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: "acceptance-criteria",
|
|
111
|
+
label: "Criteres d'acceptation",
|
|
112
|
+
description: "Given/When/Then avec scenarios de validation",
|
|
113
|
+
icon: CheckCircle2,
|
|
114
|
+
category: "Fonctionnel",
|
|
115
|
+
createNodes: () => [
|
|
116
|
+
{ type: "h3", children: [{ text: "Criteres d'acceptation" }] },
|
|
117
|
+
{ type: "table", children: [
|
|
118
|
+
{ type: "tr", children: [
|
|
119
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "#", bold: true }] }] },
|
|
120
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Scenario", bold: true }] }] },
|
|
121
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Given", bold: true }] }] },
|
|
122
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "When", bold: true }] }] },
|
|
123
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Then", bold: true }] }] },
|
|
124
|
+
]},
|
|
125
|
+
{ type: "tr", children: [
|
|
126
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "AC-01" }] }] },
|
|
127
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Nominal" }] }] },
|
|
128
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "L'utilisateur est connecte" }] }] },
|
|
129
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Il clique sur le bouton" }] }] },
|
|
130
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Le resultat s'affiche" }] }] },
|
|
131
|
+
]},
|
|
132
|
+
{ type: "tr", children: [
|
|
133
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "AC-02" }] }] },
|
|
134
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Erreur" }] }] },
|
|
135
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Le service est indisponible" }] }] },
|
|
136
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Il clique sur le bouton" }] }] },
|
|
137
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Un message d'erreur s'affiche" }] }] },
|
|
138
|
+
]},
|
|
139
|
+
]},
|
|
140
|
+
{ type: "p", children: [{ text: "" }] },
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
key: "use-case",
|
|
145
|
+
label: "Cas d'utilisation",
|
|
146
|
+
description: "Acteur, pre-conditions, flux nominal, flux alternatifs",
|
|
147
|
+
icon: GitBranch,
|
|
148
|
+
category: "Fonctionnel",
|
|
149
|
+
createNodes: () => [
|
|
150
|
+
{ type: "h3", children: [{ text: "Cas d'utilisation : [Nom]" }] },
|
|
151
|
+
{ type: "column_group", children: [
|
|
152
|
+
{ type: "column", children: [
|
|
153
|
+
{ type: "h4", children: [{ text: "ACTEUR" }] },
|
|
154
|
+
{ type: "p", children: [{ text: "[Role utilisateur]" }] },
|
|
155
|
+
{ type: "h4", children: [{ text: "PRE-CONDITIONS" }] },
|
|
156
|
+
{ type: "p", children: [{ text: "- L'utilisateur est authentifie" }] },
|
|
157
|
+
{ type: "p", children: [{ text: "- [Autre condition]" }] },
|
|
158
|
+
{ type: "h4", children: [{ text: "POST-CONDITIONS" }] },
|
|
159
|
+
{ type: "p", children: [{ text: "- [Etat apres execution]" }] },
|
|
160
|
+
]},
|
|
161
|
+
{ type: "column", children: [
|
|
162
|
+
{ type: "h4", children: [{ text: "FLUX NOMINAL" }] },
|
|
163
|
+
{ type: "p", children: [{ text: "1. L'utilisateur accede a la page" }] },
|
|
164
|
+
{ type: "p", children: [{ text: "2. Le systeme affiche le formulaire" }] },
|
|
165
|
+
{ type: "p", children: [{ text: "3. L'utilisateur remplit et soumet" }] },
|
|
166
|
+
{ type: "p", children: [{ text: "4. Le systeme enregistre et confirme" }] },
|
|
167
|
+
{ type: "h4", children: [{ text: "FLUX ALTERNATIFS" }] },
|
|
168
|
+
{ type: "p", children: [{ text: "3a. Donnees invalides : erreur affichee" }] },
|
|
169
|
+
]},
|
|
170
|
+
]},
|
|
171
|
+
{ type: "p", children: [{ text: "" }] },
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
key: "api-endpoint",
|
|
176
|
+
label: "Endpoint API",
|
|
177
|
+
description: "Specification d'un endpoint REST avec requete/reponse",
|
|
178
|
+
icon: Zap,
|
|
179
|
+
category: "Technique",
|
|
180
|
+
createNodes: () => [
|
|
181
|
+
{ type: "h3", children: [{ text: "API: [METHOD] /api/v1/[resource]" }] },
|
|
182
|
+
{ type: "table", children: [
|
|
183
|
+
{ type: "tr", children: [
|
|
184
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Propriete", bold: true }] }] },
|
|
185
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Valeur", bold: true }] }] },
|
|
186
|
+
]},
|
|
187
|
+
{ type: "tr", children: [
|
|
188
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Methode" }] }] },
|
|
189
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "GET | POST | PUT | DELETE" }] }] },
|
|
190
|
+
]},
|
|
191
|
+
{ type: "tr", children: [
|
|
192
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Authentification" }] }] },
|
|
193
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Bearer JWT" }] }] },
|
|
194
|
+
]},
|
|
195
|
+
{ type: "tr", children: [
|
|
196
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Permissions" }] }] },
|
|
197
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "[ROLE_REQUIRED]" }] }] },
|
|
198
|
+
]},
|
|
199
|
+
{ type: "tr", children: [
|
|
200
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Rate Limit" }] }] },
|
|
201
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "100 req/min" }] }] },
|
|
202
|
+
]},
|
|
203
|
+
]},
|
|
204
|
+
{ type: "h4", children: [{ text: "CORPS DE LA REQUETE" }] },
|
|
205
|
+
{ type: "blockquote", children: [{ text: "{ \"field\": \"value\" }" }] },
|
|
206
|
+
{ type: "h4", children: [{ text: "REPONSE 200" }] },
|
|
207
|
+
{ type: "blockquote", children: [{ text: "{ \"data\": { ... }, \"meta\": { \"total\": 42 } }" }] },
|
|
208
|
+
{ type: "p", children: [{ text: "" }] },
|
|
209
|
+
],
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
key: "data-model",
|
|
213
|
+
label: "Modele de donnees",
|
|
214
|
+
description: "Schema d'entite avec champs, types et contraintes",
|
|
215
|
+
icon: Database,
|
|
216
|
+
category: "Technique",
|
|
217
|
+
createNodes: () => [
|
|
218
|
+
{ type: "h3", children: [{ text: "Modele : [NomEntite]" }] },
|
|
219
|
+
{ type: "table", children: [
|
|
220
|
+
{ type: "tr", children: [
|
|
221
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Champ", bold: true }] }] },
|
|
222
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Type", bold: true }] }] },
|
|
223
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Nullable", bold: true }] }] },
|
|
224
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Description", bold: true }] }] },
|
|
225
|
+
]},
|
|
226
|
+
{ type: "tr", children: [
|
|
227
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "id" }] }] },
|
|
228
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "UUID" }] }] },
|
|
229
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Non" }] }] },
|
|
230
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Identifiant unique" }] }] },
|
|
231
|
+
]},
|
|
232
|
+
{ type: "tr", children: [
|
|
233
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "createdAt" }] }] },
|
|
234
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "DateTime" }] }] },
|
|
235
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Non" }] }] },
|
|
236
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Date de creation" }] }] },
|
|
237
|
+
]},
|
|
238
|
+
]},
|
|
239
|
+
{ type: "p", children: [{ text: "" }] },
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
key: "security-requirements",
|
|
244
|
+
label: "Exigences de securite",
|
|
245
|
+
description: "Regles OWASP, chiffrement, acces, conformite",
|
|
246
|
+
icon: Shield,
|
|
247
|
+
category: "Non-fonctionnel",
|
|
248
|
+
createNodes: () => [
|
|
249
|
+
{ type: "h3", children: [{ text: "Exigences de securite" }] },
|
|
250
|
+
{ type: "callout", variant: "warning", children: [{ text: "Section obligatoire pour les modules HDS et les donnees sensibles" }] },
|
|
251
|
+
{ type: "table", children: [
|
|
252
|
+
{ type: "tr", children: [
|
|
253
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Categorie", bold: true }] }] },
|
|
254
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Exigence", bold: true }] }] },
|
|
255
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Niveau", bold: true }] }] },
|
|
256
|
+
]},
|
|
257
|
+
{ type: "tr", children: [
|
|
258
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Authentification" }] }] },
|
|
259
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "OAuth2 PKCE via Keycloak" }] }] },
|
|
260
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Obligatoire" }] }] },
|
|
261
|
+
]},
|
|
262
|
+
{ type: "tr", children: [
|
|
263
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Chiffrement" }] }] },
|
|
264
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "AES-256-GCM au repos, TLS 1.3 en transit" }] }] },
|
|
265
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Obligatoire" }] }] },
|
|
266
|
+
]},
|
|
267
|
+
{ type: "tr", children: [
|
|
268
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Audit" }] }] },
|
|
269
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "TracingInterceptor sur toutes les operations" }] }] },
|
|
270
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Obligatoire" }] }] },
|
|
271
|
+
]},
|
|
272
|
+
]},
|
|
273
|
+
{ type: "p", children: [{ text: "" }] },
|
|
274
|
+
],
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
key: "risk-assessment",
|
|
278
|
+
label: "Risques et mitigations",
|
|
279
|
+
description: "Matrice de risques projet avec probabilite et impact",
|
|
280
|
+
icon: AlertTriangle,
|
|
281
|
+
category: "Non-fonctionnel",
|
|
282
|
+
createNodes: () => [
|
|
283
|
+
{ type: "h3", children: [{ text: "Analyse des risques" }] },
|
|
284
|
+
{ type: "table", children: [
|
|
285
|
+
{ type: "tr", children: [
|
|
286
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Risque", bold: true }] }] },
|
|
287
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Probabilite", bold: true }] }] },
|
|
288
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Impact", bold: true }] }] },
|
|
289
|
+
{ type: "th", children: [{ type: "p", children: [{ text: "Mitigation", bold: true }] }] },
|
|
290
|
+
]},
|
|
291
|
+
{ type: "tr", children: [
|
|
292
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "[Description du risque]" }] }] },
|
|
293
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Moyen" }] }] },
|
|
294
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Haut" }] }] },
|
|
295
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "[Plan de mitigation]" }] }] },
|
|
296
|
+
]},
|
|
297
|
+
]},
|
|
298
|
+
{ type: "p", children: [{ text: "" }] },
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
key: "spec-header",
|
|
303
|
+
label: "En-tete de specification",
|
|
304
|
+
description: "Bloc d'en-tete avec version, auteur, statut, date",
|
|
305
|
+
icon: BookOpen,
|
|
306
|
+
category: "Document",
|
|
307
|
+
createNodes: () => [
|
|
308
|
+
{ type: "h1", children: [{ text: "[Titre de la specification]" }] },
|
|
309
|
+
{ type: "table", children: [
|
|
310
|
+
{ type: "tr", children: [
|
|
311
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Version", bold: true }] }] },
|
|
312
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "1.0.0" }] }] },
|
|
313
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Statut", bold: true }] }] },
|
|
314
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Brouillon" }] }] },
|
|
315
|
+
]},
|
|
316
|
+
{ type: "tr", children: [
|
|
317
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Auteur", bold: true }] }] },
|
|
318
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "[Nom]" }] }] },
|
|
319
|
+
{ type: "td", children: [{ type: "p", children: [{ text: "Date", bold: true }] }] },
|
|
320
|
+
{ type: "td", children: [{ type: "p", children: [{ text: new Date().toLocaleDateString("fr-FR") }] }] },
|
|
321
|
+
]},
|
|
322
|
+
]},
|
|
323
|
+
{ type: "h2", children: [{ text: "CONTEXTE" }] },
|
|
324
|
+
{ type: "p", children: [{ text: "[Description du contexte et des objectifs]" }] },
|
|
325
|
+
{ type: "h2", children: [{ text: "PERIMETRE" }] },
|
|
326
|
+
{ type: "p", children: [{ text: "[Ce qui est inclus et exclu du perimetre]" }] },
|
|
327
|
+
{ type: "p", children: [{ text: "" }] },
|
|
328
|
+
],
|
|
329
|
+
},
|
|
330
|
+
]
|
|
331
|
+
|
|
332
|
+
// ─── Component ───────────────────────────────────────────────────────────────
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* WakaSpecEditor -- Specification-oriented document editor.
|
|
336
|
+
*
|
|
337
|
+
* Extends the standard WakaEditor with domain-specific block templates
|
|
338
|
+
* for functional specifications, technical specs, and project documentation.
|
|
339
|
+
*
|
|
340
|
+
* Templates include: User Story, Acceptance Criteria, Use Case, API Endpoint,
|
|
341
|
+
* Data Model, Security Requirements, Risk Assessment, and Spec Header.
|
|
342
|
+
*
|
|
343
|
+
* Each template generates pre-formatted Slate nodes with placeholders
|
|
344
|
+
* that the user can fill in. Apps can register custom templates.
|
|
345
|
+
*
|
|
346
|
+
* Designed for WakaStart (project specs), WakaSign (contract specs),
|
|
347
|
+
* WakaPress (content specs), and TopFlix (content guidelines).
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* ```tsx
|
|
351
|
+
* <WakaSpecEditor
|
|
352
|
+
* title="Specification fonctionnelle - Module HDS"
|
|
353
|
+
* onTitleChange={setTitle}
|
|
354
|
+
* showTemplateSidebar
|
|
355
|
+
* enableAI
|
|
356
|
+
* aiEndpoint="/api/ai/completion"
|
|
357
|
+
* value={content}
|
|
358
|
+
* onChange={setContent}
|
|
359
|
+
* />
|
|
360
|
+
* ```
|
|
361
|
+
*/
|
|
362
|
+
export const WakaSpecEditor = React.forwardRef<HTMLDivElement, WakaSpecEditorProps>(
|
|
363
|
+
(
|
|
364
|
+
{
|
|
365
|
+
value,
|
|
366
|
+
onChange,
|
|
367
|
+
readOnly = false,
|
|
368
|
+
placeholder = "Commencez votre specification...",
|
|
369
|
+
className,
|
|
370
|
+
editorClassName,
|
|
371
|
+
minHeight = 500,
|
|
372
|
+
label,
|
|
373
|
+
description,
|
|
374
|
+
error,
|
|
375
|
+
customTemplates = [],
|
|
376
|
+
showTemplateSidebar = true,
|
|
377
|
+
enableAI = false,
|
|
378
|
+
aiEndpoint,
|
|
379
|
+
title,
|
|
380
|
+
onTitleChange,
|
|
381
|
+
extraPlugins,
|
|
382
|
+
editorRef,
|
|
383
|
+
},
|
|
384
|
+
ref
|
|
385
|
+
) => {
|
|
386
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
387
|
+
const [bundle, setBundle] = React.useState<any>(null)
|
|
388
|
+
const [loadError, setLoadError] = React.useState(false)
|
|
389
|
+
const internalEditorRef = React.useRef<unknown>(null)
|
|
390
|
+
const effectiveEditorRef = editorRef ?? internalEditorRef
|
|
391
|
+
|
|
392
|
+
const allTemplates = React.useMemo(
|
|
393
|
+
() => [...DEFAULT_SPEC_TEMPLATES, ...customTemplates],
|
|
394
|
+
[customTemplates]
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
// Group templates by category
|
|
398
|
+
const templateGroups = React.useMemo(() => {
|
|
399
|
+
const map = new Map<string, SpecBlockTemplate[]>()
|
|
400
|
+
for (const tpl of allTemplates) {
|
|
401
|
+
const cat = tpl.category || "Autre"
|
|
402
|
+
if (!map.has(cat)) map.set(cat, [])
|
|
403
|
+
map.get(cat)!.push(tpl)
|
|
404
|
+
}
|
|
405
|
+
return map
|
|
406
|
+
}, [allTemplates])
|
|
407
|
+
|
|
408
|
+
// ── Load Plate ────────────────────────────────────────────────────────
|
|
409
|
+
React.useEffect(() => {
|
|
410
|
+
let cancelled = false
|
|
411
|
+
|
|
412
|
+
const load = async () => {
|
|
413
|
+
try {
|
|
414
|
+
const [plateReact, basicNodes, tableModule, layoutModule, calloutModule, linkModule, indentModule] =
|
|
415
|
+
await Promise.all([
|
|
416
|
+
import("platejs/react"),
|
|
417
|
+
import("@platejs/basic-nodes/react"),
|
|
418
|
+
import("@platejs/table/react"),
|
|
419
|
+
import("@platejs/layout/react"),
|
|
420
|
+
import("@platejs/callout/react"),
|
|
421
|
+
import("@platejs/link/react"),
|
|
422
|
+
import("@platejs/indent/react"),
|
|
423
|
+
])
|
|
424
|
+
|
|
425
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
426
|
+
const plugins: any[] = [
|
|
427
|
+
basicNodes.BoldPlugin, basicNodes.ItalicPlugin, basicNodes.UnderlinePlugin,
|
|
428
|
+
basicNodes.StrikethroughPlugin, basicNodes.CodePlugin, basicNodes.HighlightPlugin,
|
|
429
|
+
basicNodes.SuperscriptPlugin, basicNodes.SubscriptPlugin,
|
|
430
|
+
basicNodes.H1Plugin, basicNodes.H2Plugin, basicNodes.H3Plugin,
|
|
431
|
+
basicNodes.H4Plugin, basicNodes.H5Plugin, basicNodes.H6Plugin,
|
|
432
|
+
basicNodes.BlockquotePlugin,
|
|
433
|
+
tableModule.TablePlugin, tableModule.TableRowPlugin,
|
|
434
|
+
tableModule.TableCellPlugin, tableModule.TableCellHeaderPlugin,
|
|
435
|
+
layoutModule.ColumnPlugin, layoutModule.ColumnItemPlugin,
|
|
436
|
+
calloutModule.CalloutPlugin,
|
|
437
|
+
linkModule.LinkPlugin.configure({
|
|
438
|
+
options: { allowedSchemes: ["http", "https", "mailto", "tel"] },
|
|
439
|
+
}),
|
|
440
|
+
indentModule.IndentPlugin,
|
|
441
|
+
]
|
|
442
|
+
|
|
443
|
+
// Optional: TOC
|
|
444
|
+
try { const { TocPlugin } = await import("@platejs/toc/react"); plugins.push(TocPlugin) } catch { /* */ }
|
|
445
|
+
|
|
446
|
+
// Optional: Selection
|
|
447
|
+
try { const { BlockSelectionPlugin } = await import("@platejs/selection/react"); plugins.push(BlockSelectionPlugin) } catch { /* */ }
|
|
448
|
+
|
|
449
|
+
// Optional: Markdown
|
|
450
|
+
try { const { MarkdownPlugin } = await import("@platejs/markdown"); plugins.push(MarkdownPlugin) } catch { /* */ }
|
|
451
|
+
|
|
452
|
+
// Optional: AI
|
|
453
|
+
if (enableAI && aiEndpoint) {
|
|
454
|
+
try {
|
|
455
|
+
const { AIPlugin, AIChatPlugin } = await import("@platejs/ai/react")
|
|
456
|
+
plugins.push(
|
|
457
|
+
AIPlugin,
|
|
458
|
+
AIChatPlugin.configure({
|
|
459
|
+
options: { chat: { api: aiEndpoint, body: { system: "You are a specification writing assistant for a PaaS platform." } } },
|
|
460
|
+
}),
|
|
461
|
+
)
|
|
462
|
+
} catch { /* */ }
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (!cancelled) {
|
|
466
|
+
setBundle({
|
|
467
|
+
Plate: plateReact.Plate,
|
|
468
|
+
PlateContent: plateReact.PlateContent,
|
|
469
|
+
usePlateEditor: plateReact.usePlateEditor,
|
|
470
|
+
plugins,
|
|
471
|
+
})
|
|
472
|
+
}
|
|
473
|
+
} catch (err) {
|
|
474
|
+
console.error("[WakaSpecEditor] Failed to load:", err)
|
|
475
|
+
if (!cancelled) setLoadError(true)
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
load()
|
|
480
|
+
return () => { cancelled = true }
|
|
481
|
+
}, [enableAI, aiEndpoint])
|
|
482
|
+
|
|
483
|
+
// ── Insert template ───────────────────────────────────────────────────
|
|
484
|
+
const handleInsertTemplate = React.useCallback(
|
|
485
|
+
(template: SpecBlockTemplate) => {
|
|
486
|
+
const nodes = template.createNodes()
|
|
487
|
+
const currentValue = value ?? []
|
|
488
|
+
const newValue = [...currentValue, ...nodes]
|
|
489
|
+
onChange?.(newValue)
|
|
490
|
+
},
|
|
491
|
+
[value, onChange]
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
// ── Render ────────────────────────────────────────────────────────────
|
|
495
|
+
return (
|
|
496
|
+
<div ref={ref} className={cn("space-y-1.5", className)}>
|
|
497
|
+
{label && <Label>{label}</Label>}
|
|
498
|
+
{description && <p className="text-sm text-muted-foreground">{description}</p>}
|
|
499
|
+
|
|
500
|
+
<div className={cn(
|
|
501
|
+
"flex border rounded-lg overflow-hidden",
|
|
502
|
+
error && "border-destructive",
|
|
503
|
+
)}>
|
|
504
|
+
{/* Template sidebar */}
|
|
505
|
+
{showTemplateSidebar && !readOnly && (
|
|
506
|
+
<aside className="w-52 shrink-0 border-r bg-muted/20 hidden md:block">
|
|
507
|
+
<div className="p-3 border-b">
|
|
508
|
+
<h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">
|
|
509
|
+
Blocs specification
|
|
510
|
+
</h4>
|
|
511
|
+
</div>
|
|
512
|
+
<div className="p-2 space-y-3 max-h-[600px] overflow-y-auto">
|
|
513
|
+
{Array.from(templateGroups.entries()).map(([category, templates]) => (
|
|
514
|
+
<div key={category}>
|
|
515
|
+
<div className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground px-1 mb-1">
|
|
516
|
+
{category}
|
|
517
|
+
</div>
|
|
518
|
+
<div className="space-y-0.5">
|
|
519
|
+
{templates.map((tpl) => {
|
|
520
|
+
const Icon = tpl.icon
|
|
521
|
+
return (
|
|
522
|
+
<button
|
|
523
|
+
key={tpl.key}
|
|
524
|
+
type="button"
|
|
525
|
+
onClick={() => handleInsertTemplate(tpl)}
|
|
526
|
+
className={cn(
|
|
527
|
+
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left",
|
|
528
|
+
"text-xs transition-colors cursor-pointer",
|
|
529
|
+
"hover:bg-accent/50 text-muted-foreground hover:text-foreground",
|
|
530
|
+
)}
|
|
531
|
+
title={tpl.description}
|
|
532
|
+
>
|
|
533
|
+
<Icon className="h-3.5 w-3.5 shrink-0" />
|
|
534
|
+
<span className="truncate">{tpl.label}</span>
|
|
535
|
+
</button>
|
|
536
|
+
)
|
|
537
|
+
})}
|
|
538
|
+
</div>
|
|
539
|
+
</div>
|
|
540
|
+
))}
|
|
541
|
+
</div>
|
|
542
|
+
</aside>
|
|
543
|
+
)}
|
|
544
|
+
|
|
545
|
+
{/* Editor */}
|
|
546
|
+
<div className="flex-1 min-w-0">
|
|
547
|
+
{/* Title */}
|
|
548
|
+
{(title !== undefined || onTitleChange) && (
|
|
549
|
+
<div className="border-b px-6 py-4">
|
|
550
|
+
<input
|
|
551
|
+
type="text"
|
|
552
|
+
value={title ?? ""}
|
|
553
|
+
onChange={(e) => onTitleChange?.(e.target.value)}
|
|
554
|
+
placeholder="Titre de la specification"
|
|
555
|
+
readOnly={readOnly}
|
|
556
|
+
className={cn(
|
|
557
|
+
"w-full bg-transparent text-xl font-bold text-foreground",
|
|
558
|
+
"placeholder:text-muted-foreground/50 focus:outline-none",
|
|
559
|
+
)}
|
|
560
|
+
/>
|
|
561
|
+
</div>
|
|
562
|
+
)}
|
|
563
|
+
|
|
564
|
+
{/* Plate editor */}
|
|
565
|
+
{bundle ? (
|
|
566
|
+
<SpecEditorInner
|
|
567
|
+
bundle={bundle}
|
|
568
|
+
value={value}
|
|
569
|
+
onChange={onChange}
|
|
570
|
+
readOnly={readOnly}
|
|
571
|
+
placeholder={placeholder}
|
|
572
|
+
editorClassName={editorClassName}
|
|
573
|
+
minHeight={minHeight}
|
|
574
|
+
extraPlugins={extraPlugins}
|
|
575
|
+
editorRef={effectiveEditorRef}
|
|
576
|
+
/>
|
|
577
|
+
) : (
|
|
578
|
+
<div className="relative" style={{ minHeight }}>
|
|
579
|
+
<div className="absolute inset-0 flex items-center justify-center bg-background/50">
|
|
580
|
+
<span className="text-sm text-muted-foreground animate-pulse">
|
|
581
|
+
{loadError ? "Erreur de chargement" : "Chargement de l'editeur..."}
|
|
582
|
+
</span>
|
|
583
|
+
</div>
|
|
584
|
+
</div>
|
|
585
|
+
)}
|
|
586
|
+
</div>
|
|
587
|
+
</div>
|
|
588
|
+
|
|
589
|
+
{error && <p className="text-sm text-destructive">{error}</p>}
|
|
590
|
+
</div>
|
|
591
|
+
)
|
|
592
|
+
}
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
WakaSpecEditor.displayName = "WakaSpecEditor"
|
|
596
|
+
|
|
597
|
+
// ─── Inner Plate component ──────────────────────────────────────────────────
|
|
598
|
+
|
|
599
|
+
function SpecEditorInner({
|
|
600
|
+
bundle: { Plate, PlateContent, usePlateEditor, plugins },
|
|
601
|
+
value,
|
|
602
|
+
onChange,
|
|
603
|
+
readOnly,
|
|
604
|
+
placeholder,
|
|
605
|
+
editorClassName,
|
|
606
|
+
minHeight,
|
|
607
|
+
extraPlugins,
|
|
608
|
+
editorRef,
|
|
609
|
+
}: {
|
|
610
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
611
|
+
bundle: any
|
|
612
|
+
value?: SlateNode[]
|
|
613
|
+
onChange?: (value: SlateNode[]) => void
|
|
614
|
+
readOnly?: boolean
|
|
615
|
+
placeholder?: string
|
|
616
|
+
editorClassName?: string
|
|
617
|
+
minHeight?: number
|
|
618
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
619
|
+
extraPlugins?: any[]
|
|
620
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
621
|
+
editorRef?: React.MutableRefObject<any>
|
|
622
|
+
}) {
|
|
623
|
+
const allPlugins = React.useMemo(
|
|
624
|
+
() => [...plugins, ...(extraPlugins ?? [])],
|
|
625
|
+
[plugins, extraPlugins]
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
const editor = usePlateEditor({
|
|
629
|
+
plugins: allPlugins,
|
|
630
|
+
value: value ?? [{ type: "p", children: [{ text: "" }] }],
|
|
631
|
+
})
|
|
632
|
+
|
|
633
|
+
React.useEffect(() => {
|
|
634
|
+
if (editorRef) editorRef.current = editor
|
|
635
|
+
}, [editor, editorRef])
|
|
636
|
+
|
|
637
|
+
return (
|
|
638
|
+
<Plate
|
|
639
|
+
editor={editor}
|
|
640
|
+
onChange={onChange ? ({ value: v }: { value: SlateNode[] }) => onChange(v) : undefined}
|
|
641
|
+
readOnly={readOnly}
|
|
642
|
+
>
|
|
643
|
+
<div style={{ minHeight }}>
|
|
644
|
+
<PlateContent
|
|
645
|
+
placeholder={placeholder}
|
|
646
|
+
readOnly={readOnly}
|
|
647
|
+
className={cn(
|
|
648
|
+
"prose prose-sm max-w-none px-6 py-4",
|
|
649
|
+
"focus-within:outline-none",
|
|
650
|
+
"[&_[data-slate-editor]]:outline-none [&_[data-slate-editor]]:min-h-[inherit]",
|
|
651
|
+
editorClassName,
|
|
652
|
+
)}
|
|
653
|
+
/>
|
|
654
|
+
</div>
|
|
655
|
+
</Plate>
|
|
656
|
+
)
|
|
657
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -716,23 +716,6 @@ export * from './waka-doc-nav'
|
|
|
716
716
|
export * from './waka-doc-search'
|
|
717
717
|
export * from './waka-doc-version'
|
|
718
718
|
export * from './waka-doc-toolbar'
|
|
719
|
-
|
|
720
|
-
export { WakaDocBreadcrumb, type WakaDocBreadcrumbProps } from './waka-doc-breadcrumb'
|
|
719
|
+
export * from './waka-doc-breadcrumb'
|
|
721
720
|
export * from './waka-doc-table'
|
|
722
721
|
export * from './waka-doc-renderer'
|
|
723
|
-
|
|
724
|
-
// WakaProject Sprint Components
|
|
725
|
-
export * from './waka-hour-balance-badge'
|
|
726
|
-
export * from './waka-actor-badge'
|
|
727
|
-
export * from './waka-step-comment-bubble'
|
|
728
|
-
export * from './waka-step-comment-panel'
|
|
729
|
-
export * from './waka-time-entry-dialog'
|
|
730
|
-
export * from './waka-time-tracking-flyover'
|
|
731
|
-
export * from './waka-document-preview-popup'
|
|
732
|
-
export * from './waka-document-flyover'
|
|
733
|
-
export * from './waka-ai-assistant-button'
|
|
734
|
-
export * from './waka-step-permission-matrix'
|
|
735
|
-
export * from './waka-actors-list'
|
|
736
|
-
export * from './waka-project-stats-header'
|
|
737
|
-
export * from './waka-hour-pack-dialog'
|
|
738
|
-
export * from './waka-hour-consumption-table'
|
package/dist/chunk-BDDJmn7V.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return o}});
|