-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1279 from Sinaptik-AI/feature/PAN-868
[PAN-868]: workspaces added
- Loading branch information
Showing
21 changed files
with
885 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
"use client"; | ||
import Card from "@/components/card"; | ||
import ConfirmationDialog from "@/components/ConfirmationDialog"; | ||
import { Button } from "@/components/ui/button"; | ||
import { useDeleteWorkspace } from "@/hooks/useSpaces"; | ||
import { revalidateWorkspaces } from "@/lib/actions"; | ||
import Link from "next/link"; | ||
import { useRouter } from "next/navigation"; | ||
import React, { useState } from "react"; | ||
import { toast } from "react-toastify"; | ||
|
||
interface IProps { | ||
data: any; | ||
} | ||
|
||
const WorkspaceCard = ({ data }: IProps) => { | ||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); | ||
const { isPending, mutateAsync: deleteSpace } = useDeleteWorkspace(); | ||
const router = useRouter(); | ||
|
||
const handleDeleteSpace = () => { | ||
deleteSpace( | ||
{ id: data.id }, | ||
{ | ||
onSuccess(response) { | ||
toast.success(response?.data?.message); | ||
setIsDeleteModalOpen(false); | ||
revalidateWorkspaces(); | ||
router.push("/settings/workspaces"); | ||
}, | ||
onError(error) { | ||
toast.error(error?.message); | ||
}, | ||
} | ||
); | ||
}; | ||
return ( | ||
<> | ||
<Card extra={"w-full py-4 px-6 h-full mb-4"}> | ||
<div className="flex flex-col justify-between min-h-[300px]"> | ||
<div> | ||
<h3 className="font-bold text-[20px] mb-1">{data?.name}</h3> | ||
<h3 className="font-bold text-sm mb-1"> | ||
<span className="font-normal"> | ||
{`This is the workspace dedicated to the ${data?.name} team.`} | ||
</span> | ||
</h3> | ||
</div> | ||
<div className="flex justify-start gap-4 items-center flex-wrap"> | ||
<Link href={`/settings/workspaces/editspaces?id=${data?.id}`}> | ||
<Button>Edit</Button> | ||
</Link> | ||
|
||
<div | ||
onClick={() => { | ||
setIsDeleteModalOpen(true); | ||
}} | ||
className={`px-8 py-1 rounded-[10px] flex flex-wrap items-center justify-center cursor-pointer dark:bg-[#D30000] neon-on-hovers`} | ||
> | ||
<span className="font-bold text-white">Delete</span> | ||
</div> | ||
</div> | ||
</div> | ||
</Card> | ||
{isDeleteModalOpen && ( | ||
<ConfirmationDialog | ||
text={`Are you sure you want to delete this Workspace?`} | ||
onCancel={() => { | ||
setIsDeleteModalOpen(false); | ||
}} | ||
onSubmit={handleDeleteSpace} | ||
isLoading={isPending} | ||
/> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
export default WorkspaceCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import React from "react"; | ||
import Card from "components/card"; | ||
|
||
import { GetWorkspaceDetails } from "@/services/spaces"; | ||
import Link from "next/link"; | ||
import { Button } from "@/components/ui/button"; | ||
import AddNewCard from "../../datasets/AddNewCard"; | ||
import { FaFileCsv } from "react-icons/fa"; | ||
import WorkspaceCard from "./WorkspaceCard"; | ||
|
||
interface PageProps { | ||
params: { | ||
id: string; | ||
}; | ||
} | ||
|
||
export default async function WorkSpacesDetails({ params }: PageProps) { | ||
const data = await GetWorkspaceDetails(params.id); | ||
|
||
return ( | ||
<div className="w-full h-full overflow-y-auto custom-scroll mt-5 px-2 md:px-4"> | ||
<h1 className="text-2xl font-bold dark:text-white mb-10"> | ||
<Link href="/settings/workspaces">Workspaces</Link> | ||
<small>{data?.name && ` › ${data?.name}`}</small> | ||
</h1> | ||
|
||
<div className="flex flex-col p-2 md:p-4 font-montserrat"> | ||
<div className="flex items-center md:flex-row flex-col justify-center gap-4"> | ||
<WorkspaceCard data={data} /> | ||
<Card extra={"w-full py-4 px-6 h-full mb-4"}> | ||
<div className="flex flex-col justify-between min-h-[300px]"> | ||
<div> | ||
<h3 className="font-bold text-[20px] mb-1">People</h3> | ||
<div className="flex flex-col mt-2"> | ||
<span>{data?.name}</span> | ||
</div> | ||
</div> | ||
</div> | ||
</Card> | ||
</div> | ||
|
||
<h1 className="text-neutral-500 mt-6 text-xl font-bold dark:text-white"> | ||
Datasets | ||
</h1> | ||
<div className="mt-2 grid h-full gap-5 grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4"> | ||
{data?.dataset_spaces?.map((df) => ( | ||
<Card | ||
key={df.dataset_id} | ||
extra={ | ||
"w-full pt-4 px-6 h-full border dark:border-none border-[#ccc] pb-8" | ||
} | ||
> | ||
<header className="relative flex items-center justify-between"> | ||
<div className="w-full"> | ||
<div className="flex justify-center h-24"> | ||
<FaFileCsv size="4em" key={0} /> | ||
</div> | ||
<div className="h-[65px] w-full overflow-hidden"> | ||
<h1 className="dark:text-white font-bold font-montserrat text-[20px] text-center customellipsis"> | ||
{df?.dataset?.name} | ||
</h1> | ||
</div> | ||
</div> | ||
</header> | ||
<div className="w-full flex flex-wrap items-center justify-center mt-1"> | ||
<Link href={`/settings/datasets/${df?.dataset?.id}`}> | ||
<Button>Details</Button> | ||
</Link> | ||
</div> | ||
</Card> | ||
))} | ||
<Link href={`/settings/datasets/add?space_id=${params.id}`}> | ||
<AddNewCard text="New dataset" /> | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
127 changes: 127 additions & 0 deletions
127
client/app/settings/workspaces/addspaces/AddSpaceCard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
"use client"; | ||
import React, { useState } from "react"; | ||
import { Loader } from "components/loader/Loader"; | ||
import Multiselect from "multiselect-react-dropdown"; | ||
import { useRouter } from "next/navigation"; | ||
import { toast } from "react-toastify"; | ||
import { AddWorkspace } from "@/services/spaces"; | ||
import { revalidateWorkspaces } from "@/lib/actions"; | ||
|
||
interface IProps { | ||
datasets: any; | ||
} | ||
|
||
interface DataFrame { | ||
id: number; | ||
name: string; | ||
} | ||
const AddSpaceCard = ({ datasets }: IProps) => { | ||
const [name, setName] = useState<string>(""); | ||
const [items, setItems] = useState<DataFrame[]>([]); | ||
const [isLoading, setIsLoading] = useState<boolean>(false); | ||
const [nameError, setNameError] = useState<string>(""); | ||
const [dataFramesError, setDataFramesError] = useState<string>(""); | ||
const dataFrameNames = []; | ||
const dataFrameIds: number[] = []; | ||
const router = useRouter(); | ||
|
||
items.forEach((data) => { | ||
return dataFrameIds?.push(data.id); | ||
}); | ||
|
||
datasets?.map((data) => { | ||
return dataFrameNames.push({ id: data?.id, name: data?.name }); | ||
}); | ||
|
||
const handleSelect = (selectedList) => { | ||
setItems(selectedList); | ||
}; | ||
|
||
const handleSelectRemove = (selectedList) => { | ||
setItems(selectedList); | ||
}; | ||
|
||
const handleSubmit = async () => { | ||
setNameError(""); | ||
let isValid = true; | ||
if (name?.trim() === "") { | ||
setNameError("Name field is required"); | ||
isValid = false; | ||
} | ||
|
||
if (items?.length === 0) { | ||
setDataFramesError("Tables is required"); | ||
isValid = false; | ||
} | ||
|
||
if (!isValid) { | ||
return; | ||
} | ||
setIsLoading(true); | ||
const payLoad = { | ||
name: name, | ||
datasets: [...dataFrameIds], | ||
}; | ||
await AddWorkspace(payLoad) | ||
.then((response) => { | ||
toast.success(response?.data?.message); | ||
setName(""); | ||
revalidateWorkspaces(); | ||
router.push("/settings/workspaces"); | ||
}) | ||
.catch((error) => { | ||
toast.error( | ||
error?.response?.data?.message | ||
? error?.response?.data?.message | ||
: error?.message | ||
); | ||
}) | ||
.finally(() => setIsLoading(false)); | ||
}; | ||
|
||
return ( | ||
<div className="!z-5 mx-auto relative rounded-[20px] bg-white bg-clip-border shadow-3xl shadow-shadow-100 dark:shadow-none dark:!bg-darkMain dark:text-white max-w-xl p-4 mb-4"> | ||
<div className="mb-4"> | ||
<label className="w-full">Name*</label> | ||
<input | ||
type="text" | ||
value={name} | ||
onChange={(e) => setName(e.target.value)} | ||
className={`w-full p-2 border rounded dark:!bg-darkMain `} | ||
/> | ||
{nameError && name?.length < 1 && ( | ||
<div className="mb-2 rounded-lg bg-red-50 p-2 text-sm text-red-800 dark:bg-gray-800 dark:text-red-500 mt-2 inline-flex"> | ||
{nameError} | ||
</div> | ||
)} | ||
</div> | ||
<div className="mb-4 "> | ||
<label className="w-full">Tables*</label> | ||
<Multiselect | ||
className="selectBox" | ||
options={dataFrameNames} | ||
selectedValues={items} | ||
onSelect={handleSelect} | ||
onRemove={handleSelectRemove} | ||
displayValue="name" | ||
/> | ||
{dataFramesError && items?.length < 1 && ( | ||
<div className="mb-2 rounded-lg bg-red-50 p-2 text-sm text-red-800 dark:bg-gray-800 dark:text-red-500 mt-2 inline-flex"> | ||
{dataFramesError} | ||
</div> | ||
)} | ||
</div> | ||
<div className="text-right"> | ||
<button | ||
className="px-4 py-1 text-md rounded linear bg-[#191919] font-medium text-white transition duration-200 dark:bg-[#191919 dark:text-white dark:hover:bg-[#191919 dark:active:bg-[#191919" | ||
onClick={handleSubmit} | ||
disabled={isLoading} | ||
> | ||
{isLoading ? <Loader height="h-6" width="w-10" /> : "Save"} | ||
</button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default AddSpaceCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Loader } from "@/components/loader/Loader"; | ||
import React from "react"; | ||
|
||
const Loading = () => { | ||
return ( | ||
<div className="flex items-center justify-center w-full h-full mx-auto"> | ||
<Loader /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Loading; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React from "react"; | ||
import Link from "next/link"; | ||
import { GetAllDataSets } from "@/services/datasets"; | ||
import AddSpaceCard from "./AddSpaceCard"; | ||
import { Button } from "@/components/ui/button"; | ||
|
||
export default async function AddSpaces() { | ||
const data = await GetAllDataSets(); | ||
|
||
return ( | ||
<div className="w-full h-full overflow-y-auto custom-scroll mt-5 px-2 md:px-4"> | ||
<h1 className="text-2xl font-bold dark:text-white mb-10"> | ||
<Link href="/settings/workspaces">Workspaces</Link> | ||
<small> › New</small> | ||
</h1> | ||
|
||
{data?.datasets?.length === 0 ? ( | ||
<div className="flex flex-col items-center justify-center m-auto"> | ||
<p className="dark:text-white font-montserrat text-lg mb-3"> | ||
No datasets available, please add one | ||
</p> | ||
|
||
<Link href={"/settings/datasets/add"}></Link> | ||
<Button>Add</Button> | ||
</div> | ||
) : ( | ||
<AddSpaceCard datasets={data?.datasets} /> | ||
)} | ||
</div> | ||
); | ||
} |
Oops, something went wrong.