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 9c9dbe3
Show file tree
Hide file tree
Showing 14 changed files with 344 additions and 91 deletions.
60 changes: 58 additions & 2 deletions .github/workflows/gubbins-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,17 @@ jobs:
prepare-gubbins-backend:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }}
defaults:
run:
# We need extglob for REFERENCE_BRANCH substitution
shell: bash -l -O extglob {0}
steps:
- name: Clone source
run: |
cd ..
git clone https://github.com/DIRACGrid/diracx.git
# Prepare the gubbins extension
- name: Where the magic happens (Move extensions to a temporary directory)
run: |
# We have to copy the code to another directory
Expand All @@ -69,14 +74,61 @@ jobs:
cp -r ../diracx/extensions/gubbins /tmp/
sed -i 's@../..@.@g' /tmp/gubbins/pyproject.toml
sed -i 's@../../@@g' /tmp/gubbins/gubbins-*/pyproject.toml
git init /tmp/gubbins/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: gubbins
path: /tmp/gubbins
include-hidden-files: true

# Prepare the gubbins image
# - Build the gubbins wheels
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Installing dependencies
run: |
cd ../diracx
python -m pip install \
build \
python-dateutil \
pytz \
readme_renderer[md] \
requests \
setuptools_scm
- name: Build distributions
run: |
cd ../diracx
for pkg_dir in $PWD/diracx-*; do
echo "Building $pkg_dir"
python -m build --outdir $PWD/dist $pkg_dir
done
# Also build the diracx metapackage
python -m build --outdir $PWD/dist .
# And build the gubbins package
for pkg_dir in $PWD/extensions/gubbins/gubbins-*; do
# Skip the testing package
if [[ "${pkg_dir}" =~ .*testing.* ]];
then
echo "Do not build ${pkg_dir}";
continue;
fi
echo "Building $pkg_dir"
python -m build --outdir $PWD/dist $pkg_dir
done
- name: "Find wheels"
id: find_wheel
run: |
cd ../diracx/dist
# We need to copy them there to be able to access them in the RUN --mount
cp diracx*.whl gubbins*.whl ../extensions/containers/services/
for wheel_fn in *.whl; do
pkg_name=$(basename "${wheel_fn}" | cut -d '-' -f 1)
echo "${pkg_name}-wheel-name=$(ls "${pkg_name}"-*.whl)" >> $GITHUB_OUTPUT
done
# - Build the gubbins image using the wheels
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
Expand Down Expand Up @@ -210,6 +262,10 @@ jobs:
name: gubbins
path: /tmp/gubbins

- name: Create a new git repository
run: |
git init /tmp/gubbins/
- name: Clone diracx source
run: |
cd ..
Expand All @@ -219,7 +275,7 @@ jobs:
uses: actions/download-artifact@v4
with:
name: gubbins-services-img
path: /tmp/gubbins_services_image.tar
path: /tmp/

- name: Load docker image
run: docker load --input /tmp/gubbins_services_image.tar
Expand Down
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.

Loading

0 comments on commit 9c9dbe3

Please sign in to comment.