blixify-ui-web-mcp 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/README.md +5 -0
  2. package/lib/components/action/button/README.md +75 -0
  3. package/lib/components/action/button/button.stories.tsx +138 -0
  4. package/lib/components/action/buttonGroup/README.md +79 -0
  5. package/lib/components/action/buttonGroup/buttonGroup.stories.tsx +104 -0
  6. package/lib/components/action/iconButton/README.md +39 -0
  7. package/lib/components/action/iconButton/iconButton.stories.tsx +22 -0
  8. package/lib/components/action/radioList/README.md +98 -0
  9. package/lib/components/action/radioList/radioList.stories.tsx +181 -0
  10. package/lib/components/action/slider/README.md +86 -0
  11. package/lib/components/action/slider/slider.stories.tsx +133 -0
  12. package/lib/components/action/textButton/README.md +34 -0
  13. package/lib/components/action/textButton/textButton.stories.tsx +16 -0
  14. package/lib/components/action/toggle/README.md +39 -0
  15. package/lib/components/action/toggle/toggle.stories.tsx +23 -0
  16. package/lib/components/advanced/collapse/README.md +106 -0
  17. package/lib/components/advanced/collapse/collapse.stories.tsx +165 -0
  18. package/lib/components/advanced/infoWindow/README.md +69 -0
  19. package/lib/components/advanced/infoWindow/infoWindow.stories.tsx +112 -0
  20. package/lib/components/advanced/popUp/README.md +95 -0
  21. package/lib/components/advanced/popUp/popUp.stories.tsx +189 -0
  22. package/lib/components/auth/bareSignIn/README.md +78 -0
  23. package/lib/components/auth/bareSignIn/bareSignIn.stories.tsx +141 -0
  24. package/lib/components/auth/bareSignUp/README.md +130 -0
  25. package/lib/components/auth/bareSignUp/bareSignUp.stories.tsx +159 -0
  26. package/lib/components/auth/signIn/README.md +53 -0
  27. package/lib/components/auth/signIn/signIn.stories.tsx +120 -0
  28. package/lib/components/auth/signUp/README.md +136 -0
  29. package/lib/components/auth/signUp/signUp.stories.tsx +193 -0
  30. package/lib/components/chart/README.md +13 -0
  31. package/lib/components/chart/areaChart/README.md +133 -0
  32. package/lib/components/chart/areaChart/areaChart.stories.tsx +199 -0
  33. package/lib/components/chart/barChart/README.md +193 -0
  34. package/lib/components/chart/barChart/barChart.stories.tsx +318 -0
  35. package/lib/components/chart/boxPlotChart/README.md +124 -0
  36. package/lib/components/chart/boxPlotChart/boxPlotChart.stories.tsx +104 -0
  37. package/lib/components/chart/bubbleChart/README.md +166 -0
  38. package/lib/components/chart/bubbleChart/bubbleChart.stories.tsx +144 -0
  39. package/lib/components/chart/card/README.md +107 -0
  40. package/lib/components/chart/card/card.stories.tsx +89 -0
  41. package/lib/components/chart/ganttChart/README.md +142 -0
  42. package/lib/components/chart/ganttChart/ganttChart.stories.tsx +138 -0
  43. package/lib/components/chart/heatmapChart/README.md +125 -0
  44. package/lib/components/chart/heatmapChart/heatmapChart.stories.tsx +106 -0
  45. package/lib/components/chart/lineChart/README.md +140 -0
  46. package/lib/components/chart/lineChart/lineChart.stories.tsx +152 -0
  47. package/lib/components/chart/pieChart/README.md +117 -0
  48. package/lib/components/chart/pieChart/pieChart.stories.tsx +180 -0
  49. package/lib/components/chart/polarAreaChart/README.md +126 -0
  50. package/lib/components/chart/polarAreaChart/polarAreaChart.stories.tsx +106 -0
  51. package/lib/components/chart/radarChart/README.md +57 -0
  52. package/lib/components/chart/radarChart/radarChart.stories.tsx +36 -0
  53. package/lib/components/chart/radialBar/README.md +152 -0
  54. package/lib/components/chart/radialBar/radialChart.stories.tsx +136 -0
  55. package/lib/components/chart/rangeBarChart/README.md +323 -0
  56. package/lib/components/chart/rangeBarChart/rangeBarChart.stories.tsx +208 -0
  57. package/lib/components/chart/statsCard/README.md +97 -0
  58. package/lib/components/chart/statsCard/statsCard.stories.tsx +183 -0
  59. package/lib/components/chart/treemapChart/README.md +142 -0
  60. package/lib/components/chart/treemapChart/treemapChart.stories.tsx +122 -0
  61. package/lib/components/chat/chatAnchor/README.md +113 -0
  62. package/lib/components/chat/chatAnchor/chatAnchor.stories.tsx +156 -0
  63. package/lib/components/chat/chatBase/README.md +223 -0
  64. package/lib/components/chat/chatBase/chatBase.stories.tsx +306 -0
  65. package/lib/components/chat/chatDashboard/README.md +161 -0
  66. package/lib/components/chat/chatDashboard/chatDashboard.stories.tsx +154 -0
  67. package/lib/components/data/dataGraph/README.md +13 -0
  68. package/lib/components/data/dataGraph/dataGraph.stories.tsx +84 -0
  69. package/lib/components/data/dataReference/README.md +62 -0
  70. package/lib/components/data/dataReference/dataReference.stories.tsx +53 -0
  71. package/lib/components/data/dataTemplate/README.md +903 -0
  72. package/lib/components/data/dataTemplate/dataModule.stories.tsx +196 -0
  73. package/lib/components/data/dataTemplate/dataTemplate.stories.tsx +337 -0
  74. package/lib/components/data/dataWrapper/README.md +1077 -0
  75. package/lib/components/data/dataWrapper/dataWrapper.stories.tsx +831 -0
  76. package/lib/components/data/queryForm/README.md +56 -0
  77. package/lib/components/data/queryForm/queryForm.stories.tsx +85 -0
  78. package/lib/components/data/readQuery/README.md +282 -0
  79. package/lib/components/data/readQuery/readQuery.stories.tsx +256 -0
  80. package/lib/components/data/readQueryHoc/README.md +89 -0
  81. package/lib/components/data/readQueryHoc/readQueryHoc.stories.tsx +33 -0
  82. package/lib/components/data/writeQuery/README.md +178 -0
  83. package/lib/components/data/writeQuery/writeQuery.stories.tsx +209 -0
  84. package/lib/components/design/actionSection/README.md +47 -0
  85. package/lib/components/design/actionSection/actionSection.stories.tsx +74 -0
  86. package/lib/components/design/banner/README.md +43 -0
  87. package/lib/components/design/banner/banner.stories.tsx +34 -0
  88. package/lib/components/design/bannerAction/README.md +44 -0
  89. package/lib/components/design/bannerAction/bannerAction.stories.tsx +25 -0
  90. package/lib/components/design/blogSection/README.md +111 -0
  91. package/lib/components/design/blogSection/blogSection.stories.tsx +72 -0
  92. package/lib/components/design/carouselSection/README.md +82 -0
  93. package/lib/components/design/carouselSection/carouselSection.stories.tsx +52 -0
  94. package/lib/components/design/designList/README.md +60 -0
  95. package/lib/components/design/designList/designList.stories.tsx +44 -0
  96. package/lib/components/design/faq/README.md +121 -0
  97. package/lib/components/design/faq/faq.stories.tsx +103 -0
  98. package/lib/components/design/fileGrid/README.md +87 -0
  99. package/lib/components/design/fileGrid/fileGrid.stories.tsx +110 -0
  100. package/lib/components/design/fileViewer/README.md +40 -0
  101. package/lib/components/design/fileViewer/fileViewer.stories.tsx +28 -0
  102. package/lib/components/design/footerSection/README.md +62 -0
  103. package/lib/components/design/footerSection/footerSection.stories.tsx +84 -0
  104. package/lib/components/design/googleReview/README.md +45 -0
  105. package/lib/components/design/googleReview/googleReview.stories.tsx +33 -0
  106. package/lib/components/design/heroSection/README.md +48 -0
  107. package/lib/components/design/heroSection/heroSection.stories.tsx +85 -0
  108. package/lib/components/design/iconList/README.md +60 -0
  109. package/lib/components/design/iconList/iconList.stories.tsx +41 -0
  110. package/lib/components/design/imageGallery/README.md +56 -0
  111. package/lib/components/design/imageGallery/imageGallery.stories.tsx +45 -0
  112. package/lib/components/design/imageZoom/README.md +47 -0
  113. package/lib/components/design/imageZoom/imageZoom.stories.tsx +30 -0
  114. package/lib/components/design/leftContent/README.md +47 -0
  115. package/lib/components/design/leftContent/leftContent.stories.tsx +32 -0
  116. package/lib/components/design/logoCloud/README.md +42 -0
  117. package/lib/components/design/logoCloud/logoCloud.stories.tsx +44 -0
  118. package/lib/components/design/onboarding/README.md +100 -0
  119. package/lib/components/design/onboarding/onboarding.stories.tsx +113 -0
  120. package/lib/components/design/pricing/README.md +112 -0
  121. package/lib/components/design/pricing/pricing.stories.tsx +86 -0
  122. package/lib/components/design/rightContent/README.md +47 -0
  123. package/lib/components/design/rightContent/rightContent.stories.tsx +32 -0
  124. package/lib/components/design/sectionList/README.md +51 -0
  125. package/lib/components/design/sectionList/sectionList.stories.tsx +35 -0
  126. package/lib/components/design/teams/README.md +62 -0
  127. package/lib/components/design/teams/teams.stories.tsx +61 -0
  128. package/lib/components/display/alert/README.md +82 -0
  129. package/lib/components/display/alert/alert.stories.tsx +71 -0
  130. package/lib/components/display/calendar/README.md +113 -0
  131. package/lib/components/display/calendar/calendar.stories.tsx +159 -0
  132. package/lib/components/display/clipboard/README.md +36 -0
  133. package/lib/components/display/clipboard/clipboard.stories.tsx +32 -0
  134. package/lib/components/display/detailList/README.md +61 -0
  135. package/lib/components/display/detailList/detailList.stories.tsx +131 -0
  136. package/lib/components/display/drawer/README.md +74 -0
  137. package/lib/components/display/drawer/drawer.stories.tsx +66 -0
  138. package/lib/components/display/emptyState/README.md +38 -0
  139. package/lib/components/display/emptyState/emptyState.stories.tsx +22 -0
  140. package/lib/components/display/feeds/README.md +80 -0
  141. package/lib/components/display/feeds/feeds.stories.tsx +75 -0
  142. package/lib/components/display/flexTable/README.md +160 -0
  143. package/lib/components/display/flexTable/flexTable.stories.tsx +313 -0
  144. package/lib/components/display/grid/README.md +121 -0
  145. package/lib/components/display/grid/grid.stories.tsx +234 -0
  146. package/lib/components/display/kanban/README.md +78 -0
  147. package/lib/components/display/kanban/kanban.stories.tsx +133 -0
  148. package/lib/components/display/list/README.md +109 -0
  149. package/lib/components/display/list/list.stories.tsx +188 -0
  150. package/lib/components/display/loading/README.md +25 -0
  151. package/lib/components/display/loading/loading.stories.tsx +15 -0
  152. package/lib/components/display/mapView/README.md +99 -0
  153. package/lib/components/display/mapView/mapView.stories.tsx +225 -0
  154. package/lib/components/display/modal/README.md +43 -0
  155. package/lib/components/display/modal/modal.stories.tsx +81 -0
  156. package/lib/components/display/notification/README.md +43 -0
  157. package/lib/components/display/notification/notification.stories.tsx +30 -0
  158. package/lib/components/display/progress/README.md +25 -0
  159. package/lib/components/display/progress/progress.stories.tsx +15 -0
  160. package/lib/components/display/stepper/README.md +96 -0
  161. package/lib/components/display/stepper/stepper.stories.tsx +175 -0
  162. package/lib/components/display/table/README.md +176 -0
  163. package/lib/components/display/table/table.stories.tsx +330 -0
  164. package/lib/components/display/tag/README.md +74 -0
  165. package/lib/components/display/tag/tag.stories.tsx +79 -0
  166. package/lib/components/input/address/README.md +132 -0
  167. package/lib/components/input/address/address.stories.tsx +147 -0
  168. package/lib/components/input/canvas/README.md +131 -0
  169. package/lib/components/input/canvas/canvas.stories.tsx +165 -0
  170. package/lib/components/input/checkbox/README.md +61 -0
  171. package/lib/components/input/checkbox/checkbox.stories.tsx +30 -0
  172. package/lib/components/input/datePicker/README.md +124 -0
  173. package/lib/components/input/datePicker/datePicker.stories.tsx +197 -0
  174. package/lib/components/input/form/README.md +55 -0
  175. package/lib/components/input/form/form.stories.tsx +143 -0
  176. package/lib/components/input/markdown/README.md +146 -0
  177. package/lib/components/input/markdown/markdown.stories.tsx +40 -0
  178. package/lib/components/input/monthYearPicker/README.md +69 -0
  179. package/lib/components/input/monthYearPicker/monthYearPicker.stories.tsx +47 -0
  180. package/lib/components/input/netPromoterScore/README.md +52 -0
  181. package/lib/components/input/netPromoterScore/netPromoterScore.stories.tsx +30 -0
  182. package/lib/components/input/rating/README.md +51 -0
  183. package/lib/components/input/rating/rating.stories.tsx +30 -0
  184. package/lib/components/input/select/README.md +108 -0
  185. package/lib/components/input/select/select.stories.tsx +286 -0
  186. package/lib/components/input/signature/README.md +106 -0
  187. package/lib/components/input/signature/signature.stories.tsx +188 -0
  188. package/lib/components/input/textArea/README.md +55 -0
  189. package/lib/components/input/textArea/textArea.stories.tsx +30 -0
  190. package/lib/components/input/textInput/README.md +81 -0
  191. package/lib/components/input/textInput/textinput.stories.tsx +231 -0
  192. package/lib/components/input/uploadInput/README.md +134 -0
  193. package/lib/components/input/uploadInput/uploadInput.stories.tsx +193 -0
  194. package/lib/components/navigation/bars/README.md +40 -0
  195. package/lib/components/navigation/bars/bars.stories.tsx +85 -0
  196. package/lib/components/navigation/bottomTab/README.md +53 -0
  197. package/lib/components/navigation/bottomTab/bottomTab.stories.tsx +32 -0
  198. package/lib/components/navigation/breadcrumb/README.md +48 -0
  199. package/lib/components/navigation/breadcrumb/breadcrumb.stories.tsx +27 -0
  200. package/lib/components/navigation/header/README.md +149 -0
  201. package/lib/components/navigation/header/header.stories.tsx +107 -0
  202. package/lib/components/navigation/leftNav/README.md +91 -0
  203. package/lib/components/navigation/leftNav/leftNav.stories.tsx +106 -0
  204. package/lib/components/navigation/tabs/README.md +75 -0
  205. package/lib/components/navigation/tabs/tabs.stories.tsx +60 -0
  206. package/lib/components/structure/column/README.md +40 -0
  207. package/lib/components/structure/column/column.stories.tsx +26 -0
  208. package/lib/components/structure/container/README.md +34 -0
  209. package/lib/components/structure/container/container.stories.tsx +19 -0
  210. package/lib/components/structure/link/README.md +55 -0
  211. package/lib/components/structure/link/link.stories.tsx +30 -0
  212. package/lib/components/structure/text/README.md +42 -0
  213. package/lib/components/structure/text/text.stories.tsx +39 -0
  214. package/lib/components/template/authPage/authPage.stories.tsx +68 -0
  215. package/lib/components/template/landingPage/landingPage.stories.tsx +288 -0
  216. package/lib/components/template/productListing/productListing.stories.tsx +297 -0
  217. package/lib/components/template/productOverview/productOverview.stories.tsx +194 -0
  218. package/lib/components/template/shoppingCart/shoppingCart.stories.tsx +252 -0
  219. package/lib/components/template/userHomePage/userHomePage.stories.tsx +605 -0
  220. package/lib/components/template/userRankingDashboard/userRankingDashboard.stories.tsx +481 -0
  221. package/lib/mcp/server.d.ts +2 -0
  222. package/lib/mcp/server.d.ts.map +1 -0
  223. package/lib/mcp/server.js +33 -0
  224. package/lib/mcp/server.js.map +1 -0
  225. package/lib/mcp/tools/getBackendComponent.d.ts +13 -0
  226. package/lib/mcp/tools/getBackendComponent.d.ts.map +1 -0
  227. package/lib/mcp/tools/getBackendComponent.js +119 -0
  228. package/lib/mcp/tools/getBackendComponent.js.map +1 -0
  229. package/lib/mcp/tools/getComponent.d.ts +17 -0
  230. package/lib/mcp/tools/getComponent.d.ts.map +1 -0
  231. package/lib/mcp/tools/getComponent.js +118 -0
  232. package/lib/mcp/tools/getComponent.js.map +1 -0
  233. package/lib/mcp/tools/listComponents.d.ts +13 -0
  234. package/lib/mcp/tools/listComponents.d.ts.map +1 -0
  235. package/lib/mcp/tools/listComponents.js +113 -0
  236. package/lib/mcp/tools/listComponents.js.map +1 -0
  237. package/lib/mcp/tools/listTemplates.d.ts +13 -0
  238. package/lib/mcp/tools/listTemplates.d.ts.map +1 -0
  239. package/lib/mcp/tools/listTemplates.js +68 -0
  240. package/lib/mcp/tools/listTemplates.js.map +1 -0
  241. package/lib/mcp/tools/suggestTemplate.d.ts +17 -0
  242. package/lib/mcp/tools/suggestTemplate.d.ts.map +1 -0
  243. package/lib/mcp/tools/suggestTemplate.js +212 -0
  244. package/lib/mcp/tools/suggestTemplate.js.map +1 -0
  245. package/package.json +23 -0
@@ -0,0 +1,831 @@
1
+ import { StarIcon } from "@heroicons/react/24/outline";
2
+ import {
3
+ CheckCircleIcon,
4
+ InformationCircleIcon,
5
+ } from "@heroicons/react/24/solid";
6
+ import { storiesOf } from "@storybook/react";
7
+ import moment from "moment";
8
+ import { useEffect, useRef, useState } from "react";
9
+ import { Button } from "../../action/button";
10
+ import { IconButton } from "../../action/iconButton";
11
+ import { Alert } from "../../display/alert";
12
+ import { Loading } from "../../display/loading";
13
+ import { Tag } from "../../display/tag";
14
+ import { Tabs } from "../../navigation/tabs";
15
+ import { StorySection } from "../../storyUtils";
16
+ import { Container } from "../../structure/container";
17
+ import { DataStructure } from "../dataTemplate/model";
18
+ import {
19
+ CalendarSettings,
20
+ FeedsSettings,
21
+ KanbanSettings,
22
+ } from "../dataTemplate/spaceModel";
23
+ import { ProjectSchema } from "../testSchema";
24
+ import { DataTemplateWrapper } from "./index";
25
+ import README from "./README.md";
26
+ const stories = storiesOf("Data", module);
27
+
28
+ stories.addParameters({
29
+ readme: {
30
+ content: README,
31
+ },
32
+ argTypes: {
33
+ status: {
34
+ control: { type: "select" },
35
+ options: ["Pending Submission", "Pending Review", "Approved", "Rejected"],
36
+ description: "Filter by checklist status",
37
+ },
38
+ },
39
+ args: {
40
+ status: "Pending Submission",
41
+ },
42
+ });
43
+
44
+ stories.add("Data Wrapper", () => {
45
+ const [mount, setMount] = useState<boolean>(false);
46
+ const dataRefreshRef: any = useRef(null);
47
+ const [statusFilter] = useState<string>("all");
48
+ const [viewType, setViewType] = useState<"list" | "read" | "update">("list");
49
+ const [selectedId, setSelectedId] = useState<string | undefined>(undefined);
50
+ const [listLayout, setListLayout] = useState("table");
51
+ const dtwBaseUrl = "http://localhost:3000";
52
+
53
+ useEffect(() => {
54
+ setMount(true);
55
+ }, []);
56
+
57
+ useEffect(() => {
58
+ if (mount && dataRefreshRef.current) {
59
+ dataRefreshRef.current.handleRefresh();
60
+ }
61
+ }, [statusFilter, mount]);
62
+
63
+ const handleNavigate = (type: any, id: any, viewId: any) => {
64
+ setViewType(type);
65
+ setSelectedId(id);
66
+ };
67
+
68
+ if (!mount) {
69
+ return <Loading />;
70
+ }
71
+
72
+ const renderViewSettings = () => {
73
+ const viewSettings: {
74
+ gridImage?: string;
75
+ gridScroll?: boolean;
76
+ gridContain?: boolean;
77
+ listImage?: string;
78
+ calendarSettings?: CalendarSettings;
79
+ feedsSettings?: FeedsSettings;
80
+ kanbanSettings?: KanbanSettings;
81
+ } = {};
82
+
83
+ if (listLayout === "grid") {
84
+ viewSettings.gridImage = "flowDiagramAppendix";
85
+ }
86
+ if (listLayout === "list" || listLayout === "customList") {
87
+ viewSettings.listImage = "flowDiagramAppendix";
88
+ }
89
+ if (listLayout === "calendar") {
90
+ viewSettings.calendarSettings = {
91
+ title: "researchTitle",
92
+ startDate: "createdAt",
93
+ };
94
+ }
95
+ return viewSettings;
96
+ };
97
+
98
+ const renderCustomListComponent = (data: any) => {
99
+ return (
100
+ <div className="grid grid-cols-2 gap-4">
101
+ {data.map((eachItem: any, index: number) => {
102
+ return (
103
+ <div className="p-4 rounded-lg bg-gray-50 truncate text-sm text-gray-600">
104
+ {eachItem?.researchTitle || `Item ${index}`}
105
+ </div>
106
+ );
107
+ })}
108
+ </div>
109
+ );
110
+ };
111
+
112
+ return (
113
+ <StorySection
114
+ title="Data Wrapper"
115
+ description="The recommended starting point for custom integrations. Use this when you don't have a Space object — for most custom builds, DataTemplateWrapper is the right choice over DataTemplate."
116
+ >
117
+ <div className="w-full">
118
+ <Tabs
119
+ tabs={[
120
+ { id: "table", name: "Table View", href: "#" },
121
+ { id: "list", name: "List View", href: "#" },
122
+ { id: "grid", name: "Grid View", href: "#" },
123
+ { id: "calendar", name: "Calendar View", href: "#" },
124
+ { id: "customList", name: "Custom List View", href: "#" },
125
+ ]}
126
+ onClick={(id) => {
127
+ setListLayout(id);
128
+ setViewType("list");
129
+ }}
130
+ selectedId={listLayout}
131
+ />
132
+ <div className="mb-6" />
133
+ <DataTemplateWrapper
134
+ ref={dataRefreshRef}
135
+ title={"KPJ Projects"}
136
+ description="Manage all your projects here"
137
+ type={viewType}
138
+ id={selectedId}
139
+ collectionId={"kpj-projects"}
140
+ schema={ProjectSchema}
141
+ workspace={{
142
+ apiEndpointType: "mongoDB",
143
+ apiEndpoint: `${dtwBaseUrl}/api/data`,
144
+ apiEndpointToken: "",
145
+ apiUserToken: "",
146
+ assetEndpoint:
147
+ "https://firebasestorage.googleapis.com/v0/b/verdant-dev.firebasestorage.app/o/",
148
+ assetUploadEndpoint: `${dtwBaseUrl}/api/asset`,
149
+ }}
150
+ edit={{
151
+ allEditable: true,
152
+ disabledUpdate: false,
153
+ disableBatchUpdate: false,
154
+ deleteBtn: true,
155
+ }}
156
+ bareSettings={{
157
+ bareOffline: false, //INFO: If set to true, form data will be saved into device's indexedDB and users have to submit manually once internet connection resumes
158
+ bareListComponent:
159
+ // INFO: Render custom component when type is list (table view, list view, grid view etc)
160
+ listLayout === "customList"
161
+ ? (data) => renderCustomListComponent(data)
162
+ : undefined,
163
+ bareListDescription: (key, value) => {
164
+ if (key === "status" && value) {
165
+ return (
166
+ <Tag
167
+ tagText={value}
168
+ color={value === "Approved" ? "green" : "blue"}
169
+ size="small"
170
+ />
171
+ );
172
+ } // override default UI with custom component where columnId matches key when type is list (table, list, grid etc)
173
+ },
174
+ bareListActionBtns: (data) => [
175
+ <IconButton
176
+ key={"actionBtn"}
177
+ bgColor="bg-white border"
178
+ icon={<StarIcon className="w-5 h-5 text-yellow-500" />}
179
+ onClick={(e) => {
180
+ e.preventDefault();
181
+ e.stopPropagation();
182
+ console.log(data);
183
+ }}
184
+ />, // render additional custom button in each table row
185
+ ],
186
+ bareListFilterQuery: [
187
+ // INFO: Add query to filter data when type is list (table view, grid view, grid view etc)
188
+ // { type: "=", queryId: "status", value: "Approved" },
189
+ ],
190
+ bareListGridComponent: (data: any) => {
191
+ if (data?.status === "Approved") {
192
+ return (
193
+ <div className="text-sm p-2 rounded-lg bg-primary-50 text-primary-500">
194
+ Custom Component Below Main Content
195
+ </div>
196
+ );
197
+ } // add custom content below the grid item (will not overide the default UI)
198
+ },
199
+ bareListGridColClassName: "grid-cols-2 md:grid-cols-4 gap-4", // override the default grid column, row and gap classnames
200
+ bareListGridTags: (data) => {
201
+ const tags: string[] = [];
202
+ if (data?.status) tags.push(data.status);
203
+ if (data?.researchTitleAbbreviation)
204
+ tags.push(data.researchTitleAbbreviation);
205
+
206
+ return tags; // add small tags above grid item's title
207
+ },
208
+ bareListGridFallbackImg: (data) => {
209
+ if (data?.status === "Approved") {
210
+ return "https://images.unsplash.com/photo-1553877522-43269d4ea984?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3zD";
211
+ } else
212
+ return "https://images.unsplash.com/photo-1584644769698-4762ca337c17?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
213
+ }, // fallback image in case value for image column is not present
214
+ bareListGridRibbonText: (data) => {
215
+ if (data?.status?.includes("Review")) {
216
+ return "Review";
217
+ }
218
+ return ""; // add a ribbon on the top left corner of the grid item
219
+ },
220
+ bareListHandleData: (data) => {
221
+ console.log("Available data in current date: ", data); // returns all the data when type (view type) is list
222
+ },
223
+ bareReadComponent: () => (
224
+ <Alert title="Custom Alert in Read View" />
225
+ ), // Custom additional component in read view
226
+ bareReadComponentPos: "top", // position custom addition read view component to the top
227
+ bareReadComponentHide: false, // only set to true if want to override default read view with bareReadComponent
228
+ bareReadDescription: (key, value) => {
229
+ // INFO: override default UI with custom component where columnId matches key in read view
230
+ if (key === "status" && value) {
231
+ return <Tag tagText={value} />;
232
+ }
233
+ },
234
+ bareReadHandleData: (data) => {
235
+ console.log("Data from read view: ", data); // returns data when enter read view
236
+ },
237
+ bareReferenceDel: [
238
+ {
239
+ collectionId: "",
240
+ collectionName: "",
241
+ columnId: "",
242
+ schema: [],
243
+ },
244
+ ], // INFO: This is to prevent deletion of data if there is a reference input in schema and the reference column points to existing collection in database
245
+ bareUpdateMobileView: true, //INFO: This will render form input in compact mobile view
246
+ bareUpdateActionComponent:
247
+ // INFO: Add custom component on top right corner, normally used to add buttons
248
+ // NOTE: This will overide the default action buttons (except for Delete button). Add those buttons back manually
249
+ viewType === "read"
250
+ ? (data) => {
251
+ return (
252
+ <div className="flex gap-x-3">
253
+ <Button type="normal" text="Print" />
254
+ <Button
255
+ type="normal"
256
+ text="Update"
257
+ onClick={() => {
258
+ setSelectedId(data._id);
259
+ setViewType("update");
260
+ }}
261
+ />
262
+ </div>
263
+ );
264
+ }
265
+ : undefined,
266
+ bareUpdatePrefill: () => {
267
+ // INFO: prefill column values. These columns will no longer be visible on the form. Good for values that cannot be edited by users
268
+ return [
269
+ {
270
+ key: "updatedAt",
271
+ value: moment().toDate(),
272
+ },
273
+ ];
274
+ },
275
+ bareUpdateComponent: () => {
276
+ // INFO: add additional component to below form in update view
277
+ return (
278
+ <Alert
279
+ title="Hi there!"
280
+ desc="Custom component that shows below or above (based on bareUpdateComponentAbove) the form"
281
+ />
282
+ );
283
+ },
284
+ bareUpdateComponentAbove: true, // INFO: render bareUpdateComponent above the form. Set to false to render it below form
285
+ bareUpdateIndividualComponent: (
286
+ _columnId: string,
287
+ _ref: any,
288
+ _selectedData: any,
289
+ _setSelectedData: (data: any) => void,
290
+ ) => {
291
+ // INFO: Override default input with custom input, value state will be pass back to the form
292
+ // Example:
293
+ // if (columnId === "column X") {
294
+ // return (
295
+ // <TextInput
296
+ // ref={ref}
297
+ // label=""
298
+ // placeholder=""
299
+ // type="text"
300
+ // value={selectedData.columnId}
301
+ // onChange={(e) => setSelectedData(e.target.value)}
302
+ // />
303
+ // );
304
+ // }
305
+ return <div></div>;
306
+ },
307
+ bareUpdateHandleData: (data) => {
308
+ // INFO: returns data when enter update view
309
+ console.log("Update view data: ", data);
310
+ },
311
+ bareUpdateTabId: (tabId) => {
312
+ // INFO: Returns the current tab in update view
313
+ console.log("Updating data from tab ", tabId);
314
+ },
315
+ bareUpdateTabComponent: (tabIds) => {
316
+ // INFO: Add icon to tab or skip tab in update view
317
+ return tabIds.map((eachTabId, index: number) => {
318
+ const icon =
319
+ Math.floor(index / 2) % 2 === 0 ? (
320
+ <CheckCircleIcon className="w-5 h-5 text-primary-500" />
321
+ ) : (
322
+ <InformationCircleIcon className="w-5 h-5 text-yellow-500" />
323
+ );
324
+
325
+ return {
326
+ tabId: eachTabId,
327
+ icon,
328
+ skipped: false,
329
+ };
330
+ });
331
+ },
332
+ bareUpdateColumnType: "two", // control how many inputs to be dispalyed per row in update view (default is 2, small browser width default to 1)
333
+ bareUpdateHandlePreComplete: (data) => {
334
+ /**
335
+ * Example use cases:
336
+ * 1. Validate data before submission. Return true if validation pass, otherwise return false to prevent submission
337
+ * 2. Override column value in the data
338
+ */
339
+
340
+ // Example 1: Validate data
341
+ // if(validation passes){
342
+ // return true
343
+ // }else return false
344
+
345
+ // Example 2: Overrite column value
346
+ // if(condtion X){
347
+ // data.columnId = formatted value
348
+ // }
349
+
350
+ return data;
351
+ },
352
+ bareUpdateHandleComplete: async (data) => {
353
+ console.log("Form data to be submitted: ", data);
354
+ // INFO: Use this to override the default form submission (write request to databse)
355
+ // await handleCustomFormSubmit()
356
+ },
357
+ bareUpdateHandlePostComplete: async (data) => {
358
+ console.log("Form data after submission: ", data);
359
+ // INFO: Use this to perform other actions once form data is submitted (wrote to database)
360
+ // await handleCustomPostFormSubmit()
361
+ },
362
+ }}
363
+ organise={{
364
+ sort: { sortId: "createdAt", type: "desc" as const }, // sort list view data
365
+ hideSearch: false, // set to false to enable default search input in list view
366
+ filterComponentNewRow: true, // avoid crowding for filter inputs in list view
367
+ breadcrumbType: "button", // shows a "Back" button in read view and update view
368
+ tabAlign: "left", // shows form input categories (based on groupId from models in schema) in update view
369
+ showExport: true, // enable export CSV, Import CSV, Print etc. Only when type is list (table view, grid view, list view etc)
370
+ exportSettings: {
371
+ enableExportReadPDF: true, // enable export read view page UI, blob will be generated
372
+ exportReadPDFDimensions: {
373
+ forceDesktopView: true,
374
+ captureWidth: 1440,
375
+ pageSize: "a4",
376
+ scale: 2,
377
+ },
378
+ exportReadPDFHeader: {
379
+ image: {
380
+ src: "https://images.unsplash.com/photo-1773609108583-4f0040c75e7f?q=80&w=1332&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
381
+ alignment: "center",
382
+ height: 20,
383
+ width: 50,
384
+ },
385
+ text: {
386
+ value: "PDF",
387
+ alignment: "center",
388
+ },
389
+ },
390
+ onExportReadPDFBlob: async (blob) => {
391
+ const fileName = `Export-${moment().format(
392
+ "YYYY-MM-DD-HH-mm-ss",
393
+ )}.pdf`;
394
+ const file = new File([blob], fileName, {
395
+ type: "application/pdf",
396
+ });
397
+ console.log("Read View Export: ", file);
398
+ // Process blob to generate PDF
399
+ },
400
+ },
401
+ }}
402
+ handleNavigate={handleNavigate}
403
+ additionalQuery={[
404
+ {
405
+ type: "list",
406
+ value: "sustainableDevelopmentGoals",
407
+ options: [
408
+ "No poverty",
409
+ "Zero Hunger",
410
+ "Good Health and Well Being",
411
+ ],
412
+ filterLabel: "Development Goals",
413
+ },
414
+ {
415
+ type: "reference",
416
+ value: "grantId",
417
+ spaceId: "kpj-grants",
418
+ label: "title",
419
+ filterLabel: "Grant ID",
420
+ },
421
+ {
422
+ type: "range",
423
+ value: "createdAt",
424
+ },
425
+ ]}
426
+ limit={10}
427
+ viewSettings={renderViewSettings()}
428
+ />
429
+ </div>
430
+ </StorySection>
431
+ );
432
+ });
433
+
434
+ stories.add("Data Wrapper Union", () => {
435
+ const [mount, setMount] = useState<boolean>(false);
436
+ const dataRefreshRef: any = useRef(null);
437
+ const [statusFilter, setStatusFilter] = useState<string>("all");
438
+ const [startDate, setStartDate] = useState<string>("");
439
+ const [endDate, setEndDate] = useState<string>("");
440
+ const [installerFilter, setInstallerFilter] = useState<string>("Wai Seng");
441
+ const [viewType, setViewType] = useState<"list" | "read" | "update">("list");
442
+ const [selectedId, setSelectedId] = useState<string | undefined>(undefined);
443
+
444
+ useEffect(() => {
445
+ setMount(true);
446
+ }, []);
447
+
448
+ useEffect(() => {
449
+ if (mount && dataRefreshRef.current) {
450
+ dataRefreshRef.current.handleRefresh();
451
+ }
452
+ }, [installerFilter, statusFilter, startDate, endDate, mount]);
453
+
454
+ const handleNavigate = (type: any, id: any, viewId: any) => {
455
+ setViewType(type);
456
+ setSelectedId(id);
457
+ };
458
+
459
+ const handleBackToList = () => {
460
+ setViewType("list");
461
+ setSelectedId(undefined);
462
+ };
463
+
464
+ const getUnionCollectionsConfig = () => {
465
+ const basePersonQuery: any[] = [];
466
+
467
+ if (installerFilter.length > 0) {
468
+ basePersonQuery.push({
469
+ type: "search",
470
+ searchIds: ["installer", "inspector"],
471
+ value: installerFilter,
472
+ });
473
+ }
474
+
475
+ if (statusFilter !== "all") {
476
+ basePersonQuery.push({
477
+ queryId: "status",
478
+ type: "=",
479
+ value: statusFilter,
480
+ });
481
+ }
482
+
483
+ const getDateQuery = (dateField: string) => {
484
+ if (startDate || endDate) {
485
+ return {
486
+ queryId: dateField,
487
+ value:
488
+ startDate && endDate
489
+ ? [
490
+ new Date(startDate).toISOString(),
491
+ new Date(endDate).toISOString(),
492
+ ]
493
+ : new Date(startDate).toISOString(),
494
+ type: startDate && endDate ? "><" : ">",
495
+ };
496
+ }
497
+ return null;
498
+ };
499
+
500
+ return {
501
+ unionCollections: [
502
+ {
503
+ collection: "verdant-deliveries",
504
+ source: "dynamic",
505
+ sourceLogic: {
506
+ $cond: {
507
+ if: { $eq: ["$type", "om"] },
508
+ then: "O&M Maintenance",
509
+ else: "PV Delivery",
510
+ },
511
+ },
512
+ query: [
513
+ {
514
+ queryId: "type",
515
+ type: "in",
516
+ value: ["om", "pv"],
517
+ },
518
+ ...(getDateQuery("proposed_date")
519
+ ? [
520
+ {
521
+ queryId: "proposed_date",
522
+ type: getDateQuery("proposed_date")!.type,
523
+ value: getDateQuery("proposed_date")!.value,
524
+ orQuery: true,
525
+ orQueryGroupId: "deliveryDate",
526
+ },
527
+ ]
528
+ : []),
529
+ ...(getDateQuery("tent_installation_date")
530
+ ? [
531
+ {
532
+ queryId: "tent_installation_date",
533
+ type: getDateQuery("tent_installation_date")!.type,
534
+ value: getDateQuery("tent_installation_date")!.value,
535
+ orQuery: true,
536
+ orQueryGroupId: "deliveryDate",
537
+ },
538
+ ]
539
+ : []),
540
+ ...basePersonQuery,
541
+ ].filter(Boolean),
542
+ projection: {
543
+ _id: 1,
544
+ mondayItemId: 1,
545
+ clientName: 1,
546
+ date: 1,
547
+ createdAt: 1,
548
+ type: 1,
549
+ status: 1,
550
+ installer: 1,
551
+ name: 1,
552
+ phone: 1,
553
+ location: 1,
554
+ proposed_date: 1,
555
+ tent_installation_date: 1,
556
+ tent_service_date: 1,
557
+ checklist_status: 1,
558
+ },
559
+ addFields: {
560
+ sortDate: {
561
+ $ifNull: [
562
+ {
563
+ $cond: {
564
+ if: { $eq: ["$type", "om"] },
565
+ then: "$proposed_date",
566
+ else: "$tent_installation_date",
567
+ },
568
+ },
569
+ "$createdAt",
570
+ ],
571
+ },
572
+ },
573
+ },
574
+ {
575
+ collection: "verdant-service-tickets",
576
+ source: "dynamic",
577
+ sourceLogic: {
578
+ $cond: {
579
+ if: { $eq: ["$category", "Installation Defect"] },
580
+ then: "Installation Defect",
581
+ else: "Critical Load",
582
+ },
583
+ },
584
+ query: [
585
+ {
586
+ queryId: "category",
587
+ type: "in",
588
+ value: ["Installation Defect", "Critical Load"],
589
+ },
590
+ ...(getDateQuery("tent_service_date")
591
+ ? [
592
+ {
593
+ queryId: "tent_service_date",
594
+ type: getDateQuery("tent_service_date")!.type,
595
+ value: getDateQuery("tent_service_date")!.value,
596
+ },
597
+ ]
598
+ : []),
599
+ ...basePersonQuery,
600
+ ].filter(Boolean),
601
+ projection: {
602
+ _id: 1,
603
+ mondayItemId: 1,
604
+ clientName: 1,
605
+ date: 1,
606
+ createdAt: 1,
607
+ category: 1,
608
+ status: 1,
609
+ installer: 1,
610
+ name: 1,
611
+ phone: 1,
612
+ location: 1,
613
+ tent_service_date: 1,
614
+ checklist_status: 1,
615
+ },
616
+ addFields: {
617
+ sortDate: {
618
+ $ifNull: ["$tent_service_date", "$createdAt"],
619
+ },
620
+ },
621
+ },
622
+ ],
623
+ sort: { sortId: "sortDate", type: "desc" as const },
624
+ };
625
+ };
626
+
627
+ if (!mount) {
628
+ return <Loading />;
629
+ }
630
+
631
+ return (
632
+ <Container bgColor="bg-white">
633
+ <div className="mb-4 flex flex-wrap items-end gap-4">
634
+ {viewType !== "list" && (
635
+ <button
636
+ onClick={handleBackToList}
637
+ className="px-3 py-1 text-sm bg-gray-200 hover:bg-gray-300 rounded-md"
638
+ >
639
+ ← Back to List
640
+ </button>
641
+ )}
642
+ {viewType === "list" && (
643
+ <>
644
+ <div className="flex flex-col">
645
+ <label className="text-sm text-gray-700 mb-1">
646
+ Filter by Installer
647
+ </label>
648
+ <select
649
+ className="border border-gray-300 rounded-md px-2 py-1 text-sm"
650
+ value={installerFilter}
651
+ onChange={(e) => setInstallerFilter(e.target.value)}
652
+ >
653
+ <option value="Wai Seng">Wai Seng</option>
654
+ <option value="John Doe">John Doe</option>
655
+ <option value="Jane Smith">Jane Smith</option>
656
+ </select>
657
+ </div>
658
+ <div className="flex flex-col">
659
+ <label className="text-sm text-gray-700 mb-1">
660
+ Filter by Status
661
+ </label>
662
+ <select
663
+ className="border border-gray-300 rounded-md px-2 py-1 text-sm"
664
+ value={statusFilter}
665
+ onChange={(e) => setStatusFilter(e.target.value)}
666
+ >
667
+ <option value="all">All</option>
668
+ <option value="Pending to set">Pending to set</option>
669
+ <option value="Confirmed">Confirmed</option>
670
+ </select>
671
+ </div>
672
+ <div className="flex flex-col">
673
+ <label className="text-sm text-gray-700 mb-1">Start Date</label>
674
+ <input
675
+ type="date"
676
+ className="border border-gray-300 rounded-md px-2 py-1 text-sm"
677
+ value={startDate}
678
+ onChange={(e) => setStartDate(e.target.value)}
679
+ />
680
+ </div>
681
+ <div className="flex flex-col">
682
+ <label className="text-sm text-gray-700 mb-1">End Date</label>
683
+ <input
684
+ type="date"
685
+ className="border border-gray-300 rounded-md px-2 py-1 text-sm"
686
+ value={endDate}
687
+ onChange={(e) => setEndDate(e.target.value)}
688
+ />
689
+ </div>
690
+ </>
691
+ )}
692
+ {viewType !== "list" && (
693
+ <div className="flex flex-col">
694
+ <label className="text-sm text-gray-700 mb-1">Current View:</label>
695
+ <div className="text-xs text-gray-600">
696
+ {viewType} - ID: {selectedId}
697
+ </div>
698
+ </div>
699
+ )}
700
+ </div>
701
+ <DataTemplateWrapper
702
+ ref={dataRefreshRef}
703
+ title={"Union Collections Demo"}
704
+ description="Dynamic unionCollections combining deliveries & service tickets with installer filtering"
705
+ type={viewType}
706
+ id={selectedId}
707
+ collectionId="verdant-deliveries"
708
+ schema={
709
+ [
710
+ {
711
+ id: "source",
712
+ name: "Source",
713
+ type: "string",
714
+ hideForm: true,
715
+ },
716
+ {
717
+ id: "type",
718
+ name: "Type",
719
+ type: "string",
720
+ optional: true,
721
+ hideForm: true,
722
+ },
723
+ {
724
+ id: "name",
725
+ name: "Client Name",
726
+ type: "string",
727
+ optional: true,
728
+ hideForm: true,
729
+ },
730
+ {
731
+ id: "status",
732
+ name: "Status",
733
+ type: "string",
734
+ optional: true,
735
+ hideForm: true,
736
+ },
737
+ {
738
+ id: "category",
739
+ name: "Category",
740
+ type: "string",
741
+ optional: true,
742
+ hideForm: true,
743
+ },
744
+ {
745
+ id: "proposed_date",
746
+ name: "Proposed Date",
747
+ type: "date",
748
+ optional: true,
749
+ hideForm: true,
750
+ },
751
+ {
752
+ id: "tent_service_date",
753
+ name: "Service Date",
754
+ type: "date",
755
+ optional: true,
756
+ hideForm: true,
757
+ },
758
+ {
759
+ id: "date",
760
+ name: "Date",
761
+ type: "date",
762
+ optional: true,
763
+ hideForm: true,
764
+ },
765
+ {
766
+ id: "location",
767
+ name: "Location",
768
+ type: "string",
769
+ optional: true,
770
+ hideForm: true,
771
+ },
772
+ {
773
+ id: "installer",
774
+ name: "Installer",
775
+ type: "string",
776
+ optional: true,
777
+ hideForm: true,
778
+ },
779
+ {
780
+ id: "checklist_status",
781
+ name: "Checklist Status",
782
+ type: "string",
783
+ optional: true,
784
+ hideForm: true,
785
+ },
786
+ {
787
+ id: "phone",
788
+ name: "Phone",
789
+ type: "string",
790
+ optional: true,
791
+ hideForm: true,
792
+ },
793
+ {
794
+ id: "mondayItemId",
795
+ name: "Monday Item ID",
796
+ type: "string",
797
+ optional: true,
798
+ hideForm: true,
799
+ },
800
+ {
801
+ id: "clientName",
802
+ name: "Client",
803
+ type: "string",
804
+ optional: true,
805
+ hideForm: true,
806
+ },
807
+ ] as DataStructure[]
808
+ }
809
+ workspace={{
810
+ apiEndpointType: "mongoDB",
811
+ apiEndpoint: "http://localhost:3000/api/mongoData",
812
+ apiEndpointToken: "",
813
+ assetUploadEndpoint: "http://localhost:3000/api/asset",
814
+ apiUserToken: "",
815
+ }}
816
+ bareSettings={{
817
+ bareUpdateMobileView: true,
818
+ }}
819
+ organise={getUnionCollectionsConfig()}
820
+ handleNavigate={handleNavigate}
821
+ lib={{
822
+ storage: null,
823
+ ref: null,
824
+ getDownloadURL: null,
825
+ uploadBytes: null,
826
+ }}
827
+ limit={50}
828
+ />
829
+ </Container>
830
+ );
831
+ });