Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion visualization_tool/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ function App() {
const [searchQuery, setSearchQuery] = useState<string>('');
const [sortAttribute, setSortAttribute] = useState<string>('date');
const [resources, setResources] = useState<Resource[]>([]);
const [projects, setProjects] = useState<string[]>([]);
const [allowedProjects, setAllowedProjects] = useState<string[]>(projects);
const [allowedTypes, setAllowedTypes] = useState<string[]>(
availableResourceTypes
);
Expand All @@ -22,9 +24,12 @@ function App() {
<Navbar searchQuery={searchQuery} setSearchQuery={setSearchQuery} />
<ControlMenu
setResources={setResources}
setProjects={setProjects}
setSortAttribute={setSortAttribute}
setAllowedTypes={setAllowedTypes}
setRoles={setRoles}
projects={projects}
setAllowedProjects={setAllowedProjects}
/>
<Routes>
<Route
Expand All @@ -35,12 +40,19 @@ function App() {
searchQuery={searchQuery}
sortAttribute={sortAttribute}
allowedTypes={allowedTypes}
allowedProjects={allowedProjects}
/>
}
/>
<Route
path="/static/iam-policy"
element={<IAMPolicyPage roles={roles} emailQuery={searchQuery} />}
element={
<IAMPolicyPage
roles={roles}
emailQuery={searchQuery}
allowedProjects={allowedProjects}
/>
}
/>
</Routes>
</>
Expand Down
11 changes: 7 additions & 4 deletions visualization_tool/src/components/ControlMenu/ControlMenu.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
.control-menu-container {
position: fixed;
}

.control-menu {
background-color: #f8f9fc;
position: fixed;
height: 100%;
width: 350px;
padding-block: 30px;
padding-inline: 20px;

display: flex;
flex-direction: column;
align-items: center;
height: calc(100vh - 70px);
overflow-y: auto;
}

.menu-item {
Expand Down Expand Up @@ -41,6 +43,7 @@
.menu-item h3 {
font-weight: 400;
font-size: 18px;
margin-bottom: 5px;
}

.menu-item img {
Expand Down
34 changes: 26 additions & 8 deletions visualization_tool/src/components/ControlMenu/ControlMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {useLocation} from 'react-router-dom';
import UploadMenu from './partials/UploadMenu';
import SortMenu from './partials/SortMenu';
import FilterMenu from './partials/FilterMenu';
import FilterProjects from './partials/FilterProjects';

import {Resource} from '../../types/resources';
import {IAMRole} from '../../types/IAMPolicy';
Expand All @@ -14,25 +15,42 @@ type ControlMenuProps = {
setSortAttribute: React.Dispatch<React.SetStateAction<string>>;
setAllowedTypes: React.Dispatch<React.SetStateAction<string[]>>;
setRoles: React.Dispatch<React.SetStateAction<IAMRole[]>>;
projects: string[];
setProjects: React.Dispatch<React.SetStateAction<string[]>>;
setAllowedProjects: React.Dispatch<React.SetStateAction<string[]>>;
};

const ControlMenu = ({
setResources,
setSortAttribute,
setAllowedTypes,
setRoles,
projects,
setProjects,
setAllowedProjects,
}: ControlMenuProps) => {
const location = useLocation();

return (
<div className="control-menu">
<UploadMenu setResources={setResources} setRoles={setRoles} />
{location.pathname === '/static/' && (
<>
<SortMenu setSortAttribute={setSortAttribute} />
<FilterMenu setAllowedTypes={setAllowedTypes} />
</>
)}
<div className="control-menu-container">
<div className="control-menu">
<UploadMenu
setResources={setResources}
setRoles={setRoles}
setProjects={setProjects}
setAllowedProjects={setAllowedProjects}
/>
<FilterProjects
projects={projects}
setAllowedProjects={setAllowedProjects}
/>
{location.pathname === '/static/' && (
<>
<SortMenu setSortAttribute={setSortAttribute} />
<FilterMenu setAllowedTypes={setAllowedTypes} />
</>
)}
</div>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
type FilterProjectsProps = {
projects: string[];
setAllowedProjects: React.Dispatch<React.SetStateAction<string[]>>;
};

const FilterProjects = ({
projects,
setAllowedProjects,
}: FilterProjectsProps) => {
return (
<div className="menu-item">
<div className="menu-item__header">
<span>
<img src="./icons/filter.png" alt="" />
</span>
<h3>Projects</h3>
</div>
{projects.length > 0 && (
<div className="menu-item__content">
{projects.map(project => {
return (
<div key={project}>
<input
type="checkbox"
name="resource-type"
id={project}
defaultChecked
onChange={e => {
if (e.target.checked) {
setAllowedProjects(prevProjects => [
...prevProjects,
project,
]);
} else {
setAllowedProjects(prevProjects => {
return prevProjects.filter(
prevProject => prevProject !== project
);
});
}
}}
/>
<label htmlFor={project}>{project}</label>
</div>
);
})}
</div>
)}
</div>
);
};

export default FilterProjects;
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,23 @@ import {parseData, parseIAMData} from '../Controller';
type UploadMenuProps = {
setResources: React.Dispatch<React.SetStateAction<Resource[]>>;
setRoles: React.Dispatch<React.SetStateAction<IAMRole[]>>;
setProjects: React.Dispatch<React.SetStateAction<string[]>>;
setAllowedProjects: React.Dispatch<React.SetStateAction<string[]>>;
};

const UploadMenu = ({setResources, setRoles}: UploadMenuProps) => {
type File = {
name: string;
projects: string[];
};

const UploadMenu = ({
setResources,
setRoles,
setProjects,
setAllowedProjects,
}: UploadMenuProps) => {
const fileInput = useRef<HTMLInputElement>(null);
const [files, setFiles] = useState<string[]>([]);
const [files, setFiles] = useState<File[]>([]);
const [error, setError] = useState<string | null>(null);
return (
<div className="menu-item">
Expand All @@ -35,7 +47,7 @@ const UploadMenu = ({setResources, setRoles}: UploadMenuProps) => {
return;
}
// check if file is already uploaded
if (files.includes(file.name)) {
if (files.find(prevFile => prevFile.name === file.name)) {
setError('File already uploaded');
return;
}
Expand All @@ -47,6 +59,14 @@ const UploadMenu = ({setResources, setRoles}: UploadMenuProps) => {

try {
const data = JSON.parse(result);
setProjects(prevProjects => [
...prevProjects,
...Object.keys(data.projects),
]);
setAllowedProjects(prevProjects => [
...prevProjects,
...Object.keys(data.projects),
]);
const resources = parseData(data, file.name);
setResources((prevResources: Resource[]) => [
...prevResources,
Expand All @@ -56,7 +76,10 @@ const UploadMenu = ({setResources, setRoles}: UploadMenuProps) => {
const roles = parseIAMData(data, file.name);
setRoles((prevRoles: IAMRole[]) => [...prevRoles, ...roles]);

setFiles([...files, file.name]);
setFiles([
...files,
{name: file.name, projects: Object.keys(data.projects)},
]);
} catch (err) {
setError('Invalid file');
return;
Expand Down Expand Up @@ -85,21 +108,32 @@ const UploadMenu = ({setResources, setRoles}: UploadMenuProps) => {
{files.length > 0 && (
<div className="files-list">
{files.map(file => (
<div className="file-item" key={file}>
<p>{file}</p>
<div className="file-item" key={file.name}>
<p>{file.name}</p>
<button
className="remove-button"
onClick={() => {
setFiles(prevFiles => {
return prevFiles.filter(prevFile => prevFile !== file);
return prevFiles.filter(
prevFile => prevFile.name !== file.name
);
});

setProjects(prevProjects => {
return prevProjects.filter(
prevProject => !file.projects.includes(prevProject)
);
});

setResources(prevResources => {
return prevResources.filter(
prevResource => prevResource.file !== file
prevResource => prevResource.file !== file.name
);
});
setRoles(prevRoles => {
return prevRoles.filter(prevRole => prevRole.file !== file);
return prevRoles.filter(
prevRole => prevRole.file !== file.name
);
});
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,22 @@ type ResourcesListProps = {
searchQuery: string;
sortAttribute: string;
allowedTypes: string[];
allowedProjects: string[];
};

const ResourcesList = ({
resources,
searchQuery,
sortAttribute,
allowedTypes,
allowedProjects,
}: ResourcesListProps) => {
const filteredResources = useFilter(
resources,
searchQuery,
sortAttribute,
allowedTypes
allowedTypes,
allowedProjects
);
const [selectedResource, setSelectedResource] = useState<Resource | null>(
null
Expand Down
8 changes: 5 additions & 3 deletions visualization_tool/src/components/ResourcesList/useFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export const useFilter = (
resources: Resource[],
searchQuery: string,
sortAttribute: string,
allowedTypes: string[]
allowedTypes: string[],
allowedProjects: string[]
) => {
const [filteredResources, setFilteredResources] =
useState<Resource[]>(resources);
Expand All @@ -18,7 +19,8 @@ export const useFilter = (
.filter(resource => {
return (
allowedTypes.includes(resource.type) &&
resource.name.toLowerCase().includes(searchQuery.toLowerCase())
resource.name.toLowerCase().includes(searchQuery.toLowerCase()) &&
allowedProjects.includes(resource.projectId)
);
})
.sort((a, b) => {
Expand All @@ -35,7 +37,7 @@ export const useFilter = (
};

debounce(filterResources, 100)();
}, [resources, searchQuery, sortAttribute, allowedTypes]);
}, [resources, searchQuery, sortAttribute, allowedTypes, allowedProjects]);

return filteredResources;
};
5 changes: 3 additions & 2 deletions visualization_tool/src/components/RolesList/RolesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import './RolesList.css';
type RolesListProps = {
roles: IAMRole[];
emailQuery: string;
allowedProjects: string[];
};

const RolesList = ({roles, emailQuery}: RolesListProps) => {
const filteredRoles = useFilter(roles, emailQuery);
const RolesList = ({roles, emailQuery, allowedProjects}: RolesListProps) => {
const filteredRoles = useFilter(roles, emailQuery, allowedProjects);
// console.log(filteredRoles);

return (
Expand Down
14 changes: 10 additions & 4 deletions visualization_tool/src/components/RolesList/useFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@ import {useEffect, useState} from 'react';
import {IAMRole} from '../../types/IAMPolicy';
import {debounce} from '@mui/material';

export const useFilter = (roles: IAMRole[], email: string) => {
export const useFilter = (
roles: IAMRole[],
email: string,
allowedProjects: string[]
) => {
const [filteredRoles, setFilteredRoles] = useState<IAMRole[]>(roles);

useEffect(() => {
const filterRoles = () => {
setFilteredRoles(
roles.filter(role => {
// check if this email is in the role's members
return role.members.some(member => member.email.includes(email));
return (
role.members.some(member => member.email.includes(email)) &&
allowedProjects.includes(role.projectId)
);
})
);
};

debounce(filterRoles, 200)();
}, [roles, email]);
}, [roles, email, allowedProjects]);

return filteredRoles;
};
Loading