| 1 | "use client"; |
| 2 | |
| 3 | import { type TElement } from "platejs"; |
| 4 | |
| 5 | import { ANTV_INFOGRAPHIC } from "@/components/notebook/presentation/editor/lib"; |
| 6 | import { type TAntvInfographicElement } from "@/components/notebook/presentation/editor/plugins/antv-infographic-plugin"; |
| 7 | import { INFOGRAPHIC_CATEGORIES } from "@/constants/antv-templates"; |
| 8 | |
| 9 | export type DiagramItem = { |
| 10 | key: string; |
| 11 | label: string; |
| 12 | categoryKey: string; |
| 13 | categoryName: string; |
| 14 | templateId: string; |
| 15 | syntax: string; |
| 16 | node: TElement; |
| 17 | }; |
| 18 | |
| 19 | export type DiagramCategory = { |
| 20 | key: string; |
| 21 | name: string; |
| 22 | items: DiagramItem[]; |
| 23 | }; |
| 24 | |
| 25 | const DEFAULT_THEME = `theme |
| 26 | colorBg transparent |
| 27 | palette |
| 28 | - #2563eb |
| 29 | - #14b8a6 |
| 30 | - #f97316 |
| 31 | - #8b5cf6 |
| 32 | - #22c55e`; |
| 33 | |
| 34 | function titleCaseTemplate(templateId: string): string { |
| 35 | return templateId |
| 36 | .split("-") |
| 37 | .filter(Boolean) |
| 38 | .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) |
| 39 | .join(" "); |
| 40 | } |
| 41 | |
| 42 | function createInfographicNode(syntax: string): TElement { |
| 43 | return { |
| 44 | type: ANTV_INFOGRAPHIC, |
| 45 | syntax, |
| 46 | isLoading: false, |
| 47 | align: "center", |
| 48 | width: "100%", |
| 49 | children: [{ text: "" }], |
| 50 | } satisfies TAntvInfographicElement; |
| 51 | } |
| 52 | |
| 53 | function createItemsData(title: string): string { |
| 54 | return `data |
| 55 | title ${title} |
| 56 | desc A practical workflow from idea to outcome |
| 57 | items |
| 58 | - label Discover |
| 59 | desc Frame the need and collect the right signals |
| 60 | value 24 |
| 61 | icon mdi/magnify |
| 62 | - label Design |
| 63 | desc Shape options into a clear execution path |
| 64 | value 42 |
| 65 | icon mdi/vector-square |
| 66 | - label Build |
| 67 | desc Produce the core deliverable with focused effort |
| 68 | value 68 |
| 69 | icon mdi/hammer-wrench |
| 70 | - label Launch |
| 71 | desc Release, measure, and refine the result |
| 72 | value 86 |
| 73 | icon mdi/rocket-launch`; |
| 74 | } |
| 75 | |
| 76 | function createCompareData(title: string): string { |
| 77 | return `data |
| 78 | title ${title} |
| 79 | desc Choose the path that best fits the work |
| 80 | compares |
| 81 | - label Current |
| 82 | desc Existing way of working |
| 83 | icon mdi/history |
| 84 | children |
| 85 | - label Manual |
| 86 | desc Repeated handoffs slow delivery |
| 87 | icon mdi/hand-back-left |
| 88 | - label Fragmented |
| 89 | desc Context is split across tools |
| 90 | icon mdi/call-split |
| 91 | - label Target |
| 92 | desc Improved operating model |
| 93 | icon mdi/bullseye-arrow |
| 94 | children |
| 95 | - label Guided |
| 96 | desc Clear steps keep decisions moving |
| 97 | icon mdi/sign-direction |
| 98 | - label Connected |
| 99 | desc Shared context reduces rework |
| 100 | icon mdi/source-branch`; |
| 101 | } |
| 102 | |
| 103 | function createHierarchyData(title: string): string { |
| 104 | return `data |
| 105 | title ${title} |
| 106 | desc A simple operating model for team execution |
| 107 | root |
| 108 | label Growth System |
| 109 | desc Coordinated work from insight to impact |
| 110 | children |
| 111 | - label Strategy |
| 112 | desc Define the highest-value direction |
| 113 | value 34 |
| 114 | icon mdi/chess-queen |
| 115 | - label Planning |
| 116 | desc Turn direction into sequenced work |
| 117 | value 52 |
| 118 | icon mdi/calendar-check |
| 119 | - label Delivery |
| 120 | desc Build and ship reliable outcomes |
| 121 | value 74 |
| 122 | icon mdi/package-variant-closed |
| 123 | - label Learning |
| 124 | desc Feed results back into the next cycle |
| 125 | value 91 |
| 126 | icon mdi/chart-line`; |
| 127 | } |
| 128 | |
| 129 | function createRelationData(title: string): string { |
| 130 | return `data |
| 131 | title ${title} |
| 132 | desc Connected decisions across a delivery system |
| 133 | nodes |
| 134 | - id insight |
| 135 | label Insight |
| 136 | desc Signals from users and the market |
| 137 | icon mdi/lightbulb-on |
| 138 | - id plan |
| 139 | label Plan |
| 140 | desc Prioritized scope and ownership |
| 141 | icon mdi/clipboard-list |
| 142 | - id execute |
| 143 | label Execute |
| 144 | desc Coordinated implementation work |
| 145 | icon mdi/cogs |
| 146 | - id measure |
| 147 | label Measure |
| 148 | desc Results that guide the next move |
| 149 | icon mdi/chart-timeline-variant |
| 150 | relations |
| 151 | - insight -> plan |
| 152 | - plan -> execute |
| 153 | - execute -> measure |
| 154 | - measure -> insight`; |
| 155 | } |
| 156 | |
| 157 | function createWordCloudData(title: string): string { |
| 158 | return `data |
| 159 | title ${title} |
| 160 | desc Core themes for a product strategy discussion |
| 161 | items |
| 162 | - label Research |
| 163 | value 96 |
| 164 | - label Focus |
| 165 | value 88 |
| 166 | - label Quality |
| 167 | value 82 |
| 168 | - label Launch |
| 169 | value 74 |
| 170 | - label Growth |
| 171 | value 68 |
| 172 | - label Trust |
| 173 | value 62 |
| 174 | - label Clarity |
| 175 | value 54 |
| 176 | - label Feedback |
| 177 | value 48`; |
| 178 | } |
| 179 | |
| 180 | function createSyntax(templateId: string, categoryKey: string): string { |
| 181 | const title = titleCaseTemplate(templateId); |
| 182 | const data = |
| 183 | categoryKey === "compare" |
| 184 | ? createCompareData(title) |
| 185 | : categoryKey === "hierarchy" |
| 186 | ? createHierarchyData(title) |
| 187 | : categoryKey === "relation" |
| 188 | ? createRelationData(title) |
| 189 | : categoryKey === "wordcloud" |
| 190 | ? createWordCloudData(title) |
| 191 | : createItemsData(title); |
| 192 | |
| 193 | return `infographic ${templateId} |
| 194 | ${DEFAULT_THEME} |
| 195 | ${data}`; |
| 196 | } |
| 197 | |
| 198 | export const diagramCategories: DiagramCategory[] = INFOGRAPHIC_CATEGORIES.map( |
| 199 | (category) => ({ |
| 200 | key: category.key, |
| 201 | name: category.name, |
| 202 | items: category.templates.map((templateId) => { |
| 203 | const syntax = createSyntax(templateId, category.key); |
| 204 | return { |
| 205 | key: templateId, |
| 206 | label: titleCaseTemplate(templateId), |
| 207 | categoryKey: category.key, |
| 208 | categoryName: category.name, |
| 209 | templateId, |
| 210 | syntax, |
| 211 | node: createInfographicNode(syntax), |
| 212 | }; |
| 213 | }), |
| 214 | }), |
| 215 | ); |
| 216 |