Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions commit/api/api_explorer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import frappe
import json
import os
from commit.commit.code_analysis.apis import find_all_occurrences_of_whitelist


@frappe.whitelist(allow_guest=True)
Expand Down Expand Up @@ -29,13 +30,20 @@ def get_apis_for_project(project_branch: str):


@frappe.whitelist(allow_guest=True)
def get_file_content_from_path(project_branch: str, file_path: str,block_start: int, block_end: int):
def get_file_content_from_path(project_branch: str, file_path: str,block_start: int, block_end: int,viewer_type: str):
'''
Gets the Project Branch document with the organization and app name
'''
branch_doc = frappe.get_doc("Commit Project Branch", project_branch)
if viewer_type == "project":
branch_doc = frappe.get_doc("Commit Project Branch", project_branch)

api_data = json.loads(branch_doc.whitelisted_apis)['apis']
else:
app_path = frappe.get_app_path(project_branch)

api_data = json.loads(branch_doc.whitelisted_apis)['apis']
# remove last part of the path which is the app name
app_path = app_path.rsplit('/', 1)[0]
api_data = find_all_occurrences_of_whitelist(app_path,project_branch)

found = False

Expand Down
22 changes: 15 additions & 7 deletions commit/api/erd_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,28 @@ def get_erd_schema_for_module(project_branch: str, module: str):


@frappe.whitelist(allow_guest=True)
def get_erd_schema_for_doctypes(project_branch: str, doctypes):
def get_erd_schema_for_doctypes(project_branch: list, doctypes):
doctypes = json.loads(doctypes)
branch_doctypes = {}
doctype_list = []
for doctype in doctypes:
if doctype['project_branch'] not in branch_doctypes:
branch_doctypes[doctype['project_branch']] = []
branch_doctypes[doctype['project_branch']].append(doctype['doctype'])
doctype_list.append(doctype['doctype'])

doctype_jsons = []
project_branch = frappe.get_cached_doc(
"Commit Project Branch", project_branch)
for project_branch, doctypes in branch_doctypes.items():
project_branch_doc = frappe.get_cached_doc(
"Commit Project Branch", project_branch)

for doctype in doctypes:
doctype_json = project_branch.get_doctype_json(doctype)
doctype_jsons.append(doctype_json)
for doctype in doctypes:
doctype_json = project_branch_doc.get_doctype_json(doctype)
doctype_jsons.append(doctype_json)

schema = get_schema_from_doctypes_json({
'doctypes': doctype_jsons,
'doctype_names': doctypes
'doctype_names': doctype_list
})

return schema
63 changes: 63 additions & 0 deletions commit/api/meta_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import frappe
from commit.commit.code_analysis.apis import find_all_occurrences_of_whitelist

@frappe.whitelist()
def get_installed_apps():
install_app_doc = frappe.get_cached_doc('Installed Applications')
install_apps = install_app_doc.get('installed_applications')
updated_apps = []
for app in install_apps:
app_name = app.get('app_name')
app_hooks = frappe.get_hooks(app_name=app_name)

app_description = app_hooks.get('app_description')
if app_description is not None:
app_description = app_description[0]

app_publisher = app_hooks.get('app_publisher')
if app_publisher is not None:
app_publisher = app_publisher[0]

app_logo_url = app_hooks.get('app_logo_url')
if app_logo_url is not None:
app_logo_url = app_logo_url[0]

app_version = app.get('app_version')

git_branch = app.get('git_branch')

updated_app = {
'app_name': app_name,
'app_publisher': app_publisher,
'app_description': app_description,
'app_logo_url': app_logo_url,
'app_version': app_version,
'git_branch': git_branch
}
updated_apps.append(updated_app)

return updated_apps

@frappe.whitelist()
def get_apis_for_app(app_name: str):
'''
Gets the Project Branch document with the organization and app name
'''
app_path = frappe.get_app_path(app_name)

# remove last part of the path which is the app name
app_path = app_path.rsplit('/', 1)[0]
apis = find_all_occurrences_of_whitelist(app_path,app_name)

app_hooks = frappe.get_hooks(app_name=app_name)

install_app_doc = frappe.get_cached_doc('Installed Applications')
install_apps = install_app_doc.get('installed_applications')
app = [app for app in install_apps if app.get('app_name') == app_name][0]

branch_name = app.get('git_branch')
return {
"apis": apis,
"app_name": app_name,
"branch_name": branch_name,
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,12 @@ def fetch_repo(doc):
project_branch.fetch_repo()
project_branch.save()
return "Hello"

@frappe.whitelist(allow_guest=True)
def get_module_doctype_map_for_branches(branches: str):
branches = json.loads(branches)
module_doctypes_map = {}
for branch in branches:
project_branch = frappe.get_doc("Commit Project Branch", branch)
module_doctypes_map[branch] = json.loads(project_branch.module_doctypes_map)
return module_doctypes_map
4 changes: 2 additions & 2 deletions commit/public/dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<title>Commit - Developer tooling for the Frappeverse</title>
<script type="module" crossorigin src="/assets/commit/dashboard/assets/index-c4bd59c7.js"></script>
<link rel="stylesheet" href="/assets/commit/dashboard/assets/index-871f3ee2.css">
<script type="module" crossorigin src="/assets/commit/dashboard/assets/index-256ccba7.js"></script>
<link rel="stylesheet" href="/assets/commit/dashboard/assets/index-901a955f.css">
</head>

<body>
Expand Down
4 changes: 2 additions & 2 deletions commit/www/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<title>Commit - Developer tooling for the Frappeverse</title>
<script type="module" crossorigin src="/assets/commit/dashboard/assets/index-c4bd59c7.js"></script>
<link rel="stylesheet" href="/assets/commit/dashboard/assets/index-871f3ee2.css">
<script type="module" crossorigin src="/assets/commit/dashboard/assets/index-256ccba7.js"></script>
<link rel="stylesheet" href="/assets/commit/dashboard/assets/index-901a955f.css">
</head>

<body>
Expand Down
1 change: 1 addition & 0 deletions dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"reactflow": "^11.7.4",
"rehype-raw": "^7.0.0",
"remark-gfm": "^3.0.1",
"shadcn-ui": "^0.8.0",
"socket.io-client": "^4.5.1",
"swr": "^2.1.5",
"tailwind-merge": "^1.13.2",
Expand Down
9 changes: 6 additions & 3 deletions dashboard/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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'

function App() {

Expand All @@ -17,10 +18,12 @@ function App() {
{/** Private Routes */}
{/* <Route path="/" element={<ProtectedRoute />} /> */}
{/* default route on '/' */}
<Route path="/" element={<Overview />} />
<Route path="/" index element={<Overview />} />
{/*TODO: Need to Change below route */}
<Route path='erd/:ID' element={<ERDViewer />} />
<Route path="/viewer/:ID" element={<APIViewerContainer />} />
<Route path='/project-erd' element={<ERDViewer />} />
<Route path="/project-viewer/:ID" element={<APIViewerContainer />} />
<Route path="/meta-viewer/:ID" element={<AppAPIViewerContainer />} />
<Route path='/meta-erd/:ID' element={<ERDViewer />} />
</Routes>
{/* </UserProvider> */}
</BrowserRouter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export const ErrorBanner = ({ error, overrideHeading, ...props }: ErrorBannerPro
// exc: With entire traceback - useful for reporting maybe
// httpStatus and httpStatusText - not needed
// _server_messages: Array of messages - useful for showing to user
// console.log(JSON.parse(error?._server_messages!))

const messages = useMemo(() => {
if (!error) return []
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import React from "react"
import React from 'react';


export const FullPageLoader = ({ className = '', ...props }: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => {

return (
<div className={`flex items-center justify-center h-full ${className}`} {...props}>
<div
className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status">
<span
className="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
>Loading...</span
>
</div>
</div>
)
}
export const FullPageLoader = ({
className = '',
...props
}: React.DetailedHTMLProps<
React.HTMLAttributes<HTMLDivElement>,
HTMLDivElement
>) => {
return (
<div
className={`flex items-center justify-center h-full ${className}`}
{...props}
>
<div
className='inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]'
role='status'
>
<span className='!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]'>
Loading...
</span>
</div>
</div>
);
};
41 changes: 12 additions & 29 deletions dashboard/src/components/features/api_viewer/APIDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import CopyButton from "@/components/common/CopyToClipboard/CopyToClipboard"
import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"
import { FullPageLoader } from "@/components/common/FullPageLoader.tsx/FullPageLoader"
import { Tabs } from "@/components/common/Tabs"
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { APIData, Argument } from "@/types/APIData"
import { XMarkIcon } from "@heroicons/react/24/outline"
import { useFrappeGetCall } from "frappe-react-sdk"
import { useMemo } from "react"

export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch<React.SetStateAction<string>> }) => {
export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch<React.SetStateAction<string>>, viewerType: string }) => {

const data = useMemo(() => {
return endpointData.find((endpoint: APIData) => endpoint.name === selectedEndpoint)
}, [endpointData, selectedEndpoint])

const tabs = [
{ name: 'Parameters', content: <ParametersTable parameters={data?.arguments} /> },
{ name: 'Code', content: <CodeSnippet apiData={data!} project_branch={project_branch} file_path={data?.file ?? ''} /> },
{ name: 'Code', content: <CodeSnippet apiData={data!} project_branch={project_branch} file_path={data?.file ?? ''} viewerType={viewerType} /> },
]

const requestTypeBgColor = (requestType: string) => {
Expand Down Expand Up @@ -144,43 +145,25 @@ export const ParametersTable = ({ parameters }: { parameters?: Argument[] }) =>
}


export const CodeSnippet = ({ apiData, project_branch, file_path }: { apiData: APIData, project_branch: string, file_path: string }) => {
export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: { apiData: APIData, project_branch: string, file_path: string, viewerType: string }) => {

const { data, error } = useFrappeGetCall<{ message: { file_content: string } }>('commit.api.api_explorer.get_file_content_from_path', {
const { data, error, isLoading } = useFrappeGetCall<{ message: { file_content: string } }>('commit.api.api_explorer.get_file_content_from_path', {
project_branch: project_branch,
file_path: file_path,
block_start: apiData.block_start ?? 0,
block_end: apiData.block_end ?? 0,
viewer_type: viewerType
})

return (
<div className="flex flex-col space-y-2">
{error && <ErrorBanner error={error} />}
{/* <code className="bg-gray-50 p-4 rounded-md text-sm overflow-auto border-2 border-gray-200 h-[calc(100vh-16rem)]">
<pre className="counter-reset" data-prefix={data?.message?.file_content.split('\n').length}>
{data?.message?.file_content.split('\n').map((line, idx) => (
<span key={idx} className="block" data-line-number={idx + 1}>{line}</span>
))}
</pre>
</code> */}
{/* hightlight with light yellow colour those lines which start from the def_index until next @frappe.whitelist occurs */}
<code className="bg-gray-50 p-4 rounded-md text-sm overflow-auto border-2 border-gray-200 h-[calc(100vh-16rem)]">
<pre className="counter-reset">
{/* {data?.message?.file_content.split('\n').map((line, idx) => {
// console.log(idx)
console.log(apiData.def_index)
if (idx === apiData.def_index) {
console.log(line)
if (line.startsWith('@frappe.whitelist')) {
return <span key={idx} className="block" data-line-number={idx + 1}>{line}</span>
}
return <span key={idx} className="block bg-yellow-200" data-line-number={idx + 1}>{line}</span>
}
return <span key={idx} className="block" data-line-number={idx + 1}>{line}</span>
}
)} */}
{isLoading && <div className="flex items-center justify-center h-[calc(100vh-16rem)]">
<FullPageLoader />
</div>}
<code className="bg-gray-50 p-4 rounded-md text-sm overflow-auto border-2 border-gray-200 h-[calc(100vh-22rem)]">
<pre className="counter-reset mb-2">
{isLoading && <FullPageLoader />}
{data?.message?.file_content}

</pre>
</code>
</div >
Expand Down
17 changes: 8 additions & 9 deletions dashboard/src/components/features/api_viewer/APIList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ export interface APIListProps {
apiList: APIData[]
app_name: string
branch_name: string
last_updated: string
organization_id: string
setSelectedEndpoint: (endpoint: string) => void
}

export const APIList = ({ apiList, app_name, branch_name, last_updated, organization_id, setSelectedEndpoint }: APIListProps) => {
export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint }: APIListProps) => {
const [searchQuery, setSearchQuery] = useState<string>('')
const [requestTypeFilter, setRequestTypeFilter] = useState<string>('All')

Expand All @@ -37,18 +35,13 @@ export const APIList = ({ apiList, app_name, branch_name, last_updated, organiza
<div className="flex space-x-2 items-center">
<div className="flex flex-wrap items-center space-x-1">
<GoPackage />
<p className="truncate text-md text-gray-700">{organization_id} / {app_name}</p>
<p className="truncate text-md text-gray-700">{app_name}</p>
</div>
<div className="w-px h-4 bg-gray-200" />
<div className="flex flex-wrap items-center space-x-1">
<AiOutlineBranches />
<p>{branch_name}</p>
</div>
{/* <div className="w-px h-4 bg-gray-200" />
<div className="flex flex-wrap items-center space-x-2">
<MdOutlineUpdate />
<p className="truncate text-sm text-gray-700">{last_updated.split(' ')[0]}</p><h6 className="text-gray-400 text-sm"> (<TimeAgo datetime={last_updated} />)</h6>
</div> */}
</div>
<div className="flex flex-row space-x-4">
<div className="w-4/5 flex flex-row space-x-4">
Expand Down Expand Up @@ -81,6 +74,7 @@ export const APIList = ({ apiList, app_name, branch_name, last_updated, organiza

export const ListView = ({ list, setSelectedEndpoint }: { list: APIData[], setSelectedEndpoint: (endpoint: string) => void }) => {
return (
<div>
<ul role="list" className="divide-y divide-gray-100 px-1">
{list.length === 0 && (
<div className="flex flex-col items-center justify-center h-[calc(100vh-10rem)] space-y-2" style={{ minHeight: '20rem' }} >
Expand Down Expand Up @@ -115,5 +109,10 @@ export const ListView = ({ list, setSelectedEndpoint }: { list: APIData[], setSe
</li>
))}
</ul>
{/* create a div which is at fixed location and should be stick bottom which will show total list count at right corner of same w as above ul*/}
{list.length && <div className="fixed bottom-0 flex justify-end p-2 w-[54%] bg-white h-10 border-t">
<p className="text-sm justify-end">Total {list.length} API's</p>
</div>}
</div>
)
}
Loading