Skip to content

Commit

Permalink
feat(extension): add the OwnerMonitor component
Browse files Browse the repository at this point in the history
  • Loading branch information
aldbr committed Dec 18, 2024
1 parent cbaa472 commit c676ecc
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 89 deletions.
File renamed without changes.
5 changes: 5 additions & 0 deletions packages/extensions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"dependencies": {
"@axa-fr/react-oidc": "^7.22.6",
"@dirac-grid/diracx-web-components": "0.1.0-a2",
"@mui/icons-material": "^6.1.6",
"@mui/material": "^6.1.6",
"@mui/utils": "^6.1.6",
"@mui/x-date-pickers": "^7.14.0",
"@tanstack/react-table": "^8.20.5",
"autoprefixer": "10.4.19",
"next": "15.0.2",
"react": "^18",
Expand Down
4 changes: 2 additions & 2 deletions packages/extensions/src/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
DiracXWebProviders,
} from "@dirac-grid/diracx-web-components/contexts";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { applicationList } from "@/gubbins/applicationList";
import { defaultSections } from "@/gubbins/defaultUserDashboard";
import { applicationList } from "@/gubbins/ApplicationList";
import { defaultSections } from "@/gubbins/DefaultUserDashboard";

// Layout for the dashboard: setup the providers and the dashboard for the applications
export default function DashboardLayout({
Expand Down
2 changes: 1 addition & 1 deletion packages/extensions/src/app/(dashboard)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useContext, useMemo } from "react";
import { useSearchParams } from "next/navigation";
import { BaseApp } from "@dirac-grid/diracx-web-components/components";
import { ApplicationsContext } from "@dirac-grid/diracx-web-components/contexts";
import { applicationList } from "@/gubbins/applicationList";
import { applicationList } from "@/gubbins/ApplicationList";

export default function Page() {
const searchParams = useSearchParams(); // Get and set the search params from the URL
Expand Down
13 changes: 13 additions & 0 deletions packages/extensions/src/gubbins/ApplicationList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { applicationList } from "@dirac-grid/diracx-web-components/components";
import { ApplicationMetadata } from "@dirac-grid/diracx-web-components/types";
import ElectricScooterIcon from "@mui/icons-material/ElectricScooter";
import OwnerMonitor from "@/gubbins/components/OwnerMonitor/OwnerMonitor";

// New Application List with the default ones + the Owner Monitor
const appList: ApplicationMetadata[] = [
...applicationList,
{ name: "Owner Monitor", component: OwnerMonitor, icon: ElectricScooterIcon },
];

export { appList as applicationList };
export default appList;
29 changes: 29 additions & 0 deletions packages/extensions/src/gubbins/DefaultUserDashboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { DashboardGroup } from "@dirac-grid/diracx-web-components/types";
import { BugReport } from "@mui/icons-material";
import { applicationList } from "@/gubbins/ApplicationList";

// New default user sections
export const defaultSections: DashboardGroup[] = [
{
title: "My Gubbins Apps",
extended: true,
items: [
{
title: "Owners",
id: "OwnerMonitor1",
type: "Owner Monitor",
icon:
applicationList.find((app) => app.name === "Owner Monitor")?.icon ||
BugReport,
},
{
title: "My Jobs",
id: "JobMonitor1",
type: "Job Monitor",
icon:
applicationList.find((app) => app.name === "Job Monitor")?.icon ||
BugReport,
},
],
},
];
13 changes: 0 additions & 13 deletions packages/extensions/src/gubbins/applicationList.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
"use client";
import React, { useEffect, useMemo, useState } from "react";
import { useOidcAccessToken } from "@axa-fr/react-oidc";
import {
fetcher,
useOIDCContext,
} from "@dirac-grid/diracx-web-components/hooks";
import {
Alert,
Box,
Button,
Snackbar,
TextField,
Typography,
} from "@mui/material";
import {
createColumnHelper,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import { DataTable } from "@dirac-grid/diracx-web-components/components";
import { Owner } from "@/gubbins/types/Owner";

/**
* Owner Monitor component
* @returns Owner Monitor component
*/
export default function OwnerMonitor() {
// Get info from the auth token
const { configuration } = useOIDCContext();
const { accessToken } = useOidcAccessToken(configuration?.scope);

const [owners, setOwners] = useState<Owner[]>([]);
const [ownerName, setOwnerName] = useState("");
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [pagination, setPagination] = useState({
pageIndex: 0,
pageSize: 25, // Default to 25 rows per page
});

// Fetch the list of owners
const fetchOwners = async () => {
try {
setIsLoading(true);
const response = await fetcher<string[]>([
"/api/lollygag/get_owners",
accessToken,
]);

// Transform names into objects with id and name
const transformedData = response.data.map((name, index) => ({
ownerID: index + 1, // Generate a unique ID
name, // Set the name
}));
setOwners(transformedData);
} catch (err) {
setError("Failed to fetch owners");
} finally {
setIsLoading(false);
}
};

useEffect(() => {
fetchOwners();
}, [accessToken]);

// Handle adding a new owner
const handleAddOwner = async () => {
if (!ownerName) return setError("Owner name cannot be empty.");
try {
await fetcher([
`/api/lollygag/insert_owner/${ownerName}`,
accessToken,
"POST",
]);
setSuccess(`Owner "${ownerName}" added successfully.`);
setOwnerName("");
fetchOwners(); // Refresh the owners list
} catch (err) {
setError("Failed to add owner.");
}
};

// Define table columns
const columnHelper = createColumnHelper<Owner>();
const columns = useMemo(
() => [
columnHelper.accessor("ownerID", { header: "ID" }),
columnHelper.accessor("name", { header: "Owner Name" }),
],
[columnHelper],
);

// Table instance
const table = useReactTable({
data: owners,
columns,
state: { pagination },
getCoreRowModel: getCoreRowModel(),
onPaginationChange: setPagination,
});

return (
<Box
sx={{
display: "flex",
flexDirection: "column",
flexGrow: 1,
overflow: "hidden",
}}
>
{/* Input to add owner */}
<Box display="flex" gap={2} alignItems="center" mb={2}>
<TextField
label="Owner Name"
value={ownerName}
onChange={(e) => setOwnerName(e.target.value)}
variant="outlined"
fullWidth
data-testid="owner-name-input"
/>
<Button variant="contained" color="primary" onClick={handleAddOwner}>
Add Owner
</Button>
</Box>

{/* Success and Error messages */}
{error && (
<Alert severity="error" onClose={() => setError(null)}>
{error}
</Alert>
)}
{success && (
<Snackbar open autoHideDuration={3000} onClose={() => setSuccess(null)}>
<Alert onClose={() => setSuccess(null)} severity="success">
{success}
</Alert>
</Snackbar>
)}

{/* Owner List Table */}
<DataTable<Owner>
title="Owners List"
table={table}
totalRows={owners.length}
searchBody={{}}
setSearchBody={() => {}}
error={null}
isLoading={isLoading}
isValidating={isLoading}
toolbarComponents={<></>}
menuItems={[]}
/>
</Box>
);
}
28 changes: 0 additions & 28 deletions packages/extensions/src/gubbins/components/TestApp/testApp.tsx

This file was deleted.

45 changes: 0 additions & 45 deletions packages/extensions/src/gubbins/defaultUserDashboard.tsx

This file was deleted.

6 changes: 6 additions & 0 deletions packages/extensions/src/gubbins/types/Owner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface Owner {
ownerID: number;
name: string;
// If you want to create DataTable columns for the Owner type, you can use the following snippet:
[key: string]: unknown;
}
File renamed without changes.
Loading

0 comments on commit c676ecc

Please sign in to comment.