Skip to content

Commit

Permalink
fix: create new groups column in groups UI
Browse files Browse the repository at this point in the history
  • Loading branch information
wojtekzyla committed Jan 3, 2023
1 parent 9f9e6ad commit 1bb9e10
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 59 deletions.
236 changes: 236 additions & 0 deletions frontend/packages/manager/src/components/groups/GroupsList-old.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
import React, {useState, useContext, useEffect} from 'react';
import P from '@splunk/react-ui/Paragraph';
import GroupContext from "../../store/group-contxt";
import ButtonsContext from "../../store/buttons-contx";
import axios from "axios";
import CollapsiblePanel from '@splunk/react-ui/CollapsiblePanel';
import Table from "@splunk/react-ui/Table";
import { createDOMID } from '@splunk/ui-utils/id';
import Button from '@splunk/react-ui/Button';
import AddDeviceModal from "./AddDeviceModal";
import ButtonsModal from "../ButtonsModal";
import DeleteModal from "../DeleteModal";
import Paginator from '@splunk/react-ui/Paginator';
import Select from '@splunk/react-ui/Select';
import ControlGroup from '@splunk/react-ui/ControlGroup';
import { backendHost } from "../../host";
import ErrorsModalContext from "../../store/errors-modal-contxt";


function GroupsList() {
const [groups, setGroups] = useState([]);
const [openedGroups, setOpenedGroups] = useState({});
const GrCtx = useContext(GroupContext);
const BtnCtx = useContext(ButtonsContext);
const ErrCtx = useContext(ErrorsModalContext);
const [totalPages, setTotalPages] = useState(1);
const [openedGroupId, setOpenedGroupId] = useState(null);
const [pageNum, setPageNum] = useState(1);
const [devicesPerPage, setDevicesPerPage] = useState('3');
const DEVICES_PER_PAGE = 3;

useEffect(() => {
let isMounted = true;
axios.get(`http://${backendHost}/groups`)
.then((response) => {
if (isMounted){
setGroups(response.data);
let existingGroups = [];
let opened = {};
for (let group of response.data){
opened[group._id] = false;
existingGroups.push(group._id);
}
// If page was reloaded after updating one of devices, open tab of that group
if (GrCtx.editedGroupId && existingGroups.includes(GrCtx.editedGroupId)){
openCollapsible(GrCtx.editedGroupId, pageNum);
}else{
setOpenedGroups(opened);
}
}
});
GrCtx.setEditedGroupId(null);
return () => { isMounted = false }
}, [GrCtx.groupsChange]);

useEffect(() => {
setPageNum(1);
}, [openedGroupId]);

const editGroupButtonHandler = (groupId, groupName) => {
GrCtx.setGroupId(groupId);
GrCtx.setGroupName(groupName);
GrCtx.setIsGroupEdit(true);
GrCtx.setAddGroupOpen(true);
};

const newDeviceButtonHandler = (groupId, groupName) => {
GrCtx.setGroupId(groupId);
GrCtx.setGroupName(groupName);
GrCtx.setVersion("");
GrCtx.setPort(0);
GrCtx.setIsDeviceEdit(false);
GrCtx.setAddDeviceOpen(true);
GrCtx.resetDevice();
};

const deleteGroupButtonHandler = (groupId, groupName) => {
BtnCtx.setDeleteOpen(true);
GrCtx.setDeleteName(groupName);
GrCtx.setDeleteUrl(`http://${backendHost}/groups/delete/${groupId}`);
};

const openCollapsible = (groupId, page) => {
setOpenedGroupId(groupId)
const opened = {};
opened[groupId] = true;
setOpenedGroups(prev => {
for (const prop in prev){
prev[prop] = false;
}
return {...prev, ...opened}}
);

// If last item from from current page was deleted, page variable
// must be decreased. To do this first we calculate current number
// of pages and then we load devices for this page.
axios.get(`http://${backendHost}/group/${groupId}/devices/count`)
.then((response) => {
let maxPages = Math.ceil(response.data/Number(devicesPerPage));
if (maxPages === 0) maxPages = 1;
if (page > maxPages){
page = maxPages;
};
axios.get(`http://${backendHost}/group/${groupId}/devices/${page}/${devicesPerPage.toString()}`)
.then((response2) => {
GrCtx.setDevices(response2.data);
setPageNum(page);
setTotalPages(maxPages);
})
});
}

const closeCollapsible = (groupId) => {
const opened = {};
opened[groupId] = false;
setOpenedGroups(prev => {return {...prev, ...opened}});
GrCtx.setDevices([]);
}

const handleRowClick = (row, groupId) => {
GrCtx.setButtonsOpen(true);
GrCtx.setIsDeviceEdit(true);
GrCtx.setDeleteName(`${row.address}:${row.port}`)
GrCtx.setGroupId(groupId);
GrCtx.setDeviceId(row._id);
GrCtx.setAddress(row.address);
GrCtx.setPort(row.port);
GrCtx.setVersion(row.version);
GrCtx.setCommunity(row.community);
GrCtx.setSecret(row.secret);
GrCtx.setSecurityEngine(row.securityEngine);
};

const handlePagination = (page, groupId) => {
openCollapsible(groupId, page);
};

const handleDevicesPerPage = (e, { value }) => {
setDevicesPerPage(value);
setPageNum(1);
GrCtx.makeGroupsChange();
};

const buttonsRequestDeleteDevice = (context) => {
context.setButtonsOpen(false);
context.setDeleteUrl(`http://${backendHost}/devices/delete/${GrCtx.deviceId}`)
context.setDeleteOpen(true);
};

const buttonsRequestEditDevice = (context) => {
context.setButtonsOpen(false);
context.setAddDeviceOpen(true);
};

const deleteModalRequest = (context) => {
axios.post(context.deleteUrl)
.then(function (response) {
if ('message' in response.data){
ErrCtx.setOpen(true);
ErrCtx.setMessage(response.data.message);
}
context.makeGroupsChange();
})
.catch(function (error) {
console.log(error);
context.makeGroupsChange();
});
context.setDeleteOpen(false);
context.resetDevice();
context.setDeleteUrl('');
context.setEditedGroupId(GrCtx.groupId)
context.addGroupModalToggle?.current?.focus();
};

const groupsList = groups.map((group) => (
<CollapsiblePanel title={group.groupName} key={createDOMID()} open={openedGroups[group._id]} onRequestOpen={() => {openCollapsible(group._id, 1, DEVICES_PER_PAGE)}}
onRequestClose={() => {closeCollapsible(group._id)}}>
<Button onClick={() => (newDeviceButtonHandler(group._id, group.groupName))} label="Add new device"/>
<Button onClick={() => (editGroupButtonHandler(group._id, group.groupName))} label="Edit group name"/>
<Button onClick={() => (deleteGroupButtonHandler(group._id, group.groupName))} label="Delete group"/>
<Table stripeRows>
<Table.Head>
<Table.HeadCell>Address</Table.HeadCell>
<Table.HeadCell>Port</Table.HeadCell>
<Table.HeadCell>Community</Table.HeadCell>
<Table.HeadCell>Secret</Table.HeadCell>
<Table.HeadCell>Version</Table.HeadCell>
<Table.HeadCell>Security Engine</Table.HeadCell>
</Table.Head>
<Table.Body>
{GrCtx.devices.map((row) => (
<Table.Row key={createDOMID()} onClick={() => handleRowClick(JSON.parse(JSON.stringify(row)), group._id)}>
<Table.Cell>{row.address}</Table.Cell>
<Table.Cell>{row.port}</Table.Cell>
<Table.Cell>{row.community}</Table.Cell>
<Table.Cell>{row.secret}</Table.Cell>
<Table.Cell>{row.version}</Table.Cell>
<Table.Cell>{row.securityEngine}</Table.Cell>
</Table.Row>
))}

</Table.Body>
</Table>
<Paginator
onChange={(event, { page }) => (handlePagination(page, group._id))}
current={pageNum}
alwaysShowLastPageLink
totalPages={totalPages}
/>
</CollapsiblePanel>
))

return (
<div>
<ControlGroup label={"Number of devices per page"} labelPosition="top">
<Select value={devicesPerPage} onChange={handleDevicesPerPage} defaultValue={"3"}>
<Select.Option label="3" value="3" />
<Select.Option label="10" value="10" />
<Select.Option label="50" value="50" />
<Select.Option label="100" value="100" />
<Select.Option label="200" value="200" />
</Select>
</ControlGroup>
{groupsList}
<AddDeviceModal />
<ButtonsModal handleRequestDelete={() => (buttonsRequestDeleteDevice(GrCtx))}
handleRequestEdit={() => (buttonsRequestEditDevice(GrCtx))}
context={GrCtx}/>
<DeleteModal deleteName={GrCtx.deleteName}
handleDelete={() => (deleteModalRequest(GrCtx))}/>

</div>
);
}

export default GroupsList;
92 changes: 37 additions & 55 deletions frontend/packages/manager/src/components/groups/GroupsList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import Select from '@splunk/react-ui/Select';
import ControlGroup from '@splunk/react-ui/ControlGroup';
import { backendHost } from "../../host";
import ErrorsModalContext from "../../store/errors-modal-contxt";
import Plus from '@splunk/react-icons/Plus';
import Trash from '@splunk/react-icons/Trash';
import Pencil from '@splunk/react-icons/Pencil';
import { GroupsContent, GroupsNames, GroupsNamesHeader, SingleGroup, GroupDevices } from "../../styles/groups/GroupsStyle";



function GroupsList() {
Expand Down Expand Up @@ -57,6 +62,13 @@ function GroupsList() {
setPageNum(1);
}, [openedGroupId]);

const handleRequestOpenGroups = () => {
GrCtx.setAddGroupOpen(true);
GrCtx.setIsGroupEdit(false);
GrCtx.setGroupName('');
GrCtx.setGroupId(null);
};

const editGroupButtonHandler = (groupId, groupName) => {
GrCtx.setGroupId(groupId);
GrCtx.setGroupName(groupName);
Expand Down Expand Up @@ -173,63 +185,33 @@ function GroupsList() {
};

const groupsList = groups.map((group) => (
<CollapsiblePanel title={group.groupName} key={createDOMID()} open={openedGroups[group._id]} onRequestOpen={() => {openCollapsible(group._id, 1, DEVICES_PER_PAGE)}}
onRequestClose={() => {closeCollapsible(group._id)}}>
<Button onClick={() => (newDeviceButtonHandler(group._id, group.groupName))} label="Add new device"/>
<Button onClick={() => (editGroupButtonHandler(group._id, group.groupName))} label="Edit group name"/>
<Button onClick={() => (deleteGroupButtonHandler(group._id, group.groupName))} label="Delete group"/>
<Table stripeRows>
<Table.Head>
<Table.HeadCell>Address</Table.HeadCell>
<Table.HeadCell>Port</Table.HeadCell>
<Table.HeadCell>Community</Table.HeadCell>
<Table.HeadCell>Secret</Table.HeadCell>
<Table.HeadCell>Version</Table.HeadCell>
<Table.HeadCell>Security Engine</Table.HeadCell>
</Table.Head>
<Table.Body>
{GrCtx.devices.map((row) => (
<Table.Row key={createDOMID()} onClick={() => handleRowClick(JSON.parse(JSON.stringify(row)), group._id)}>
<Table.Cell>{row.address}</Table.Cell>
<Table.Cell>{row.port}</Table.Cell>
<Table.Cell>{row.community}</Table.Cell>
<Table.Cell>{row.secret}</Table.Cell>
<Table.Cell>{row.version}</Table.Cell>
<Table.Cell>{row.securityEngine}</Table.Cell>
</Table.Row>
))}

</Table.Body>
</Table>
<Paginator
onChange={(event, { page }) => (handlePagination(page, group._id))}
current={pageNum}
alwaysShowLastPageLink
totalPages={totalPages}
/>
</CollapsiblePanel>
))
<SingleGroup key={createDOMID()}>
<P>
{group.groupName}
</P>
<div>
<Button style={{ margin: "0" }} onClick={() => console.log("dodaj device")} appearance="pill" icon={<Plus />} />
<Button style={{ margin: "0" }} onClick={() => (editGroupButtonHandler(group._id, group.groupName))} appearance="pill" icon={<Pencil />} />
<Button style={{ margin: "0" }} onClick={() => (deleteGroupButtonHandler(group._id, group.groupName))} appearance="pill" icon={<Trash />} />
</div>
</SingleGroup>
));

return (
<div>
<ControlGroup label={"Number of devices per page"} labelPosition="top">
<Select value={devicesPerPage} onChange={handleDevicesPerPage} defaultValue={"3"}>
<Select.Option label="3" value="3" />
<Select.Option label="10" value="10" />
<Select.Option label="50" value="50" />
<Select.Option label="100" value="100" />
<Select.Option label="200" value="200" />
</Select>
</ControlGroup>
{groupsList}
<AddDeviceModal />
<ButtonsModal handleRequestDelete={() => (buttonsRequestDeleteDevice(GrCtx))}
handleRequestEdit={() => (buttonsRequestEditDevice(GrCtx))}
context={GrCtx}/>
<DeleteModal deleteName={GrCtx.deleteName}
handleDelete={() => (deleteModalRequest(GrCtx))}/>

</div>
<GroupsContent>
<GroupsNames>
<GroupsNamesHeader>
<P>Group name</P>
<div>
<Button onClick={handleRequestOpenGroups} appearance="pill" icon={<Plus />} />
</div>
</GroupsNamesHeader>
{groupsList}
</GroupsNames>
<GroupDevices>
TEST
</GroupDevices>
</GroupsContent>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { backendHost } from "../../host";
import Trash from '@splunk/react-icons/Trash';
import Pencil from '@splunk/react-icons/Pencil';
import Button from '@splunk/react-ui/Button';
import { Pagination, StyledRow } from '../../styles/inventory/InventoryStyle';
import { Pagination } from '../../styles/inventory/InventoryStyle';


const columns = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import { ProfilesValidationContxtProvider } from "../../store/profiles-validatio

function TabPanels(){
const MenuCtx = useContext(MenuHeaderContxt);
let padding = MenuCtx.activeTabId != "Groups" ? "20px" : "0";

return(
<div style={{ width: "100%", paddingLeft: "20px", paddingRight: "20px", boxSizing: "border-box"}}>
<div style={{ width: "100%", paddingLeft: padding, paddingRight: padding, height: "100vh", boxSizing: "border-box"}}>
{
MenuCtx.activeTabId == "Profiles" ?
<ProfilesValidationContxtProvider>
Expand Down
2 changes: 1 addition & 1 deletion frontend/packages/manager/src/pages/GroupsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import GroupContext from "../store/group-contxt";
function GroupsPage() {

return (
<div>
<div style={{ height: "100%"}}>
<GroupsList/>
<AddGroupModal />
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/packages/manager/src/store/menu-header-contxt.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, {useState, createContext, useRef, useContext} from 'react';
const MenuHeaderContxt = createContext();

export function MenuHeaderContxtProvider(props){
const [activeTabId, setActiveTabId] = useState('Profiles');
const [activeTabId, setActiveTabId] = useState('Groups');

const context = {
activeTabId: activeTabId,
Expand Down
Loading

0 comments on commit 1bb9e10

Please sign in to comment.