diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py
index 5f493ae..152e3bd 100644
--- a/commit/commit/doctype/commit_docs/commit_docs.py
+++ b/commit/commit/doctype/commit_docs/commit_docs.py
@@ -51,6 +51,33 @@ def get_docs_sidebar_parent_labels(id:str):
return parent_labels_obj
+@frappe.whitelist()
+def get_all_commit_docs_detail():
+ '''
+ Get the All Commit Docs Details which are Published
+ # 1. Get the Commit Docs Document from the route
+ # 2. Check if the Commit Docs Document Published
+ # 3. Return the Commit Docs Document
+ # 4. Get The Sidebar Items for the Commit Docs
+ # 5. Return the Sidebar Items
+ '''
+
+ # Get All the Commit Docs which are Published
+ all_commit_docs = frappe.get_all('Commit Docs',{'published':1},'name')
+
+ # Maintain the Commit Docs Object
+ commit_docs_obj = {}
+
+ for commit_docs in all_commit_docs:
+ commit_docs = frappe.get_doc('Commit Docs',commit_docs.name).as_dict()
+
+ parse_doc = parse_commit_docs(commit_docs)
+
+ commit_docs_obj[commit_docs['route']] = parse_doc
+
+ return commit_docs_obj
+
+
@frappe.whitelist(allow_guest=True)
def get_commit_docs_details(route:str):
'''
@@ -67,35 +94,11 @@ def get_commit_docs_details(route:str):
# Check if the document is published
if frappe.db.get_value('Commit Docs',{'route':route},'published'):
-
# Get the Commit Docs Document
commit_docs = frappe.get_doc('Commit Docs',{'route':route}).as_dict()
- # Maintain route_map from the sidebar where key is the route and value is the name of the page
- route_map = {}
-
- # Get the Sidebar Items
- sidebar_items, route_map = get_sidebar_items(commit_docs.sidebar,route_map)
-
- # Get the Footer Items
- footer_items = get_footer_items(commit_docs.footer)
-
- # Get the Navbar Items
- navbar_items = get_navbar_items(commit_docs.navbar_items)
+ return parse_commit_docs(commit_docs)
- # remove the sidebar from the commit_docs as it is not needed
- commit_docs.pop('sidebar')
- commit_docs.pop('footer')
- commit_docs.pop('navbar_items')
-
- return {
- 'commit_docs': commit_docs,
- 'sidebar_items': sidebar_items,
- 'footer_items': footer_items,
- 'navbar_items': navbar_items,
- 'route_map': route_map
- }
-
else:
return frappe.throw('Docs Not Published')
@@ -103,6 +106,32 @@ def get_commit_docs_details(route:str):
return frappe.throw('Docs Not Found')
+def parse_commit_docs(commit_docs):
+ # Maintain route_map from the sidebar where key is the route and value is the name of the page
+ route_map = {}
+
+ # Get the Sidebar Items
+ sidebar_items, route_map = get_sidebar_items(commit_docs.sidebar,route_map)
+
+ # Get the Footer Items
+ footer_items = get_footer_items(commit_docs.footer)
+
+ # Get the Navbar Items
+ navbar_items = get_navbar_items(commit_docs.navbar_items)
+
+ # remove the sidebar from the commit_docs as it is not needed
+ commit_docs.pop('sidebar')
+ commit_docs.pop('footer')
+ commit_docs.pop('navbar_items')
+
+ return {
+ 'commit_docs': commit_docs,
+ 'sidebar_items': sidebar_items,
+ 'footer_items': footer_items,
+ 'navbar_items': navbar_items,
+ 'route_map': route_map
+ }
+
def get_footer_items(footer):
'''
Get the Footer Items
diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.json b/commit/commit/doctype/commit_docs_page/commit_docs_page.json
index 4110d98..989f952 100644
--- a/commit/commit/doctype/commit_docs_page/commit_docs_page.json
+++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.json
@@ -1,133 +1,133 @@
{
- "actions": [],
- "allow_rename": 1,
- "autoname": "format:{title}-{route}",
- "creation": "2024-10-29 19:39:29.842455",
- "doctype": "DocType",
- "engine": "InnoDB",
- "field_order": [
- "title",
- "route",
- "published",
- "allow_guest",
- "icon",
- "column_break_sedp",
- "badge",
- "badge_color",
- "is_group_page",
- "documentation_section",
- "content",
- "section_break_twyn",
- "linked_pages"
- ],
- "fields": [
- {
- "fieldname": "title",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Title",
- "reqd": 1
- },
- {
- "fieldname": "route",
- "fieldtype": "Data",
- "in_list_view": 1,
- "in_preview": 1,
- "in_standard_filter": 1,
- "label": "Route",
- "reqd": 1,
- "unique": 1
- },
- {
- "default": "1",
- "fieldname": "published",
- "fieldtype": "Check",
- "label": "Published"
- },
- {
- "default": "1",
- "fieldname": "allow_guest",
- "fieldtype": "Check",
- "label": "Allow Guest"
- },
- {
- "depends_on": "eval:doc.is_group_page == 0",
- "fieldname": "content",
- "fieldtype": "Markdown Editor",
- "ignore_xss_filter": 1,
- "label": "Content"
- },
- {
- "description": "This is badge field, eg: GET , POST etc.",
- "fieldname": "badge",
- "fieldtype": "Data",
- "label": "Badge"
- },
- {
- "description": "Add Tailwind colours like red, green, blue, yellow, purple, pink, indigo, cyan, teal, lime, orange, gray etc.",
- "fieldname": "badge_color",
- "fieldtype": "Data",
- "label": "Badge Color"
- },
- {
- "fieldname": "column_break_sedp",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "description": "When enabled, this page can hold and display nested sub-pages, creating a structured hierarchy in the sidebar.",
- "fieldname": "is_group_page",
- "fieldtype": "Check",
- "label": "Is Group Page"
- },
- {
- "fieldname": "documentation_section",
- "fieldtype": "Section Break",
- "label": "Documentation"
- },
- {
- "description": "\"Supports only icons from the react-icons library. Enter the icon name in the format 'libraryPrefix/IconName' (e.g., 'Fa/FaFileExcel') to display it beside the title in the sidebar.\"\n",
- "documentation_url": "https://react-icons.github.io/react-icons/search/",
- "fieldname": "icon",
- "fieldtype": "Data",
- "label": "Icon"
- },
- {
- "fieldname": "section_break_twyn",
- "fieldtype": "Section Break"
- },
- {
- "depends_on": "eval:doc.is_group_page == 1",
- "fieldname": "linked_pages",
- "fieldtype": "Table",
- "label": "Linked Pages",
- "options": "Linked Commit Docs Page"
- }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2024-11-15 15:20:42.503563",
- "modified_by": "Administrator",
- "module": "commit",
- "name": "Commit Docs Page",
- "naming_rule": "Expression",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "share": 1,
- "write": 1
- }
- ],
- "sort_field": "creation",
- "sort_order": "DESC",
- "states": [],
- "title_field": "title"
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "format:{title}-{route}",
+ "creation": "2024-10-29 19:39:29.842455",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+ "title",
+ "route",
+ "published",
+ "allow_guest",
+ "icon",
+ "column_break_sedp",
+ "badge",
+ "badge_color",
+ "is_group_page",
+ "documentation_section",
+ "content",
+ "section_break_twyn",
+ "linked_pages"
+ ],
+ "fields": [
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Title",
+ "reqd": 1
+ },
+ {
+ "fieldname": "route",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "in_preview": 1,
+ "in_standard_filter": 1,
+ "label": "Route",
+ "reqd": 1,
+ "unique": 1
+ },
+ {
+ "default": "1",
+ "fieldname": "published",
+ "fieldtype": "Check",
+ "label": "Published"
+ },
+ {
+ "default": "1",
+ "fieldname": "allow_guest",
+ "fieldtype": "Check",
+ "label": "Allow Guest"
+ },
+ {
+ "depends_on": "eval:doc.is_group_page == 0",
+ "fieldname": "content",
+ "fieldtype": "Markdown Editor",
+ "ignore_xss_filter": 1,
+ "label": "Content"
+ },
+ {
+ "description": "This is badge field, eg: GET , POST etc.",
+ "fieldname": "badge",
+ "fieldtype": "Data",
+ "label": "Badge"
+ },
+ {
+ "description": "Add Tailwind colours like red, green, blue, yellow, purple, pink, indigo, cyan, teal, lime, orange, gray etc.",
+ "fieldname": "badge_color",
+ "fieldtype": "Data",
+ "label": "Badge Color"
+ },
+ {
+ "fieldname": "column_break_sedp",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "description": "When enabled, this page can hold and display nested sub-pages, creating a structured hierarchy in the sidebar.",
+ "fieldname": "is_group_page",
+ "fieldtype": "Check",
+ "label": "Is Group Page"
+ },
+ {
+ "fieldname": "documentation_section",
+ "fieldtype": "Section Break",
+ "label": "Documentation"
+ },
+ {
+ "description": "\"Supports only icons from the lucid-react library. Enter the icon name in the format 'libraryPrefix/IconName' (e.g., 'Fa/FaFileExcel') to display it beside the title in the sidebar.\"\n",
+ "documentation_url": "https://lucide.dev/icons",
+ "fieldname": "icon",
+ "fieldtype": "Data",
+ "label": "Icon"
+ },
+ {
+ "fieldname": "section_break_twyn",
+ "fieldtype": "Section Break"
+ },
+ {
+ "depends_on": "eval:doc.is_group_page == 1",
+ "fieldname": "linked_pages",
+ "fieldtype": "Table",
+ "label": "Linked Pages",
+ "options": "Linked Commit Docs Page"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [],
+ "modified": "2024-12-13 14:07:48.524842",
+ "modified_by": "Administrator",
+ "module": "commit",
+ "name": "Commit Docs Page",
+ "naming_rule": "Expression",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "sort_field": "creation",
+ "sort_order": "DESC",
+ "states": [],
+ "title_field": "title"
}
\ No newline at end of file
diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.py b/commit/commit/doctype/commit_docs_page/commit_docs_page.py
index e3bf74f..3726f55 100644
--- a/commit/commit/doctype/commit_docs_page/commit_docs_page.py
+++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.py
@@ -93,7 +93,7 @@ def publish_documentation(project_branch, endpoint, viewer_type, docs_name, pare
'commit_docs': commit_docs.name
}
-@frappe.whitelist()
+@frappe.whitelist(allow_guest=True)
def get_commit_docs_page(name):
'''
Get the Commit Docs Page
diff --git a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json
index d2034da..fa2edf2 100644
--- a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json
+++ b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json
@@ -53,6 +53,7 @@
"label": "Parent Label"
},
{
+ "description": "\"Supports only icons from the lucid-react library. Enter the icon name, eg:\"Bell\" to display it beside the title in the sidebar.\"\n",
"fieldname": "icon",
"fieldtype": "Data",
"label": "Icon"
@@ -73,7 +74,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2024-11-09 18:41:50.962807",
+ "modified": "2024-12-13 14:08:16.402492",
"modified_by": "Administrator",
"module": "commit",
"name": "Commit Docs Topbar Item",
diff --git a/commit/www/commit.py b/commit/www/commit.py
index d92d51f..ced1b6a 100644
--- a/commit/www/commit.py
+++ b/commit/www/commit.py
@@ -2,19 +2,17 @@
import json
import frappe.sessions
import re
-
+from commit.api.meta_data import get_installed_apps
+from commit.commit.doctype.commit_docs.commit_docs import get_all_commit_docs_detail
no_cache = 1
SCRIPT_TAG_PATTERN = re.compile(r"\")
def get_context(context):
- csrf_token = frappe.sessions.get_csrf_token()
- frappe.db.commit()
context = frappe._dict()
context.boot = get_boot()
- context.csrf_token = csrf_token
context.build_version = frappe.utils.get_build_version()
return context
@@ -36,6 +34,8 @@ def get_boot():
show_system_apps = commit_settings.show_system_apps
boot["show_system_apps"] = show_system_apps
+ boot["get_installed_apps"] = get_installed_apps()
+ boot["get_all_commit_docs_detail"] = get_all_commit_docs_detail()
boot_json = frappe.as_json(boot, indent=None, separators=(",", ":"))
boot_json = SCRIPT_TAG_PATTERN.sub("", boot_json)
diff --git a/dashboard/index.html b/dashboard/index.html
index 2eaa979..4d0e54f 100644
--- a/dashboard/index.html
+++ b/dashboard/index.html
@@ -9,6 +9,8 @@
+
Commit - Developer tooling for the Frappeverse
diff --git a/dashboard/package.json b/dashboard/package.json
index 08fa1da..d97d157 100644
--- a/dashboard/package.json
+++ b/dashboard/package.json
@@ -53,20 +53,22 @@
"jotai": "^2.8.3",
"lodash": "^4.17.21",
"lodash.isplainobject": "^4.0.6",
+ "lucide-react": "^0.468.0",
"moment-timezone": "^0.5.43",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.45.1",
- "react-icons": "^5.2.1",
"react-router-dom": "^6.14.1",
"reactflow": "^11.11.4",
"rehype-katex": "^7.0.1",
+ "rehype-pretty-code": "^0.14.0",
"rehype-raw": "^7.0.0",
"remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"shadcn-ui": "^0.8.0",
+ "shiki": "^1.24.3",
"socket.io-client": "^4.5.1",
"swr": "^2.1.5",
"tailwind-merge": "^1.13.2",
diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx
index d36d6e1..56702d0 100644
--- a/dashboard/src/App.tsx
+++ b/dashboard/src/App.tsx
@@ -1,13 +1,16 @@
import { FrappeProvider } from 'frappe-react-sdk'
import { BrowserRouter, Route, Routes } from 'react-router-dom'
-import { APIViewerContainer } from './pages/features/api_viewer/APIViewer'
-import { Overview } from './pages/overview/Overview'
-import { ERDViewer } from './pages/features/erd/ERDViewer'
-import { AppAPIViewerContainer } from './pages/features/api_viewer/AppAPIViewer'
-import { CreateERD } from './pages/features/erd/meta/CreateERDForMeta'
-import ViewDocs from './pages/features/docs/ViewDocs'
-import { PageNotFound } from './components/common/PageNotFound/PageNotFound'
-import DocsPage from './pages/features/docs/DocsPage'
+import { lazy, Suspense } from 'react'
+import { FullPageLoader } from './components/common/FullPageLoader/FullPageLoader'
+
+const ERDViewer = lazy(async () => import('./pages/features/erd/ERDViewer'))
+const Overview = lazy(async () => import('./pages/overview/Overview'))
+const APIViewerContainer = lazy(async () => import('./pages/features/api_viewer/APIViewer'))
+const AppAPIViewerContainer = lazy(async () => import('./pages/features/api_viewer/AppAPIViewer'))
+const CreateERD = lazy(async () => import('./pages/features/erd/meta/CreateERDForMeta'))
+const ViewDocs = lazy(async () => import('./pages/features/docs/ViewDocs'))
+const PageNotFound = lazy(async () => import('./components/common/PageNotFound/PageNotFound'))
+const DocsPage = lazy(async () => import('./pages/features/docs/DocsPage'))
function App() {
@@ -24,25 +27,27 @@ function App() {
return (
+ }>
{/* */}
-
- {/** Public Routes */}
- {/* } /> */}
+
+ {/** Public Routes */}
+ {/* } /> */}
- {/** Private Routes */}
- {/* } /> */}
- {/* default route on '/' */}
- } />
- {/*TODO: Need to Change below route */}
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
+ {/** Private Routes */}
+ {/* } /> */}
+ {/* default route on '/' */}
+ } />
+ {/*TODO: Need to Change below route */}
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
{/* */}
diff --git a/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx b/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx
index 6e807bc..4eb76a8 100644
--- a/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx
+++ b/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx
@@ -1,5 +1,5 @@
import { FrappeError, useFrappePostCall } from 'frappe-react-sdk'
-import { PropsWithChildren, useEffect, useRef } from 'react'
+import { lazy, PropsWithChildren, Suspense, useEffect, useRef } from 'react'
import { Filter, useFrappeGetCall } from "frappe-react-sdk";
import { useCallback, useMemo, useState } from "react";
import { RegisterOptions, useController, useFormContext } from "react-hook-form";
@@ -12,9 +12,11 @@ import { useDebounce } from '@/hooks/useDebounce';
import { getLinkTitleAtom, setLinkTitleAtom } from './LinkTitles';
import { AsyncSpinnerLoader } from '../FullPageLoader/SpinnerLoader';
import { getErrorMessages } from '../ErrorBanner/ErrorBanner';
-import MDXRenderer from '../MarkdownRenderer/MDX';
+import { FullPageLoader } from '../FullPageLoader/FullPageLoader';
+const MDXRenderer = lazy(() => import('../MarkdownRenderer/MDX'))
+
interface ResultItem {
value: string,
description: string,
@@ -472,7 +474,9 @@ const ErrorContainer = ({ error }: { error?: FrappeError }) => {
- {getErrorMessages(error).map(e => )}
+ }>
+ {getErrorMessages(error).map(e => )}
+
);
diff --git a/dashboard/src/components/common/Checkbox/CreatableSelect.tsx b/dashboard/src/components/common/Checkbox/CreatableSelect.tsx
index 4c46907..6c1b7a7 100644
--- a/dashboard/src/components/common/Checkbox/CreatableSelect.tsx
+++ b/dashboard/src/components/common/Checkbox/CreatableSelect.tsx
@@ -13,10 +13,9 @@ import {
PopoverTrigger,
} from '@/components/ui/popover';
import { ScrollArea } from '@/components/ui/scroll-area';
-import { MdAdd, MdCheck } from 'react-icons/md';
-import { LuChevronsUpDown } from 'react-icons/lu';
import { Input } from '@/components/ui/input';
import { Controller, UseControllerProps, useFormContext } from 'react-hook-form';
+import { Check, ChevronsUpDown, Plus } from 'lucide-react';
export type ComboboxOptions = {
value: string;
@@ -76,7 +75,7 @@ export const CreatableSelect = ({ options, selected, className, label, mode = 's
) : (
`Select ${label ?? 'Item'}`
)}
-
+
@@ -111,7 +110,7 @@ export const CreatableSelect = ({ options, selected, className, label, mode = 's
}
}}
>
-
+
)}
@@ -218,7 +217,7 @@ export const FormCreatableSelect = ({
) : (
`Select ${label ?? 'Item'}`
)}
-
+
@@ -246,7 +245,7 @@ export const FormCreatableSelect = ({
}
}}
>
- setIsCreating(true)}
>
{`Add ${label ?? 'Item'}`}
-
+
)}
diff --git a/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx
index 7979661..f11595c 100644
--- a/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx
+++ b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx
@@ -1,82 +1,65 @@
-import { CSSProperties, lazy, Suspense, SVGAttributes, useMemo } from "react";
-import { IconContext } from "react-icons";
+import React, { CSSProperties, lazy, Suspense, SVGAttributes, useMemo } from 'react';
-interface IProps {
+interface LucideDynamicIconProps {
icon: string;
color?: string;
- size?: string;
+ size?: number | string;
className?: string;
style?: CSSProperties;
+ strokeWidth?: number;
+ absoluteStrokeWidth?: boolean;
attr?: SVGAttributes;
fallback?: JSX.Element | null;
}
+
// Helper to load the icon
-const loadIcon = async (icon: string) => {
- const [library, iconName] = icon.split("/");
- const lib = library.toLowerCase();
- // Statically construct the import statement using a function map
- // Full list of importable libraries from react-icons
- const moduleImporters: Record Promise> = {
- ai: () => import("react-icons/ai"), // Ant Design Icons
- bs: () => import("react-icons/bs"), // Bootstrap Icons
- bi: () => import("react-icons/bi"), // BoxIcons
- ci: () => import("react-icons/ci"), // Circum Icons
- cg: () => import("react-icons/cg"), // css.gg
- di: () => import("react-icons/di"), // Devicons
- fi: () => import("react-icons/fi"), // Feather Icons
- fc: () => import("react-icons/fc"), // Flat Color Icons
- fa: () => import("react-icons/fa"), // Font Awesome 5 Icons
- fa6: () => import("react-icons/fa6"), // Font Awesome 6 Icons
- gi: () => import("react-icons/gi"), // Game Icons
- go: () => import("react-icons/go"), // GitHub Octicons
- gr: () => import("react-icons/gr"), // Grommet Icons
- hi: () => import("react-icons/hi"), // Heroicons
- hi2: () => import("react-icons/hi2"), // Heroicons v2
- im: () => import("react-icons/im"), // IcoMoon Free
- lia: () => import("react-icons/lia"), // Icons8 Line Awesome
- io: () => import("react-icons/io"), // Ionicons
- io5: () => import("react-icons/io5"), // Ionicons v5
- lu: () => import("react-icons/lu"), // Lucide Icons
- md: () => import("react-icons/md"), // Material Design Icons
- pi: () => import("react-icons/pi"), // Phosphor Icons
- rx: () => import("react-icons/rx"), // Radix Icons
- ri: () => import("react-icons/ri"), // Remix Icons
- si: () => import("react-icons/si"), // Simple Icons
- sl: () => import("react-icons/sl"), // Simple Line Icons
- tb: () => import("react-icons/tb"), // Tabler Icons
- tfi: () => import("react-icons/tfi"), // Themify Icons
- ti: () => import("react-icons/ti"), // Typicons
- vsc: () => import("react-icons/vsc"), // VS Code Icons
- wi: () => import("react-icons/wi"), // Weather Icons
- };
+const loadLucideIcon = async (iconName: string) => {
+ try {
+ const module: any = await import('lucide-react');
+ const IconComponent = module[iconName];
+
+ if (!IconComponent) {
+ throw new Error(`Icon "${iconName}" not found in Lucide React library`);
+ }
- const importer = moduleImporters[lib];
- if (!importer) throw new Error(`Icon library "${library}" is not supported.`);
- const module = await importer()
- const IconComponent = module[iconName]
- if (!IconComponent) throw new Error(`Icon "${icon}" not found in "${library}".`)
- return IconComponent
+ return IconComponent;
+ } catch (error) {
+ console.error('Failed to load Lucide icon:', error);
+ throw error;
+ }
};
-const DynamicIcon: React.FC = ({ icon, color, size, className, style, attr, fallback = null }) => {
+const DynamicIcon: React.FC = ({
+ icon,
+ color,
+ size = 24,
+ className,
+ style,
+ strokeWidth,
+ absoluteStrokeWidth,
+ attr,
+ fallback = null
+}) => {
// Memoize the icon component so it's loaded only when `icon` changes
const Icon = useMemo(
- () => lazy(() => loadIcon(icon).then((component) => ({ default: component }))),
+ () => lazy(() => loadLucideIcon(icon).then((component) => ({ default: component }))),
[icon]
);
- const iconContext = {
- color,
- size,
- className,
- style,
- attr,
- };
+
return (
-
-
-
+
);
};
+
export default DynamicIcon;
diff --git a/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx b/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx
index 640316c..f7cee0e 100644
--- a/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx
+++ b/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx
@@ -1,7 +1,8 @@
import { FrappeError } from 'frappe-react-sdk'
-import { useMemo } from 'react'
-import MDXRenderer from '../MarkdownRenderer/MDX'
+import { lazy, Suspense, useMemo } from 'react'
+import { FullPageLoader } from '../FullPageLoader/FullPageLoader'
+const MDXRenderer = lazy(() => import('../MarkdownRenderer/MDX'))
interface ErrorBannerProps extends React.HTMLAttributes {
error?: FrappeError | null,
@@ -123,8 +124,10 @@ export const ErrorBanner = ({ error, overrideHeading, ...props }: ErrorBannerPro
+ }>
{messages.map((m, i) =>
)}
+
diff --git a/dashboard/src/components/common/Icons.ts b/dashboard/src/components/common/Icons.ts
index 8de3f8a..45e3cbf 100644
--- a/dashboard/src/components/common/Icons.ts
+++ b/dashboard/src/components/common/Icons.ts
@@ -1,63 +1,48 @@
-import { IconType } from 'react-icons'
-import { GrCurrency, GrFormAttachment, GrTextAlignFull } from 'react-icons/gr'
-import { AiFillCode, AiFillFileImage, AiFillHtml5, AiOutlineHtml5, AiOutlineLink, AiOutlinePhone, AiOutlineStar, AiOutlineTable } from 'react-icons/ai'
-import { BiBarcode, BiCheckboxChecked, BiColorFill, BiCurrentLocation, BiEdit, BiHeading, BiStopwatch, BiTime } from 'react-icons/bi'
-import { BsBodyText, BsCalendarDate, BsFileEarmarkImage, BsFiletypeMdx, BsLink45Deg, BsMenuButton, BsPercent } from 'react-icons/bs'
-import { TbTxt } from 'react-icons/tb'
-import { HiOutlineLightBulb } from 'react-icons/hi'
-import { TiSortNumerically } from 'react-icons/ti'
-import { MdOutlineFunctions, MdOutlineNumbers } from 'react-icons/md'
-import { FaIcons } from 'react-icons/fa'
-import { VscJson } from 'react-icons/vsc'
-import { RiLockPasswordLine } from 'react-icons/ri'
-import { CiRead } from 'react-icons/ci'
-import { IoIosArrowDropdown } from 'react-icons/io'
-import { PiSignatureLight } from 'react-icons/pi'
-import { LuText } from 'react-icons/lu'
+import { ArrowUp01, Barcode, Calendar, CalendarClock, Check, Clock3, Code, FileCode, FileDigit, FileJson, Grid3x3, Heading, Heading1, Image, IndianRupee, LetterText, Lightbulb, Link, Link2, MapPinned, Menu, MousePointer2, PaintBucket, Paperclip, Parentheses, Pencil, PenOff, Percent, Phone, RectangleEllipsis, ScrollText, Signature, SquareStack, Star, Table, Timer, TypeOutline } from 'lucide-react'
export type ICON_KEY = 'Autocomplete' | 'Attach' | 'Attach Image' | 'Barcode' | 'Button' | 'Check' | 'Code' | 'Color' | 'Currency' | 'Data' | 'Date' | 'Datetime' | 'Duration' | 'Dynamic Link' | 'Float' | 'Fold' | 'Geolocation' | 'Heading' | 'HTML' | 'HTML Editor' | 'Icon' | 'Image' | 'Int' | 'JSON' | 'Link' | 'Long Text' | 'Markdown Editor' | 'Password' | 'Percent' | 'Phone' | 'Read Only' | 'Rating' | 'Select' | 'Signature' | 'Small Text' | 'Table' | 'Table MultiSelect' | 'Text' | 'Text Editor' | 'Time'
-export const ICON_KEY_MAP: Record = {
- 'Autocomplete': HiOutlineLightBulb as IconType,
- 'Attach': GrFormAttachment as IconType,
- 'Attach Image': AiFillFileImage as IconType,
- 'Barcode': BiBarcode as IconType,
- 'Button': BsMenuButton as IconType,
- 'Check': BiCheckboxChecked as IconType,
- 'Code': AiFillCode as IconType,
- 'Color': BiColorFill as IconType,
- 'Currency': GrCurrency as IconType,
- 'Data': TbTxt as IconType,
- 'Date': BsCalendarDate as IconType,
- 'Datetime': BsCalendarDate as IconType,
- 'Duration': BiStopwatch as IconType,
- 'Dynamic Link': BsLink45Deg as IconType,
- 'Float': TiSortNumerically as IconType,
- 'Fold': MdOutlineFunctions as IconType,
- 'Geolocation': BiCurrentLocation as IconType,
- 'Heading': BiHeading as IconType,
- 'HTML': AiOutlineHtml5 as IconType,
- 'HTML Editor': AiFillHtml5 as IconType,
- 'Icon': FaIcons as IconType,
- 'Image': BsFileEarmarkImage as IconType,
- 'Int': MdOutlineNumbers as IconType,
- 'JSON': VscJson as IconType,
- 'Link': AiOutlineLink as IconType,
- 'Long Text': BsBodyText as IconType,
- 'Markdown Editor': BsFiletypeMdx as IconType,
- 'Password': RiLockPasswordLine as IconType,
- 'Percent': BsPercent as IconType,
- 'Phone': AiOutlinePhone as IconType,
- 'Read Only': CiRead as IconType,
- 'Rating': AiOutlineStar as IconType,
- 'Select': IoIosArrowDropdown as IconType,
- 'Signature': PiSignatureLight as IconType,
- 'Small Text': LuText as IconType,
- 'Table': AiOutlineTable as IconType,
- 'Table MultiSelect': AiOutlineTable as IconType,
- 'Text': GrTextAlignFull as IconType,
- 'Text Editor': BiEdit as IconType,
- 'Time': BiTime as IconType,
+export const ICON_KEY_MAP: Record = {
+ 'Autocomplete': Lightbulb as any,
+ 'Attach': Paperclip as any,
+ 'Attach Image': Image as any,
+ 'Barcode': Barcode as any,
+ 'Button': Menu as any,
+ 'Check': Check as any,
+ 'Code': Code as any,
+ 'Color': PaintBucket as any,
+ 'Currency': IndianRupee as any,
+ 'Data': TypeOutline as any,
+ 'Date': Calendar as any,
+ 'Datetime': CalendarClock as any,
+ 'Duration': Timer as any,
+ 'Dynamic Link': Link as any,
+ 'Float': ArrowUp01 as any,
+ 'Fold': Parentheses as any,
+ 'Geolocation': MapPinned as any,
+ 'Heading': Heading1 as any,
+ 'HTML': Heading as any,
+ 'HTML Editor': FileCode as any,
+ 'Icon': SquareStack as any,
+ 'Image': Image as any,
+ 'Int': FileDigit as any,
+ 'JSON': FileJson as any,
+ 'Link': Link2 as any,
+ 'Long Text': ScrollText as any,
+ 'Markdown Editor': Heading1 as any,
+ 'Password': RectangleEllipsis as any,
+ 'Percent': Percent as any,
+ 'Phone': Phone as any,
+ 'Read Only': PenOff as any,
+ 'Rating': Star as any,
+ 'Select': MousePointer2 as any,
+ 'Signature': Signature as any,
+ 'Small Text': LetterText as any,
+ 'Table': Table as any,
+ 'Table MultiSelect': Grid3x3 as any,
+ 'Text': LetterText as any,
+ 'Text Editor': Pencil as any,
+ 'Time': Clock3 as any,
}
diff --git a/dashboard/src/components/common/ImageUploader2/FileDrop.tsx b/dashboard/src/components/common/ImageUploader2/FileDrop.tsx
index 4683ac7..018942a 100644
--- a/dashboard/src/components/common/ImageUploader2/FileDrop.tsx
+++ b/dashboard/src/components/common/ImageUploader2/FileDrop.tsx
@@ -1,12 +1,9 @@
import { Accept, useDropzone } from "react-dropzone"
-import { MdOutlineDevices } from "react-icons/md"
import { useEffect, useState } from "react"
import { CustomFile } from "./ImageUploader"
import { useToast } from "@/components/ui/use-toast"
import { Button } from "@/components/ui/button"
-import { TbTrash } from "react-icons/tb"
-import { FiFile, FiLink } from 'react-icons/fi'
-import { IoMdCheckmark } from "react-icons/io"
+import { Check, MonitorSmartphone, Trash2, File as LucidFile, Link } from "lucide-react"
export interface FileDropProps extends React.HTMLAttributes {
@@ -87,7 +84,7 @@ export const FileDrop = ({ files, onFileChange, maxFiles = 1, uploading, accept,
Drag 'n' drop your files here.
@@ -128,7 +125,7 @@ export const FileListItem = ({ file, removeFile, isUploading, ...props }: FileLi
{previewURL ? (

) : (
- file.fileType === 'file' ?
:
+ file.fileType === 'file' ?
:
)}
@@ -140,10 +137,10 @@ export const FileListItem = ({ file, removeFile, isUploading, ...props }: FileLi
{isUploading ? (
-
+
) : (
)}
diff --git a/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx b/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx
index e49d7d3..0fbed14 100644
--- a/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx
+++ b/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx
@@ -1,6 +1,5 @@
import { useFrappeUpdateDoc } from "frappe-react-sdk"
import { Accept } from "react-dropzone"
-import { MdOutlineFileUpload } from 'react-icons/md'
import { useState } from "react"
import { useToast } from "@/components/ui/use-toast"
import { File } from "@/types/Core/File"
@@ -11,6 +10,7 @@ import { SpinnerLoader } from "../FullPageLoader/SpinnerLoader"
import { DocumentUploadModal } from "./DocumentUploadModal"
import { cn } from "@/lib/utils"
import { useGetFilePreviewUrl } from "./FileDrop"
+import { Upload } from "lucide-react"
/**
* Custom File Type for FILE UPLOADER component; with 'fileID' for unique ID & 'preview' for blob URL.
@@ -136,7 +136,7 @@ export const ImageUploader = ({ file, doctype, docname, onUpdate, fieldname = 'i
: updatingDoc ?
:
- {icon ? icon : }
+ {icon ? icon : }
}
{deleteImage && }
diff --git a/dashboard/src/components/common/MarkdownRenderer/MDX.tsx b/dashboard/src/components/common/MarkdownRenderer/MDX.tsx
index 01953e7..d859546 100644
--- a/dashboard/src/components/common/MarkdownRenderer/MDX.tsx
+++ b/dashboard/src/components/common/MarkdownRenderer/MDX.tsx
@@ -13,6 +13,7 @@ import rehypeKatex from 'rehype-katex';
import rehypeSlug from 'rehype-slug';
import CustomHeading from '@/components/features/custommdxcomponent/CustomHeading';
import CustomCodeBlock from '@/components/features/custommdxcomponent/CustomCodeBlock';
+import rehypePrettyCode from "rehype-pretty-code";
// Custom components
const CustomParagraph = ({ children }: { children?: React.ReactNode }) => {
@@ -42,7 +43,7 @@ const compileMDX = async (mdxContent: string) => {
const compiled = await compile(mdxContent, {
outputFormat: 'function-body',
remarkPlugins: [remarkMdx, remarkMath, remarkBreaks, remarkGfm],
- rehypePlugins: [rehypeSlug, rehypeKatex],
+ rehypePlugins: [rehypeSlug, rehypeKatex, rehypePrettyCode],
});
return String(compiled);
};
diff --git a/dashboard/src/components/common/MarkdownRenderer/markdown.css b/dashboard/src/components/common/MarkdownRenderer/markdown.css
index d452b8d..6ceaff0 100644
--- a/dashboard/src/components/common/MarkdownRenderer/markdown.css
+++ b/dashboard/src/components/common/MarkdownRenderer/markdown.css
@@ -237,10 +237,10 @@
font-size: 1em;
}
- .markdown-body figure {
+ /* .markdown-body figure {
margin: 1em var(--base-size-40);
}
-
+ */
.markdown-body hr {
box-sizing: content-box;
overflow: hidden;
@@ -829,7 +829,7 @@
text-decoration: inherit;
}
- .markdown-body samp {
+ .markdown-body samp {
font-size: 85%;
}
@@ -838,10 +838,10 @@
}
.markdown-body pre>code {
- padding: 0;
+ padding: 4px;
margin: 0;
word-break: normal;
- white-space: pre;
+ /* white-space: pre; */
background: transparent;
border: 0;
}
@@ -870,8 +870,8 @@
.markdown-body pre tt {
display: inline;
max-width: auto;
- padding: 0;
- margin: 0;
+ padding: 2px;
+ margin: 2px;
overflow: visible;
line-height: inherit;
word-wrap: normal;
diff --git a/dashboard/src/components/common/PageNotFound/PageNotFound.tsx b/dashboard/src/components/common/PageNotFound/PageNotFound.tsx
index d126f03..2e097d5 100644
--- a/dashboard/src/components/common/PageNotFound/PageNotFound.tsx
+++ b/dashboard/src/components/common/PageNotFound/PageNotFound.tsx
@@ -1,9 +1,9 @@
import { motion } from 'framer-motion';
import { Button } from "@/components/ui/button";
-import { IoCloudOutline } from "react-icons/io5";
import { useNavigate } from 'react-router-dom';
+import { Cloud } from 'lucide-react';
-export const PageNotFound = () => {
+const PageNotFound = () => {
const navigate = useNavigate()
@@ -33,7 +33,7 @@ export const PageNotFound = () => {
transition={{ duration: 1.2, ease: 'easeInOut' }}
className="mb-10"
>
-
+
{
);
-}
\ No newline at end of file
+}
+
+export default PageNotFound;
\ No newline at end of file
diff --git a/dashboard/src/components/features/APIClient/APIClientContent.tsx b/dashboard/src/components/features/APIClient/APIClientContent.tsx
index 08c95cd..8472e78 100644
--- a/dashboard/src/components/features/APIClient/APIClientContent.tsx
+++ b/dashboard/src/components/features/APIClient/APIClientContent.tsx
@@ -6,10 +6,9 @@ import { Input } from "@/components/ui/input"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Argument } from "@/types/APIData"
import { FrappeConfig, FrappeContext } from "frappe-react-sdk"
+import { ChevronDown, Plus } from "lucide-react"
import { useCallback, useContext, useEffect, useState } from "react"
import { FormProvider, useForm } from "react-hook-form"
-import { FaCaretDown } from "react-icons/fa"
-import { IoAdd } from "react-icons/io5";
export interface APIClientContentProps {
@@ -18,7 +17,7 @@ export interface APIClientContentProps {
open: boolean
}
-export const APIClientContent = ({ endpoint, open, parameters }: APIClientContentProps) => {
+const APIClientContent = ({ endpoint, open, parameters }: APIClientContentProps) => {
const [requestType, setRequestType] = useState<"GET" | "POST">('GET')
@@ -164,7 +163,7 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten
className="rounded-r-none w-[12ch]"
>
{requestType}
-
+
@@ -196,7 +195,7 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten
className="w-[14ch]"
>
{paramsType === 'params' ? 'Params' : 'Form Data'}
-
+
@@ -256,7 +255,7 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten
+ }} variant="outline">Add Param
}
@@ -281,4 +280,6 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten
)
-}
\ No newline at end of file
+}
+
+export default APIClientContent
\ No newline at end of file
diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx
index 3245c83..49825b1 100644
--- a/dashboard/src/components/features/api_viewer/APIDetails.tsx
+++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx
@@ -6,17 +6,17 @@ import { Button } from "@/components/ui/button"
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { web_url } from "@/config/socket"
import { APIData, Argument } from "@/types/APIData"
-import { XMarkIcon } from "@heroicons/react/24/outline"
import { useFrappeGetCall } from "frappe-react-sdk"
-import { useMemo, useState } from "react"
-import { MdOutlineFileDownload } from "react-icons/md"
-import { APIDocumentationOfSiteApp } from "../documentation/APIDocumentation"
+import { lazy, Suspense, useMemo, useState } from "react"
import { Dialog } from "@/components/ui/dialog"
-import { APIClientContent } from "../APIClient/APIClientContent"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
-import { AiOutlineThunderbolt } from "react-icons/ai"
+import { Download, X, Zap } from "lucide-react"
-export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType, mutate }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string, mutate: () => void }) => {
+
+const APIDocumentationOfSiteApp = lazy(() => import('../documentation/APIDocumentation'))
+const APIClientContent = lazy(() => import('../APIClient/APIClientContent'))
+
+const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType, mutate }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string, mutate: () => void }) => {
const data = useMemo(() => {
return endpointData.find((endpoint: APIData) => endpoint.name === selectedEndpoint)
}, [endpointData, selectedEndpoint])
@@ -73,7 +73,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
>
Close panel
-
+
@@ -94,7 +94,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
size="sm"
onClick={() => setApiOpen(true)}
>
- Call API
+ Call API
@@ -139,11 +139,15 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
-
+ }>
+
+
)
@@ -236,7 +240,7 @@ export const Bruno = ({ doc }: { doc: APIData }) => {
@@ -258,4 +262,6 @@ export const Bruno = ({ doc }: { doc: APIData }) => {
)
-}
\ No newline at end of file
+}
+
+export default APIDetails
\ No newline at end of file
diff --git a/dashboard/src/components/features/api_viewer/APIList.tsx b/dashboard/src/components/features/api_viewer/APIList.tsx
index 2edab0f..17d38af 100644
--- a/dashboard/src/components/features/api_viewer/APIList.tsx
+++ b/dashboard/src/components/features/api_viewer/APIList.tsx
@@ -4,10 +4,8 @@ import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { APIData } from "@/types/APIData"
import { useEffect, useMemo, useRef, useState } from "react"
-import { AiOutlineBranches } from "react-icons/ai"
-import { GoPackage } from "react-icons/go"
import { CommandContent } from "../commands/CommandsContent"
-import { HiOutlineCommandLine } from "react-icons/hi2";
+import { Box, GitBranch, SquareTerminal } from "lucide-react"
export interface APIListProps {
apiList: APIData[]
@@ -19,7 +17,7 @@ export interface APIListProps {
listRef?: React.RefObject
}
-export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, selectedEndpoint, path_to_folder, listRef }: APIListProps) => {
+const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, selectedEndpoint, path_to_folder, listRef }: APIListProps) => {
const [searchQuery, setSearchQuery] = useState('')
const [requestTypeFilter, setRequestTypeFilter] = useState('All')
@@ -53,19 +51,19 @@ export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, s
}
)
-}
\ No newline at end of file
+}
+
+export default APIList
\ No newline at end of file
diff --git a/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx
index 20cfee9..065a030 100644
--- a/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx
+++ b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx
@@ -1,11 +1,11 @@
-import { Button } from "@/components/ui/button";
import { useToast } from "@/components/ui/use-toast";
import { CheckIcon, CopyIcon } from "@radix-ui/react-icons";
-import { useState } from "react";
+import { useRef, useState } from "react";
// Custom Code Block Component
-const CustomCodeBlock = ({ children }: { children: React.ReactNode }) => {
+const CustomCodeBlock = ({ children, ...props }: { children: React.ReactNode, props?: any }) => {
const [isCopied, setIsCopied] = useState(false);
+ const preRef = useRef(null);
const { toast } = useToast()
@@ -24,14 +24,9 @@ const CustomCodeBlock = ({ children }: { children: React.ReactNode }) => {
return (
-
-
- {children}
-
-
+
+ {children}
+
);
};
diff --git a/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx
index 15a5490..82e3f66 100644
--- a/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx
+++ b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx
@@ -1,6 +1,6 @@
import { Button } from "@/components/ui/button";
+import { Link2 } from "lucide-react";
import React, { useEffect, useRef } from "react";
-import { MdLink } from "react-icons/md";
const CustomHeading = ({ id, children, as }: { id: string, children: React.ReactNode, as: string }) => {
const headingRef = useRef(null);
@@ -50,9 +50,9 @@ const CustomHeading = ({ id, children, as }: { id: string, children: React.React
-
+
diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx
index b2e592e..a5bdf76 100644
--- a/dashboard/src/components/features/documentation/APIDocumentation.tsx
+++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx
@@ -4,14 +4,9 @@ import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { APIData } from "@/types/APIData";
import { FrappeConfig, FrappeContext, useFrappePostCall } from "frappe-react-sdk";
-import { useCallback, useContext, useEffect, useMemo, useState } from "react";
-import { MdOutlineRocketLaunch } from "react-icons/md";
-import MDEditor from '@uiw/react-md-editor';
-import { FiEdit, FiExternalLink, FiSave } from "react-icons/fi";
+import { lazy, Suspense, useCallback, useContext, useEffect, useMemo, useState } from "react";
import { isSystemManager } from "@/utils/roles";
-import { IoMdClose } from "react-icons/io";
import { convertFrappeTimestampToTimeAgo } from "@/components/utils/dateconversion";
-import { AiOutlineGlobal } from "react-icons/ai";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { useToast } from "@/components/ui/use-toast";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
@@ -20,13 +15,16 @@ import { Input } from "@/components/ui/input";
import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown";
import { Check } from "@/components/common/Checkbox/Check";
import { FormCreatableSelect } from "@/components/common/Checkbox/CreatableSelect";
+import { ExternalLink, Globe, Rocket, Save, SquarePen, X } from "lucide-react";
+
+const MDEditor = lazy(() => import('@uiw/react-md-editor'));
export interface DocumentationResponse {
function_name: string,
path: string,
documentation: string
}
-export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint, viewerType, mutate }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string, viewerType: string, mutate: () => void }) => {
+const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint, viewerType, mutate }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string, viewerType: string, mutate: () => void }) => {
const renderContent = () => {
// return string by type checking
@@ -101,17 +99,19 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path,
{isCreateAccess && }
: (isCreateAccess && )}
- onDocumentationChange(value ?? '')}
- style={{
- minHeight: (apiData?.last_updated || isCreateAccess) ? 'calc(100vh - 22rem)' : 'calc(100vh - 19rem)',
- overflowY: 'auto', margin: 8, padding: 4
- }}
- />
+ }>
+ onDocumentationChange(value ?? '')}
+ style={{
+ minHeight: (apiData?.last_updated || isCreateAccess) ? 'calc(100vh - 22rem)' : 'calc(100vh - 19rem)',
+ overflowY: 'auto', margin: 8, padding: 4
+ }}
+ />
+