From 2865d8c84e5639144f083c19b4d13e257a6a0781 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 2 Aug 2024 16:06:02 +0530 Subject: [PATCH 1/8] refactor: Update UI layout and styling in ERDDoctypeAndAppModal, YourAppAPIExplorer, APIExplorer, YourApps, and ProjectCard components --- .../features/meta_apps/YourAppAPIExplorer.tsx | 10 +++++----- .../src/components/features/projects/APIExplorer.tsx | 10 +++++----- .../components/features/projects/ViewERDAppDialog.tsx | 10 ++++++---- .../pages/features/erd/meta/ERDDoctypeAndAppModal.tsx | 2 +- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx index 1942488..60f5a07 100644 --- a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx +++ b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx @@ -54,11 +54,11 @@ export const ViewAPIExplorerContent = ({ data }: { data: AppsData[] }) => { }, [branch, navigate]) return ( - + - Select Apps + Select App - Select the apps to view API's + Select the app to view API's setBranch(value)} className="flex flex-col space-y-1" > @@ -89,9 +89,9 @@ export const ViewAPIExplorerCard = ({ app }: ViewAPIExplorerProps) => {
  • -
    { @@ -23,7 +24,7 @@ export const ViewERDDialogContent = ({ data }: { data: ProjectData[] }) => { } return ( - + Select Apps @@ -60,8 +61,9 @@ export const ViewERDProjectCard = ({ project, apps, setApps }: ViewERDProjectCar return (
  • -
    +
    +

    {project.display_name}

    + + * + **/ +export const FormElement = ({ name, label, children, tooltip, ...props }: FormElementProps) => { + + const { errors } = useFormState() + + /** + * The name can be a path like `items.0.item_code` so we need to split it + * and then get the error message from the errors object + * */ + let error: Record = errors + const path = name.split('.') + + for (let i = 0; i < path.length; i++) { + error = error?.[path[i]] + } + + return ( + +
    + {label &&
    +
    + } + {children} + {tooltip && {tooltip}} + {error && + {error.message} + + } +
    +
    + ) +}; diff --git a/dashboard/src/components/common/Forms/FormControl/index.ts b/dashboard/src/components/common/Forms/FormControl/index.ts new file mode 100644 index 0000000..c797cde --- /dev/null +++ b/dashboard/src/components/common/Forms/FormControl/index.ts @@ -0,0 +1,2 @@ +export * from './Control' +export * from './FormElement' \ No newline at end of file diff --git a/dashboard/src/components/common/Label/Label.tsx b/dashboard/src/components/common/Label/Label.tsx new file mode 100644 index 0000000..3149d2a --- /dev/null +++ b/dashboard/src/components/common/Label/Label.tsx @@ -0,0 +1,16 @@ +import { FormLabel } from "@/components/ui/form" +import { LabelProps } from "@radix-ui/react-label" + +interface FormLabelProps extends LabelProps { + label: string +} + +export const Label = ({ label, ...props }: FormLabelProps) => { + + return ( + + {label} + + + ) +} \ No newline at end of file diff --git a/dashboard/src/components/common/Label/index.ts b/dashboard/src/components/common/Label/index.ts new file mode 100644 index 0000000..d0ac8fd --- /dev/null +++ b/dashboard/src/components/common/Label/index.ts @@ -0,0 +1 @@ +export { Label } from './Label' \ No newline at end of file From ac91f31d2726f5d5761474e92f6ffe5f06cef10a Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:36:27 +0530 Subject: [PATCH 5/8] refactor: passed open to modal for reset the form when form get open --- .../src/components/features/projects/AddMenuButton.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dashboard/src/components/features/projects/AddMenuButton.tsx b/dashboard/src/components/features/projects/AddMenuButton.tsx index 9dbd797..6e14c03 100644 --- a/dashboard/src/components/features/projects/AddMenuButton.tsx +++ b/dashboard/src/components/features/projects/AddMenuButton.tsx @@ -59,13 +59,13 @@ export const AddMenuButton = ({ mutate }: { - + - + - + ) From c5614e264b0b97c8ec112ec338caf8fe537f945d Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:37:22 +0530 Subject: [PATCH 6/8] refactor:Use of FormElement Component in this modals --- .../projects/Branch/CreateBranchModal.tsx | 66 ++++++++------- .../features/projects/Org/CreateOrgModal.tsx | 80 +++++++++++-------- .../projects/Projects/CreateProjectModal.tsx | 80 +++++++++++-------- 3 files changed, 131 insertions(+), 95 deletions(-) diff --git a/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx b/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx index 6595189..b35344a 100644 --- a/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx +++ b/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx @@ -1,15 +1,15 @@ import { DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { FormProvider, useForm, SubmitHandler } from "react-hook-form" import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" import { Button } from '@/components/ui/button' import { ProjectData } from "../Projects" import { useToast } from "@/components/ui/use-toast" import { useFrappeCreateDoc, useFrappeEventListener } from "frappe-react-sdk" import { KeyedMutator } from "swr" -import { useState } from "react" +import { useEffect, useState } from "react" import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner" import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown" +import { FormElement } from "@/components/common/Forms/FormControl" type FormFields = { project: string, @@ -21,9 +21,10 @@ export interface BranchProps { message: ProjectData[]; }> setOpen: React.Dispatch> + open: boolean } -const CreateBranchModal = ({ mutate, setOpen }: BranchProps) => { +const CreateBranchModal = ({ mutate, setOpen, open }: BranchProps) => { const [desc, setDesc] = useState() const [eventLoading, setEventLoading] = useState(false) @@ -96,39 +97,50 @@ const CreateBranchModal = ({ mutate, setOpen }: BranchProps) => { }) } + useEffect(() => { + methods.reset() + }, [open]) + return ( - Add Branch. + Add Branch {error && } {creationError && }
    - - - - - -
    -
    {desc}
    - -
    -
    +
    + + + + + + + +
    +
    {desc}
    + +
    +
    +
    diff --git a/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx b/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx index c52f348..fc51ba8 100644 --- a/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx +++ b/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx @@ -2,13 +2,14 @@ import { Button } from '@/components/ui/button' import { DialogHeader, DialogTitle, DialogContent, DialogFooter } from '@/components/ui/dialog' import { FormProvider, SubmitHandler, useForm } from 'react-hook-form' import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" import { useFrappeCreateDoc } from 'frappe-react-sdk' import { useToast } from '@/components/ui/use-toast' import { ProjectData } from '../Projects' import { KeyedMutator } from 'swr' import { ErrorBanner } from '@/components/common/ErrorBanner/ErrorBanner' import { SpinnerLoader } from '@/components/common/FullPageLoader/SpinnerLoader' +import { FormElement } from '@/components/common/Forms/FormControl' +import { useEffect } from 'react' type FormFields = { organization_name: string, @@ -19,10 +20,11 @@ type FormFields = { interface CreateOrgModalProps { mutate: KeyedMutator<{ message: ProjectData[]; }> onClose: () => void + open: boolean } -const CreateOrgModal = ({ mutate, onClose }: CreateOrgModalProps) => { +const CreateOrgModal = ({ mutate, onClose, open }: CreateOrgModalProps) => { const { toast } = useToast() const methods = useForm() @@ -40,6 +42,10 @@ const CreateOrgModal = ({ mutate, onClose }: CreateOrgModalProps) => { })) } + useEffect(() => { + methods.reset() + }, [open]) + return ( @@ -48,39 +54,43 @@ const CreateOrgModal = ({ mutate, onClose }: CreateOrgModalProps) => { {error && }
    - - - - - - - - - +
    + + + + + + + + + + + + +
    diff --git a/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx b/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx index 969e5fd..f68c9a9 100644 --- a/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx +++ b/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx @@ -2,12 +2,13 @@ import { DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/compon import { useFrappeCreateDoc } from "frappe-react-sdk" import { FormProvider, SubmitHandler, useForm } from "react-hook-form" import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" import { Button } from '@/components/ui/button' import { useToast } from "@/components/ui/use-toast" import { ProjectData } from "../Projects" import { KeyedMutator } from "swr" import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown" +import { FormElement } from "@/components/common/Forms/FormControl" +import { useEffect } from "react" export type FormFields = { org: string, @@ -18,9 +19,10 @@ export type FormFields = { interface CreateProjectModalProps { mutate: KeyedMutator<{ message: ProjectData[]; }>, onClose: VoidFunction + open: boolean } -const CreateProjectModal = ({ mutate, onClose }: CreateProjectModalProps) => { +const CreateProjectModal = ({ mutate, onClose, open }: CreateProjectModalProps) => { const { toast } = useToast() const methods = useForm() @@ -40,6 +42,9 @@ const CreateProjectModal = ({ mutate, onClose }: CreateProjectModalProps) => { }) } + useEffect(() => { + methods.reset() + }, [open]) return ( @@ -48,37 +53,46 @@ const CreateProjectModal = ({ mutate, onClose }: CreateProjectModalProps) => {
    - - - - - - - - - - - +
    + + + + + + + + + + + + + + + +
    From 97b8339cbc3ec0359535539c4035904a0c139430 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:37:29 +0530 Subject: [PATCH 7/8] refactor: Update UI layout and styling in multiple components --- .../projects/Branch/ManageBranchItem.tsx | 280 ++++++++++-------- 1 file changed, 149 insertions(+), 131 deletions(-) diff --git a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx index 5f013e4..3af3949 100644 --- a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx +++ b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx @@ -1,151 +1,169 @@ -import { Button } from '@/components/ui/button' -import { toast } from '@/components/ui/use-toast' -import { convertFrappeTimestampToTimeAgo } from '@/components/utils/dateconversion' -import { CommitProjectBranch } from '@/types/commit/CommitProjectBranch' -import { useFrappeDeleteDoc, useFrappePostCall, useFrappeUpdateDoc } from 'frappe-react-sdk' -import { AiOutlineDelete } from 'react-icons/ai' -import { IoMdSync } from 'react-icons/io' -import { ProjectData } from '../Projects' -import { KeyedMutator } from 'swr' +import { Button } from '@/components/ui/button'; +import { toast } from '@/components/ui/use-toast'; +import { convertFrappeTimestampToTimeAgo } from '@/components/utils/dateconversion'; +import { CommitProjectBranch } from '@/types/commit/CommitProjectBranch'; +import { useFrappeDeleteDoc, useFrappePostCall, useFrappeUpdateDoc } from 'frappe-react-sdk'; +import { AiOutlineDelete } from 'react-icons/ai'; +import { IoMdSync } from 'react-icons/io'; +import { ProjectData } from '../Projects'; +import { KeyedMutator } from 'swr'; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { Controller, FormProvider, useForm } from 'react-hook-form' -import { Label } from '@/components/ui/label' -import { useState } from 'react' - +import { Controller, FormProvider, useForm } from 'react-hook-form'; +import { Label } from '@/components/ui/label'; +import { useState } from 'react'; const ManageBranchItem = ({ branch, mutate }: { branch: CommitProjectBranch, mutate: KeyedMutator<{ message: ProjectData[]; }> }) => { - const { call, loading, reset: callReset } = useFrappePostCall<{ message: any }>('commit.commit.doctype.commit_project_branch.commit_project_branch.fetch_repo') - + const { call, loading: syncLoading, reset: callReset } = useFrappePostCall<{ message: any }>('commit.commit.doctype.commit_project_branch.commit_project_branch.fetch_repo'); + const { deleteDoc, loading: deleteLoading, reset } = useFrappeDeleteDoc(); + const { updateDoc } = useFrappeUpdateDoc(); + const [open, setOpen] = useState(false); - const { deleteDoc, reset, loading: deleteLoading } = useFrappeDeleteDoc() + const methods = useForm({ + defaultValues: { + frequency: branch.frequency, + }, + }); const handleDelete = () => { deleteDoc("Commit Project Branch", branch.name) .then(() => { - mutate() - reset() - }).then(() => toast({ - description: "Branch Deleted Successfully", - duration: 1500 - })) - } + mutate(); + reset(); + toast({ + description: "Branch Deleted Successfully", + duration: 1500, + }); + }); + }; const handleSync = () => { - call({ - doc: {}, - name: branch.name, - }).then(() => { - mutate() - callReset() - }).then(() => toast({ - description: "Branch Synced!", - duration: 1500 - })) - } - - const methods = useForm({ - defaultValues: { - frequency : branch.frequency - } - }) - - const { control, reset: formReset } = methods - - const { updateDoc } = useFrappeUpdateDoc() + call({ doc: {}, name: branch.name }) + .then(() => { + mutate(); + callReset(); + toast({ + description: "Branch Synced!", + duration: 1500, + }); + }); + }; const onSubmit = (data: CommitProjectBranch) => { updateDoc("Commit Project Branch", branch.name, data) .then(() => { - mutate() - formReset({ frequency: data.frequency }) - }).then(() => { + mutate(); + methods.reset({ frequency: data.frequency }); toast({ description: `Branch ${branch.branch_name} will be updated ${data.frequency}`, - duration: 2000 - }) - setOpen(false) - } - ) - - } - - - const [open, setOpen] = useState(false); + duration: 2000, + }); + setOpen(false); + }); + }; return ( -
  • -
    - {branch.branch_name} -
    - Last synced {convertFrappeTimestampToTimeAgo(branch.last_fetched)} -
    -
    -
    - - - - - - - -
    -
    - - ( - - )} - /> -
    -
    - -
    -
    -
    -
    -
    - +
  • + +
    + + +
    -
  • - ) -} - -export default ManageBranchItem - - + + ); +}; + +const BranchInfo = ({ branch }: { branch: CommitProjectBranch }) => ( +
    + {branch.branch_name} + Last synced {convertFrappeTimestampToTimeAgo(branch.last_fetched)} +
    +); + +const SyncButton = ({ loading, onSync }: { loading: boolean, onSync: () => void }) => ( + +); + +const FrequencyPopover = ({ open, setOpen, methods, onSubmit, control, frequency }: { + open: boolean, + setOpen: (open: boolean) => void, + methods: any, + onSubmit: any, + control: any, + frequency: string | undefined +}) => ( + + + + + + +
    +
    + + ( + + )} + /> +
    +
    + +
    +
    +
    +
    +
    +); + +const DeleteButton = ({ loading, onDelete }: { loading: boolean, onDelete: () => void }) => ( + +); + +export default ManageBranchItem; From 2a107107de5a096861d2f0f08ab15842a1b7a5fb Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:37:53 +0530 Subject: [PATCH 8/8] refactor:Make pages responsive and svg file added --- dashboard/src/assets/api.svg | 1 + dashboard/src/assets/erd.svg | 341 ++++++++++++++++++ .../features/meta_apps/YourAppAPIExplorer.tsx | 43 ++- .../features/meta_apps/YourApps.tsx | 78 ++-- .../features/projects/APIExplorer.tsx | 31 +- .../components/features/projects/Projects.tsx | 53 ++- .../projects/Projects/ProjectCard.tsx | 99 +++-- .../features/projects/ViewERDButton.tsx | 81 +++++ 8 files changed, 587 insertions(+), 140 deletions(-) create mode 100644 dashboard/src/assets/api.svg create mode 100644 dashboard/src/assets/erd.svg create mode 100644 dashboard/src/components/features/projects/ViewERDButton.tsx diff --git a/dashboard/src/assets/api.svg b/dashboard/src/assets/api.svg new file mode 100644 index 0000000..17728fa --- /dev/null +++ b/dashboard/src/assets/api.svg @@ -0,0 +1 @@ + diff --git a/dashboard/src/assets/erd.svg b/dashboard/src/assets/erd.svg new file mode 100644 index 0000000..6461be4 --- /dev/null +++ b/dashboard/src/assets/erd.svg @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx index 60f5a07..f6d355e 100644 --- a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx +++ b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx @@ -4,11 +4,13 @@ import { useNavigate } from "react-router-dom" import { AppsData } from "./YourApps" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" -import { AiOutlineApi } from "react-icons/ai" import { useCallback, useState } from "react" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card" +import { MdKeyboardArrowRight } from "react-icons/md" +import api from '../../../assets/api.svg' export const YourAppAPIExplorer = () => { @@ -28,15 +30,36 @@ export const YourAppAPIExplorer = () => { if (data && data.message) { return ( - - - - - - + +
    + + Explore your API's + + +
    + Explore and interact with your site installed apps whitelisted API's effortlessly + using our API Explorer. +
    +
    + + + + + + + + + +
    +
    + API +
    +
    ) } } diff --git a/dashboard/src/components/features/meta_apps/YourApps.tsx b/dashboard/src/components/features/meta_apps/YourApps.tsx index e2bff95..9d26140 100644 --- a/dashboard/src/components/features/meta_apps/YourApps.tsx +++ b/dashboard/src/components/features/meta_apps/YourApps.tsx @@ -1,13 +1,10 @@ import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { Avatar, AvatarFallback } from "@/components/ui/avatar" -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardDescription, CardTitle } from "@/components/ui/card" import { AvatarImage } from "@radix-ui/react-avatar" import { useFrappeGetCall } from "frappe-react-sdk" import { useMemo } from "react" -import { BsDatabase } from "react-icons/bs" -import { useNavigate } from "react-router-dom" import { YourAppAPIExplorer } from "./YourAppAPIExplorer" +import { ViewERDButtonForSiteApps } from "../projects/ViewERDButton" export interface AppsData { app_name: string @@ -19,7 +16,6 @@ export interface AppsData { } export const YourApps = () => { - const navigate = useNavigate() const { data, error, isLoading } = useFrappeGetCall<{ message: AppsData[] }>('commit.api.meta_data.get_installed_apps', {}, 'get_installed_apps', { keepPreviousData: true, @@ -37,25 +33,24 @@ export const YourApps = () => { if (data && data.message) { return ( -
    -
    - -
    +
    +
    +
    + -
    -
    -
    - {data.message.map((app: AppsData) => { - return - })} +
    +
    +
    Projects
    +
    +
    + {data.message.map((org: AppsData) => { + return ( + + ) + })} +
    +
    ) @@ -64,32 +59,25 @@ export const YourApps = () => { const AppsCard = ({ app }: { app: AppsData }) => { - const appNameInitials = useMemo(() => { - return app.app_name.split('_').map((word) => word[0]).join('').toUpperCase() - }, [app]) + return app.app_name.split('_').map((word) => word[0]).join('').toUpperCase(); + }, [app]); return ( - - -
    - - - {appNameInitials} +
    +
    + + + {appNameInitials} -
    -
    -
    - {app.app_name} -
    - {app.app_publisher} +
    +
    {app.app_name}
    +
    + {app.app_description}
    +
    {app.app_publisher}
    - - {app.app_description} - -
    - - - ) -} \ No newline at end of file +
    +
    + ); +}; \ No newline at end of file diff --git a/dashboard/src/components/features/projects/APIExplorer.tsx b/dashboard/src/components/features/projects/APIExplorer.tsx index 4a24615..85bda45 100644 --- a/dashboard/src/components/features/projects/APIExplorer.tsx +++ b/dashboard/src/components/features/projects/APIExplorer.tsx @@ -3,13 +3,15 @@ import { Button } from "@/components/ui/button" import { useFrappeGetCall } from "frappe-react-sdk" import { ProjectData, ProjectWithBranch } from "./Projects" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" -import { AiOutlineApi } from "react-icons/ai" import { useCallback, useState } from "react" import { useNavigate } from "react-router-dom" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { CommitProjectBranch } from "@/types/commit/CommitProjectBranch" import { Label } from "@/components/ui/label" +import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card" +import { MdKeyboardArrowRight } from "react-icons/md" +import api from '../../../assets/api.svg' export const APIExplorer = () => { const { data, error, isLoading } = useFrappeGetCall<{ message: ProjectData[] }>('commit.api.commit_project.commit_project.get_project_list_with_branches', {}, 'get_project_list_with_branches', { @@ -28,15 +30,36 @@ export const APIExplorer = () => { if (data && data.message) { return ( + +
    + + Explore your API's + + +
    + Explore and interact with your whitelisted API's effortlessly + using our API Explorer. +
    +
    + + - + +
    +
    + API +
    +
    ) } return null diff --git a/dashboard/src/components/features/projects/Projects.tsx b/dashboard/src/components/features/projects/Projects.tsx index 97e78e9..78f8df6 100644 --- a/dashboard/src/components/features/projects/Projects.tsx +++ b/dashboard/src/components/features/projects/Projects.tsx @@ -1,15 +1,12 @@ import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; -import { Button } from "@/components/ui/button"; -import { Dialog, DialogTrigger } from "@/components/ui/dialog"; import { CommitProject } from "@/types/commit/CommitProject"; import { useFrappeGetCall } from "frappe-react-sdk"; -import { BsDatabase } from "react-icons/bs"; -import { ViewERDDialogContent } from "./ViewERDAppDialog"; import { isSystemManager } from "@/utils/roles"; import { CommitProjectBranch } from "@/types/commit/CommitProjectBranch"; import { AddMenuButton } from "./AddMenuButton"; import { APIExplorer } from "./APIExplorer"; import ProjectCard from "./Projects/ProjectCard"; +import { ViewERDButton } from "./ViewERDButton"; export interface ProjectWithBranch extends CommitProject { @@ -18,6 +15,7 @@ export interface ProjectWithBranch extends CommitProject { export interface ProjectData extends CommitProjectBranch { projects: ProjectWithBranch[]; organization_name: string; + github_org: string; image: string; name: string; about: string; @@ -48,32 +46,31 @@ export const Projects = () => { if (data && data.message) { return ( -
    -
    -
    - {isCreateAccess && } +
    +
    +
    + - - - - - -
    -
    - {data.message.map((org: ProjectData) => { - const orgName = org.organization_name; - return org.projects.map((project) => ( - - )); - })} +
    +
    +
    Projects
    + {isCreateAccess && } +
    +
    + {data.message.map((org: ProjectData) => { + const orgName = org.organization_name; + return org.projects.map((project) => ( + + )); + })} +
    diff --git a/dashboard/src/components/features/projects/Projects/ProjectCard.tsx b/dashboard/src/components/features/projects/Projects/ProjectCard.tsx index 7b1bb4d..f342f5b 100644 --- a/dashboard/src/components/features/projects/Projects/ProjectCard.tsx +++ b/dashboard/src/components/features/projects/Projects/ProjectCard.tsx @@ -1,10 +1,4 @@ import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardTitle, -} from "@/components/ui/card"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { AiOutlineDelete } from "react-icons/ai"; import { AlertDialog } from "@/components/ui/alert-dialog"; @@ -25,9 +19,10 @@ export interface ProjectCardProps { message: ProjectData[]; }> orgName: string + githubOrg: string } -const ProjectCard = ({ project, mutate, orgName }: ProjectCardProps) => { +const ProjectCard = ({ project, mutate, orgName, githubOrg }: ProjectCardProps) => { const appNameInitials = useMemo(() => { return project.display_name[0].toUpperCase() @@ -39,54 +34,52 @@ const ProjectCard = ({ project, mutate, orgName }: ProjectCardProps) => { const [openDeleteDialogModal, setOpenDeleteDialogModal] = useState(false) - return ( - - -
    -
    - - - - {appNameInitials} - - -
    -
    -
    -
    - {project.display_name} -
    - {orgName} -
    -
    - {isCreateAccess && - - - - - {project.branches.length > 0 && - { setOpenManageModal(true) }}> - <> - - Manage Branches - - - } - setOpenDeleteDialogModal(true)}> - - Delete Project - + const openGithubRepo = () => { + window.open(`https://github.com/${githubOrg}/${project.repo_name}`, '_blank') + } - - } -
    - - - {project.description} - + return ( +
    +
    + + + + {appNameInitials} + + +
    +
    {project.display_name}
    +
    + {project.description}
    +
    {orgName}
    - +
    +
    + {isCreateAccess && ( + + + + + + {project.branches.length > 0 && ( + { setOpenManageModal(true) }}> + <> + + Manage Branches + + + )} + setOpenDeleteDialogModal(true)}> + + Delete Project + + + + )} +
    @@ -95,7 +88,7 @@ const ProjectCard = ({ project, mutate, orgName }: ProjectCardProps) => { - +
    ); } diff --git a/dashboard/src/components/features/projects/ViewERDButton.tsx b/dashboard/src/components/features/projects/ViewERDButton.tsx new file mode 100644 index 0000000..482b710 --- /dev/null +++ b/dashboard/src/components/features/projects/ViewERDButton.tsx @@ -0,0 +1,81 @@ +import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card"; +import { Dialog, DialogTrigger } from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { ViewERDDialogContent } from "./ViewERDAppDialog"; +import { ProjectData } from "./Projects"; +import { MdKeyboardArrowRight } from "react-icons/md"; +import { useNavigate } from "react-router-dom"; +import erd from '../../../assets/erd.svg' + +export const ViewERDButton = ({ data }: { data: ProjectData[] }) => { + return ( + +
    + + Visualize your database + + +
    Analyze and understand the relationships between your doctypes with an interactive Entity Relationship Diagram (ERD).
    +
    + + + + + + + + +
    +
    + ERD Diagram +
    +
    + ); +}; + +export const ViewERDButtonForSiteApps = () => { + + const navigate = useNavigate() + + return ( + +
    + + Visualize your site database + + +
    Analyze and understand the relationships between your doctypes with an interactive Entity Relationship Diagram (ERD).
    +
    + + + +
    +
    + ERD Diagram +
    +
    + ); +} \ No newline at end of file