1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/web/ synced 2025-03-09 00:00:01 +01:00

added pages for usergroups and add usergroup dialog

Signed-off-by: Andrii Podriez <andrey5577990@gmail.com>
This commit is contained in:
Andrii Podriez 2024-09-18 13:58:41 +02:00 committed by Youssef Nakti
parent b1628fa081
commit 7364b74d2f
12 changed files with 387 additions and 1 deletions

View file

@ -37,6 +37,8 @@ import './styles/login.css';
import branding from './branding/branding';
import Logout from './pages/login/logout';
import Infrastructure from './pages/infrastructure/infrastructure';
import Usergroups from './pages/usergroups/usergroups';
import Usergroup from './pages/usergroups/usergroup';
import { useSelector } from 'react-redux';
const App = () => {
@ -72,6 +74,12 @@ const App = () => {
<Route exact path="/scenarios">
<Scenarios />
</Route>
<Route path="/usergroups">
<Usergroups />
</Route>
<Route path="/usergroup/:usergroup">
<Usergroup />
</Route>
<Route exact path="/logout">
<Logout />
</Route>

View file

@ -157,6 +157,7 @@ class Branding {
pages.scenarios = true;
pages.infrastructure = true;
pages.users = true;
pages.usergroups = true;
pages.account = true;
pages.api = true;

View file

@ -23,6 +23,7 @@ const villasweb_values = {
home: true,
scenarios: true,
infrastructure: true,
usergroups: true,
account: true,
api: true,
},

View file

@ -99,6 +99,13 @@ const SideBarMenu = (props) => {
</NavLink>
</li> : ''
}
<li>
<NavLink
to="/usergroups"
title="Usegroups">
Usergroups
</NavLink>
</li>
<li hidden={!values.pages.account}>
<NavLink
to="/account"
@ -156,6 +163,13 @@ const SideBarMenu = (props) => {
</NavLink>
</li> : ''
}
<li>
<NavLink
to="/usergroups"
title="Usegroups">
Usergroups
</NavLink>
</li>
<li hidden={!values.pages.account}>
<NavLink
to="/account"

View file

@ -0,0 +1,117 @@
/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import React from 'react';
import { useState } from 'react';
import { Form, Col, Button} from 'react-bootstrap';
import Dialog from '../../../common/dialogs/dialog';
import { useGetScenariosQuery } from '../../../store/apiSlice';
const AddUsergroupDialog = ({isModalOpened, onClose}) => {
const [name, setName] = useState('');
const [isValid, setIsValid] = useState(false);
const [selectedOption, setSelectedOption] = useState('addUsersToScenario');
const [selectedScenarioID, setSelectedScenarioID] = useState('');
const {data: {scenarios} = {}, isLoading: isLoadingScenarios} = useGetScenariosQuery();
const checkValidity = (name, scenarioID) => {
//group names have to be at lest 3 characters long and cannot start with spaces
const isNameValid = name.length >= 3 && !(/^\s/.test(name));
//scenario ID is chosen from the dropdown therefore we just make sure that empty option is not selected
const isScenarioIDValid = scenarioID !== '';
setIsValid(isNameValid && isScenarioIDValid);
}
const handleNameChange = (e) => {
const newName = e.target.value;
setName(newName);
checkValidity(newName, selectedScenarioID);
}
const handleRadioChange = (e) => {
setSelectedOption(e.target.value);
}
const handleClose = (canceled) => {
if(canceled) {
onClose(null);
} else {
onClose({name: name, scenarioID: selectedScenarioID, isDuplicateSelected: selectedOption === 'duplicateScenarioForUsers'});
}
}
const handleReset = () => {
setName('');
}
const handleSelectChange = (e) => {
setSelectedScenarioID(e.target.value);
checkValidity(name, e.target.value);
};
return (<Dialog
show={isModalOpened}
title="New User Group"
buttonTitle="Add"
onClose={handleClose}
onReset={handleReset}
valid={isValid}>
<Form>
<Form.Group as={Col} controlId="name" style={{marginBottom: '15px'}}>
<Form.Label>Name</Form.Label>
<Form.Control type="text" placeholder="Enter name" value={name} onChange={handleNameChange} />
<Form.Control.Feedback />
</Form.Group>
<Form.Group as={Col} controlId="radioGroup" style={{ marginBottom: '15px' }}>
<div>
<Form.Check
type="radio"
id="addUsersToScenario"
name="options"
label="Add users to scenario"
value="addUsersToScenario"
checked={selectedOption === 'addUsersToScenario'}
onChange={handleRadioChange}
/>
<Form.Check
type="radio"
id="duplicateScenarioForUsers"
name="options"
label="Duplicate scenario for each user"
value="duplicateScenarioForUsers"
checked={selectedOption === 'duplicateScenarioForUsers'}
onChange={handleRadioChange}
/>
</div>
</Form.Group>
<Form.Group controlId="scenario">
<Form.Label>Select Option</Form.Label>
{isLoadingScenarios ? <div>Loading...</div> : (
<Form.Control as="select" value={selectedScenarioID} onChange={handleSelectChange}>
<option value="">-- Select scenario --</option>
{scenarios.map(scenario => <option key={scenario.id} value={scenario.id}>{scenario.name}</option>)}
</Form.Control>
)}
</Form.Group>
</Form>
</Dialog>);
}
export default AddUsergroupDialog;

View file

@ -0,0 +1,21 @@
export const buttonStyle = {
marginLeft: '5px',
}
export const iconStyle = {
height: '25px',
width: '25px'
}
export const tableHeadingStyle = {
paddingTop: '30px'
}
export const dialogWarningLabel = {
background: '#eb4d2a',
color: 'white'
}
export const signalDialogCheckButton = {
float: 'right'
}

View file

@ -0,0 +1,22 @@
/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
const UsergroupScenariosTable = (props) => {
return <div></div>
}
export default UsergroupScenariosTable;

View file

@ -0,0 +1,22 @@
/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
const UsergroupUsersTable = (props) => {
return <div></div>
}
export default UsergroupUsersTable;

View file

@ -0,0 +1,46 @@
/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import { useParams } from "react-router-dom/cjs/react-router-dom.min";
import { Table, DataColumn, LinkColumn } from "../../common/table";
import { Row, Col } from "react-bootstrap";
import UsergroupScenariosTable from "./tables/usergroup-scenarios-table";
import UsergroupUsersTable from "./tables/usergroup-users-table";
const Usergroup = (props) => {
// const params = useParams();
// const id = params.usergroup;
const usergroup = {name: 'Test Group'};
return (
<div className='section'>
<h1>{usergroup.name}</h1>
<Row>
<Col>
<h4>Users</h4>
<UsergroupUsersTable />
</Col>
<Col>
<h4>Scenario Mappings</h4>
<UsergroupScenariosTable />
</Col>
</Row>
</div>
);
}
export default Usergroup;

View file

@ -0,0 +1,82 @@
/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import { useState } from "react";
import { useGetUsergroupsQuery, useAddUserGroupMutation } from "../../store/apiSlice";
import { Table, DataColumn, LinkColumn } from "../../common/table";
import IconButton from "../../common/buttons/icon-button";
import { buttonStyle, iconStyle } from "./styles";
import AddUsergroupDialog from "./dialogs/addUsergroupDialog";
const Usergroups = (props) => {
const {data: {usergroups} = {}, refetch: refetchUsergroups, isLoading} = useGetUsergroupsQuery();
const [addUserGroup] = useAddUserGroupMutation();
const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
const handleAddNewGroup = async (response) => {
if(response){
try {
//put data in correct structure
const usergroup = {Name: response.name, ScenarioMappings: [{Duplicate: response.isDuplicateSelected, ScenarioID: Number(response.scenarioID)}]};
await addUserGroup(usergroup).unwrap();
refetchUsergroups();
} catch (err) {
console.log("Error adding usergroup: ", err);
}
}
setIsAddDialogOpen(false);
}
if(isLoading) return <div>Loading</div>;
if(usergroups){
return (<div className="section">
<h1>
User Groups
<span className="icon-button">
<IconButton
childKey={0}
tooltip="Add Usergroup"
onClick={() => setIsAddDialogOpen(true)}
icon="plus"
buttonStyle={buttonStyle}
iconStyle={iconStyle}
/>
</span>
</h1>
<Table data={usergroups}>
<DataColumn
title='ID'
dataKey='id'
width={70}
/>
<LinkColumn
title="Name"
dataKey="name"
link="/usergroup/"
linkKey="id"
/>
</Table>
<AddUsergroupDialog isModalOpened={isAddDialogOpen} onClose={handleAddNewGroup} />
</div>);
}
}
export default Usergroups;

View file

@ -1,3 +1,20 @@
/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { sessionToken } from '../localStorage';
import { widgetEndpoints } from './endpoints/widget-endpoints';
@ -11,6 +28,7 @@ import { signalEndpoints } from './endpoints/signal-endpoints';
import { resultEndpoints } from './endpoints/result-endpoints';
import { authEndpoints } from './endpoints/auth-endpoints';
import { websocketEndpoints } from './endpoints/websocket-endpoints';
import { usergroupEndpoints } from './endpoints/usergroup-endpoints';
export const apiSlice = createApi({
reducerPath: 'api',
@ -36,6 +54,7 @@ export const apiSlice = createApi({
...signalEndpoints(builder),
...authEndpoints(builder),
...websocketEndpoints(builder),
...usergroupEndpoints(builder),
}),
});
@ -86,5 +105,7 @@ export const {
useUpdateSignalMutation,
useGetIcDataQuery,
useLazyDownloadImageQuery,
useUpdateComponentConfigMutation
useUpdateComponentConfigMutation,
useGetUsergroupsQuery,
useAddUserGroupMutation
} = apiSlice;

View file

@ -0,0 +1,31 @@
/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
export const usergroupEndpoints = (builder) => ({
getUsergroups: builder.query({
query: () => 'usergroups',
}),
addUserGroup: builder.mutation({
query: (usergroup) => ({
url: '/usergroups',
method: 'POST',
body: {
userGroup: usergroup
},
}),
}),
});