]> PHS Git Server - phs-admin.git/commitdiff
Cleaning up Docker.jsx and Git.jsx main views.
authorcharleswrayjr <charleswrayjr@gmail.com>
Sun, 14 Sep 2025 03:23:19 +0000 (22:23 -0500)
committercharleswrayjr <charleswrayjr@gmail.com>
Sun, 14 Sep 2025 03:23:19 +0000 (22:23 -0500)
src/app/views/Docker/Docker.jsx
src/app/views/Git/Git.jsx

index d1f9caf7a57d5c8f89aecfe5e6499bad9fbc464d..9fa72dd5a51e3ce21c453bc2d2748c8f0f886a9d 100644 (file)
@@ -1,5 +1,5 @@
 import React, { useEffect, useState } from 'react';
-import { Button, Container, TextField, Typography } from '@mui/material';
+import { Button, Container, Tab, Tabs, TextField, Typography } from '@mui/material';
 import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
 import { DockerService } from '../../services';
 
@@ -8,6 +8,12 @@ const Docker = () => {
   const [images, setImages] = useState( [] );
   const [composeFile, setComposeFile] = useState( '' );
   const [message, setMessage] = useState( '' );
+  const [activeTab, setActiveTab] = useState( 0 );
+
+  useEffect( () => {
+    fetchImages().catch();
+    fetchContainers().catch();
+  }, [] );
 
   const fetchContainers = async () => {
     try {
@@ -17,7 +23,6 @@ const Docker = () => {
       setMessage( error );
     }
   };
-
   const fetchImages = async () => {
     try {
       const imagesData = await DockerService.fetchImages(); // Assuming you have a service to fetch images
@@ -26,22 +31,14 @@ const Docker = () => {
       setMessage( error );
     }
   };
-
-  useEffect( () => {
-    fetchImages().catch();
-    fetchContainers().catch();
-  }, [] );
-
   const handleContainerAction = async ( action, containerId ) => {
     await DockerService.containerAction( action, containerId );
     await fetchContainers();
   };
-
   const handleComposeSubmit = async ( event ) => {
     event.preventDefault();
     setMessage( await DockerService.composeDown( composeFile ) );
   };
-
   const containerTable = useMaterialReactTable( {
     columns:[
       { accessorKey:'id', header:'ID' },
@@ -68,41 +65,48 @@ const Docker = () => {
         ),
       },
     ],
-    data:containers
+    data:containers,
+    renderTopToolbarCustomActions:() => (<Typography variant="h5"
+                                                     className="mt-6">Docker Containers</Typography>)
   } );
-
   const imageTable = useMaterialReactTable( {
     columns:[
       { accessorKey:'id', header:'ID' },
       { accessorKey:'tags', header:'Tags', Cell:( { cell } ) => cell.getValue().join( ', ' ) },
       { accessorKey:'created', header:'Created' },
     ],
-    data:images
+    data:images,
+    renderTopToolbarCustomActions:() => (<Typography variant="h5"
+                                                     className="mt-6">Docker Images</Typography>)
   } );
 
   return (
-    <Container>
-      <Typography variant="h5"
-                  className="mt-6">Docker Containers</Typography>
-      <MaterialReactTable table={ containerTable }/>
-
-      <Typography variant="h5"
-                  className="mt-6">Docker Images</Typography>
-      <MaterialReactTable table={ imageTable }/>
-
-      <Typography variant="h5"
-                  className="mt-6">Stop Docker Compose Services</Typography>
-      <form onSubmit={ handleComposeSubmit }
-            className="space-y-4">
-        <TextField label="Compose File Path"
-                   value={ composeFile }
-                   onChange={ ( e ) => setComposeFile( e.target.value ) }
-                   fullWidth/>
-        <Button type="submit"
-                variant="contained"
-                color="secondary">Stop Compose Services</Button>
-      </form>
-
+    <Container maxWidth="xxl">
+      <Tabs value={ activeTab }>
+        <Tab label="Containers"
+             onClick={ () => setActiveTab( 0 ) }/>
+        <Tab label="Images"
+             onClick={ () => setActiveTab( 1 ) }/>
+        <Tab label="Compose"
+             onClick={ () => setActiveTab( 2 ) }/>
+      </Tabs>
+      { activeTab === 0 && <MaterialReactTable table={ containerTable }/> }
+      { activeTab === 1 && <MaterialReactTable table={ imageTable }/> }
+      { activeTab === 2 &&
+        <>
+          <Typography variant="h5"
+                      className="mt-6">Stop Docker Compose Services</Typography>
+          <form onSubmit={ handleComposeSubmit }
+                className="space-y-4">
+            <TextField label="Compose File Path"
+                       value={ composeFile }
+                       onChange={ ( e ) => setComposeFile( e.target.value ) }
+                       fullWidth/>
+            <Button type="submit"
+                    variant="contained"
+                    color="secondary">Stop Compose Services</Button>
+          </form>
+        </> }
       { message && <Typography color={ message?.startsWith( 'Error' ) ? 'error' : 'success' }>{ message }</Typography> }
     </Container>
   );
index 165d9ec0221eedda3f1310efa6307c0993348505..cc11f0ff084b5d82b1df342682b7423b50c8c9d9 100755 (executable)
-import React, { useState, useEffect } from 'react';
-
-import { Container, Typography, TextField, Button, Select, MenuItem } from '@mui/material';
-import { MaterialReactTable } from 'material-react-table';
+import React, { useEffect, useState } from 'react';
+import {
+  Button,
+  Card,
+  CardActions,
+  CardContent,
+  CardHeader,
+  Container,
+  Grid,
+  MenuItem,
+  Select,
+  TextField,
+  Typography
+} from '@mui/material';
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
 import { GitService } from '../../services';
 
 const Git = () => {
-  const [repoName, setRepoName] = useState('');
-  const [repoType, setRepoType] = useState('global');
-  const [repoUser, setRepoUser] = useState('');
-  const [message, setMessage] = useState('');
+  const [repoName, setRepoName] = useState( '' );
+  const [repoType, setRepoType] = useState( 'global' );
+  const [repoUser, setRepoUser] = useState( '' );
+  const [message, setMessage] = useState( '' );
   const [repos, setRepos] = useState( [] );
-  const [deployRepoName, setDeployRepoName] = useState('');
-  const [deployPath, setDeployPath] = useState('');
-  const [deployUser, setDeployUser] = useState('');
+  const [deployRepoName, setDeployRepoName] = useState( '' );
+  const [deployPath, setDeployPath] = useState( '' );
+  const [deployUser, setDeployUser] = useState( '' );
 
   const fetchRepos = async () => {
     await GitService.fetchRepos().then( res => setRepos( res ) ).catch( err => setMessage( err ) );
   };
 
-  useEffect(() => {
+  useEffect( () => {
     fetchRepos().catch( e => setMessage( e ) );
   }, [] );
 
-  const handleRepoSubmit = async (e) => {
+  const handleRepoSubmit = async ( e ) => {
     e.preventDefault();
-    setMessage( await GitService.createRepo({repoName, repoType, repoUser}, fetchRepos ) );
+    setMessage( await GitService.createRepo( { repoName, repoType, repoUser }, fetchRepos ) );
   };
 
-  const handleDeleteRepo = async (name) => {
-      setMessage( await GitService.deleteRepo( name, fetchRepos ) );
+  const handleDeleteRepo = async ( name ) => {
+    setMessage( await GitService.deleteRepo( name, fetchRepos ) );
   };
 
-  const handleCloneSubmit = async (e) => {
+  const handleCloneSubmit = async ( e ) => {
     e.preventDefault();
     setMessage( await GitService.cloneRepo( { deployRepoName, deployPath, deployUser } ) );
   };
 
-  return(
-    <Container>
-      <Typography variant="h5">Create Git Repository</Typography>
-      <form onSubmit={handleRepoSubmit} className="space-y-4">
-        <TextField
-          label="Repository Name"
-          value={repoName}
-          onChange={(e) => setRepoName(e.target.value)}
-          fullWidth
-        />
-        <Select
-          value={repoType}
-          onChange={(e) => setRepoType(e.target.value)}
-          fullWidth
-        >
-          <MenuItem value="global">Global (Group-Shared)</MenuItem>
-          <MenuItem value="private">Private (User-Specific)</MenuItem>
-        </Select>
-          <TextField
-            label="Username"
-            value={repoUser}
-            onChange={(e) => setRepoUser(e.target.value)}
-            fullWidth
-          />
-        <Button type="submit" variant="contained" color="primary">Create Repository</Button>
-      </form>
+  const gitTable = useMaterialReactTable( {
+    columns:[
+      { accessorKey:'name', header:'Name' },
+      { accessorKey:'cloneUrl', header:'Clone URL' },
+      {
+        header:'Actions',
+        Cell:( { row } ) => (
+          <Button variant="contained"
+                  color="secondary"
+                  onClick={ () => handleDeleteRepo( row.original.name ) }>
+            Delete
+          </Button>
+        ),
+      },
+    ],
+    data:repos,
+    enableRowActions:true,
+    renderRowActions:( { row } ) => (
+      <Button onClick={ () => navigator.clipboard.writeText( row.original.cloneUrl ) }>
+        Copy Clone URL
+      </Button>
+    ),
+    renderTopToolbarCustomActions:() => (<Typography variant="h5"
+                                                     className="mt-6">Repositories</Typography>)
+  } );
 
-      <Typography variant="h5" className="mt-6">Clone Repository Locally</Typography>
-      <form onSubmit={handleCloneSubmit} className="space-y-4">
-        <TextField
-          label="Repository Name"
-          value={deployRepoName}
-          onChange={(e) => setDeployRepoName(e.target.value)}
-          fullWidth
-        />
-        <TextField
-          label="Deployment Path"
-          value={deployPath}
-          onChange={(e) => setDeployPath(e.target.value)}
-          fullWidth
-        />
-        <TextField
-          label="Username"
-          value={deployUser}
-          onChange={(e) => setDeployUser(e.target.value)}
-          fullWidth
-        />
-        <Button type="submit" variant="contained" color="primary">Clone Repository</Button>
-      </form>
+  return (
+    <Container maxWidth="xxl">
+      <Grid container
+            spacing={ 2 }>
+        <Grid item
+              size={ { xs:12, sm:6 } }>
+          <Card className="mt-6">
+            <CardHeader title="Create Git Repository"
+                        component="h5"
+                        className="!pt-0 !pb-0"/>
+            <form onSubmit={ handleRepoSubmit }
+                  className="space-y-4">
+              <CardContent>
+                <TextField label="Repository Name"
+                           value={ repoName }
+                           onChange={ ( e ) => setRepoName( e.target.value ) }
+                           fullWidth/>
+                <Select variant="outlined"
+                        value={ repoType }
+                        onChange={ ( e ) => setRepoType( e.target.value ) }
+                        fullWidth>
+                  <MenuItem value="global">Global (Group-Shared)</MenuItem>
+                  <MenuItem value="private">Private (User-Specific)</MenuItem>
+                </Select>
+                <TextField label="Username"
+                           value={ repoUser }
+                           onChange={ ( e ) => setRepoUser( e.target.value ) }
+                           fullWidth/>
+              </CardContent>
+              <CardActions>
+                <Button type="submit"
+                        variant="contained"
+                        color="primary">Create Repository</Button>
+              </CardActions>
+            </form>
+          </Card>
+        </Grid>
+        <Grid item
+              size={ { xs:12, sm:6 } }>
+          <Card className="mt-6">
+            <CardHeader title="Clone Repository Locally"
+                        component="h5"
+                        className="!pt-0 !pb-0"/>
+            <form onSubmit={ handleCloneSubmit }
+                  className="space-y-4">
+              <CardContent>
+                <TextField label="Repository Name"
+                           value={ deployRepoName }
+                           onChange={ ( e ) => setDeployRepoName( e.target.value ) }
+                           fullWidth/>
+                <TextField label="Deployment Path"
+                           value={ deployPath }
+                           onChange={ ( e ) => setDeployPath( e.target.value ) }
+                           fullWidth/>
+                <TextField label="Username"
+                           value={ deployUser }
+                           onChange={ ( e ) => setDeployUser( e.target.value ) }
+                           fullWidth/>
+              </CardContent>
+              <CardActions>
+                <Button type="submit"
+                        variant="contained"
+                        color="primary">Clone Repository</Button>
+              </CardActions>
+            </form>
+          </Card>
+        </Grid>
+      </Grid>
+      <br/>
 
-      <Typography variant="h5" className="mt-6">Repositories</Typography>
-      <MaterialReactTable
-        columns={[
-          { accessorKey: 'name', header: 'Name' },
-          { accessorKey: 'cloneUrl', header: 'Clone URL' },
-          {
-            header: 'Actions',
-            Cell: ({ row }) => (
-              <Button
-                variant="contained"
-                color="secondary"
-                onClick={() => handleDeleteRepo(row.original.name)}
-              >
-                Delete
-              </Button>
-            ),
-          },
-        ]}
-        data={repos}
-        enableRowActions
-        renderRowActions={({ row }) => (
-          <Button
-            onClick={() => navigator.clipboard.writeText(row.original.cloneUrl)}
-          >
-            Copy Clone URL
-          </Button>
-        )}
-      />
+      <MaterialReactTable table={ gitTable }/>
 
-      {message && <Typography color={message.startsWith('Error') ? 'error' : 'success'}>{message}</Typography>}
+      { message && <Typography color={ message.startsWith( 'Error' ) ? 'error' : 'success' }>{ message }</Typography> }
     </Container>
   );
 };