+ {user.id} |
{userRoleError ? (
'Error'
@@ -319,13 +223,19 @@ const RoleTd: FC = (props) => {
-
|
@@ -343,7 +253,7 @@ const RoleTd: FC = (props) => {
onChange={(e) => {
setUserInput(e.target.value);
}}
- placeholder={`Please enter the Username to confirm, i.e. ${Username}`}
+ placeholder={`Please enter the user to confirm, i.e. ${user.id}`}
required
/>
@@ -352,7 +262,7 @@ const RoleTd: FC = (props) => {
variant="filled"
color="gray"
className={classes.modalActionBtn}
- disabled={UserInput === Username ? false : true}
+ disabled={UserInput === user.id ? false : true}
onClick={handleDelete}>
Delete
@@ -361,7 +271,7 @@ const RoleTd: FC = (props) => {
- {userRole && userRole[deleteRoleIndex] ? (
+ {userRole && deleteRole && userRole[deleteRole] ? (
= (props) => {
centered
className={classes.modalStyle}>
- {getBadge(userRole[deleteRoleIndex], deleteRoleIndex, false)}
+ {getBadge(deleteRole, false)}
{
setUserInput(e.target.value);
}}
- placeholder={`Please enter the Username to confirm, i.e. ${Username}`}
+ placeholder={`Please enter the user to confirm, i.e. ${user.id}`}
required
/>
@@ -388,7 +298,7 @@ const RoleTd: FC = (props) => {
variant="filled"
color="gray"
className={classes.modalActionBtn}
- disabled={UserInput === Username ? false : true}
+ disabled={UserInput === user.id ? false : true}
onClick={handleRoleDelete}>
Delete
@@ -411,7 +321,7 @@ const RoleTd: FC = (props) => {
{
setUserInput(e.target.value);
}}
@@ -443,14 +353,16 @@ const RoleTd: FC = (props) => {
)}
-
+ disabled={UserInput === user.id ? false : true}>
Reset Password
-
+ ):(
+ Cannot reset password for this user
+ )}
Cancel
@@ -464,62 +376,34 @@ const RoleTd: FC = (props) => {
className={classes.modalStyle}>
-
+
+
{
- handleRoleEdit();
- }}
- disabled={updateRoleVaildtion()}>
- Add Role
+ onClick={handleEditUserRole}
+ //if role is already assigned or no role is selected then disable the button
+ disabled={userRole && (Object.keys(userRole).includes(SelectedRole) || SelectedRole === '') ? true : false}
+ >
+ Create
Cancel
@@ -530,4 +414,4 @@ const RoleTd: FC = (props) => {
);
};
-export default RoleTd;
+export default RoleTR;
diff --git a/src/pages/Users/index.tsx b/src/pages/AccessManagement/Roles.tsx
similarity index 70%
rename from src/pages/Users/index.tsx
rename to src/pages/AccessManagement/Roles.tsx
index e24fabb3..d2c972e2 100644
--- a/src/pages/Users/index.tsx
+++ b/src/pages/AccessManagement/Roles.tsx
@@ -1,15 +1,14 @@
-import { Box, Button, Group, Modal, ScrollArea, Select, Stack, Table, Text, TextInput } from '@mantine/core';
+import { Box, Button, Group, Modal, ScrollArea, Select, Stack, Table, Text, TextInput, px } from '@mantine/core';
import { useDocumentTitle } from '@mantine/hooks';
import { FC, useEffect, useState } from 'react';
-
-import { useGetUsers } from '@/hooks/useGetUsers';
import { useUsersStyles } from './styles';
-import { usePostUser } from '@/hooks/usePostUser';
-import { Prism } from '@mantine/prism';
-import RoleTd from './row';
import { useGetLogStreamList } from '@/hooks/useGetLogStreamList';
import { useHeaderContext } from '@/layouts/MainLayout/Context';
-const Users: FC = () => {
+import { useGetRoles } from '@/hooks/useGetRoles';
+import PrivilegeTR from './PrivilegeTR';
+import { IconUserPlus } from '@tabler/icons-react';
+import { usePutRole } from '@/hooks/usePutRole';
+const Roles: FC = () => {
useDocumentTitle('Parseable | Users');
const {
state: { subCreateUserModalTogle },
@@ -23,7 +22,7 @@ const Users: FC = () => {
}, [subCreateUserModalTogle.get()]);
const [modalOpen, setModalOpen] = useState(false);
- const [createUserInput, setCreateUserInput] = useState('');
+ const [createRoleInput, setCreateRoleInput] = useState('');
const [tagInput, setTagInput] = useState('');
const [selectedPrivilege, setSelectedPrivilege] = useState('');
const [SelectedStream, setSelectedStream] = useState('');
@@ -31,61 +30,55 @@ const Users: FC = () => {
const { data: streams } = useGetLogStreamList();
- const {
- data: CreatedUserResponse,
- error: CreatedUserError,
- loading: CreatedUserLoading,
- createUser,
- resetData: resetCreateUser,
- } = usePostUser();
- const { data: users, error: usersError, loading: usersLoading, getUsersList, resetData: usersReset } = useGetUsers();
+ const { data: CreatedRoleResponse, putRolePrivilege, resetData: resetCreateRoleData } = usePutRole();
+ const { data: roles, error: rolesError, loading: rolesLoading, getRolesList, resetData: rolesReset } = useGetRoles();
const [tableRows, setTableRows] = useState([]);
useEffect(() => {
- getUsersList();
+ getRolesList();
return () => {
- usersReset();
+ rolesReset();
};
}, []);
useEffect(() => {
- if (users) {
+ if (roles) {
const getrows = async () => {
- let rows = users.map((user: any) => {
- return ;
+ let rows = roles.map((role: any) => {
+ return ;
});
setTableRows(rows);
};
getrows();
}
- if (usersError) {
+ if (rolesError) {
setTableRows(
error |
,
);
}
- if (usersLoading) {
+ if (rolesLoading) {
setTableRows(
loading |
,
);
}
- }, [users, usersError, usersLoading]);
+ }, [roles, rolesError, rolesLoading]);
useEffect(() => {
- if (CreatedUserResponse) {
- getUsersList();
+ if (CreatedRoleResponse) {
+ getRolesList();
}
- }, [CreatedUserResponse]);
+ }, [CreatedRoleResponse]);
const handleClose = () => {
- setCreateUserInput('');
+ setCreateRoleInput('');
setModalOpen(false);
- resetCreateUser();
+ resetCreateRoleData();
setSelectedPrivilege('');
setSelectedStream('');
setStreamSearchValue('');
@@ -119,11 +112,12 @@ const Users: FC = () => {
}
}
}
- createUser(createUserInput, userRole);
+ putRolePrivilege(createRoleInput, userRole);
+ handleClose();
};
const createVaildtion = () => {
- if (users?.includes(createUserInput) || createUserInput.length < 3) {
+ if (roles?.includes(createRoleInput) && createRoleInput.length > 0) {
return true;
}
if (selectedPrivilege !== '') {
@@ -149,14 +143,28 @@ const Users: FC = () => {
const { classes } = useUsersStyles();
return (
+
+
+ Roles
+
+ {
+ setModalOpen(true);
+ }}
+ rightIcon={}>
+ Create Role
+
+
- Username |
Role |
+ Access |
Delete |
- Reset Password |
{tableRows}
@@ -166,12 +174,12 @@ const Users: FC = () => {
{
- setCreateUserInput(e.target.value);
+ setCreateRoleInput(e.target.value);
}}
- value={createUserInput}
+ value={createRoleInput}
required
/>
{
) : (
''
)}
-
- {CreatedUserError ? (
-
- {CreatedUserError}
-
- ) : CreatedUserLoading ? (
- loading
- ) : CreatedUserResponse ? (
-
- Password
-
- {CreatedUserResponse}
-
-
- Warning this is the only time you are able to see Password
-
-
- ) : (
- ''
- )}
@@ -250,8 +234,8 @@ const Users: FC = () => {
variant="filled"
color="gray"
className={classes.modalActionBtn}
- onClick={handleCreateUser}
- disabled={createVaildtion()}>
+ disabled={createVaildtion()}
+ onClick={handleCreateUser}>
Create
@@ -263,4 +247,4 @@ const Users: FC = () => {
);
};
-export default Users;
+export default Roles;
diff --git a/src/pages/AccessManagement/Users.tsx b/src/pages/AccessManagement/Users.tsx
new file mode 100644
index 00000000..0e5cd318
--- /dev/null
+++ b/src/pages/AccessManagement/Users.tsx
@@ -0,0 +1,218 @@
+import { Box, Button, Group, Modal, ScrollArea, Select, Stack, Table, Text, TextInput, px } from '@mantine/core';
+import { useDocumentTitle } from '@mantine/hooks';
+import { FC, useEffect, useState } from 'react';
+
+import { useGetUsers } from '@/hooks/useGetUsers';
+import { useUsersStyles } from './styles';
+import { usePostUser } from '@/hooks/usePostUser';
+import { Prism } from '@mantine/prism';
+
+import { useHeaderContext } from '@/layouts/MainLayout/Context';
+import RoleTR from './RoleTR';
+import { IconUserPlus } from '@tabler/icons-react';
+import { useGetRoles } from '@/hooks/useGetRoles';
+const Users: FC = () => {
+ useDocumentTitle('Parseable | Users');
+ const {
+ state: { subCreateUserModalTogle },
+ } = useHeaderContext();
+
+ useEffect(() => {
+ const listener = subCreateUserModalTogle.subscribe(setModalOpen);
+ return () => {
+ listener();
+ };
+ }, [subCreateUserModalTogle.get()]);
+
+ const [modalOpen, setModalOpen] = useState(false);
+ const [createUserInput, setCreateUserInput] = useState('');
+ const [SelectedRole, setSelectedRole] = useState('');
+ const [roleSearchValue, setRoleSearchValue] = useState('');
+ const [tableRows, setTableRows] = useState([]);
+ const {
+ data: CreatedUserResponse,
+ error: CreatedUserError,
+ loading: CreatedUserLoading,
+ createUser,
+ resetData: resetCreateUser,
+ } = usePostUser();
+ const { data: users, error: usersError, loading: usersLoading, getUsersList, resetData: usersReset } = useGetUsers();
+ const { data: roles, getRolesList, resetData: rolesReset } = useGetRoles();
+
+ useEffect(() => {
+ getUsersList();
+ getRolesList();
+ return () => {
+ usersReset();
+ rolesReset();
+ };
+ }, []);
+
+ useEffect(() => {
+ if (users) {
+ const getrows = async () => {
+ let rows = users.map((user: any) => {
+ return ;
+ });
+ setTableRows(rows);
+ };
+
+ getrows();
+ }
+ if (usersError ) {
+ setTableRows(
+
+ error |
+ ,
+ );
+ }
+ if (usersLoading ) {
+ setTableRows(
+
+ loading |
+ ,
+ );
+ }
+ }, [users, usersError, usersLoading]);
+
+ useEffect(() => {
+ if (CreatedUserResponse) {
+ getUsersList();
+ }
+ }, [CreatedUserResponse]);
+
+ const handleClose = () => {
+ setCreateUserInput('');
+ setModalOpen(false);
+ resetCreateUser();
+ setSelectedRole('');
+ setRoleSearchValue('');
+ };
+
+ const handleCreateUser = () => {
+ let userRole: any = [];
+ if (SelectedRole !== '') {
+ userRole.push(SelectedRole);
+ }
+ createUser(createUserInput, userRole);
+ };
+
+ const createVaildtion = () => {
+ if (users?.includes(createUserInput) || createUserInput.length < 3) {
+ return true;
+ }
+
+ if (SelectedRole !== '') {
+ if (roles?.includes(SelectedRole)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ };
+
+ const { classes } = useUsersStyles();
+ return (
+
+
+
+ Users
+
+ {
+ setModalOpen(true);
+ }}
+ rightIcon={}>
+ Create Users
+
+
+
+
+
+
+ Username |
+ Role |
+ Delete |
+ Reset Password |
+
+
+ {tableRows}
+
+
+
+
+ {
+ setCreateUserInput(e.target.value);
+ }}
+ value={createUserInput}
+ required
+ />
+
+ {
+ setSelectedRole(value ?? '');
+ }}
+ nothingFound="No roles found"
+ value={SelectedRole}
+ searchValue={roleSearchValue}
+ onSearchChange={(value) => setRoleSearchValue(value)}
+ onDropdownClose={() => setRoleSearchValue(SelectedRole)}
+ onDropdownOpen={() => setRoleSearchValue('')}
+ data={roles}
+ searchable
+ label="Select a role to assign"
+ required
+ />
+
+ {CreatedUserError ? (
+
+ {CreatedUserError}
+
+ ) : CreatedUserLoading ? (
+ loading
+ ) : CreatedUserResponse ? (
+
+ Password
+
+ {CreatedUserResponse}
+
+
+ Warning this is the only time you are able to see Password
+
+
+ ) : (
+ ''
+ )}
+
+
+
+
+ Create
+
+
+ Cancel
+
+
+
+
+ );
+};
+
+export default Users;
diff --git a/src/pages/AccessManagement/index.tsx b/src/pages/AccessManagement/index.tsx
new file mode 100644
index 00000000..f0d45578
--- /dev/null
+++ b/src/pages/AccessManagement/index.tsx
@@ -0,0 +1,18 @@
+import { Box } from '@mantine/core';
+import { FC } from 'react';
+import Users from './Users';
+import Roles from './Roles';
+
+const AccessMangement: FC = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default AccessMangement;
diff --git a/src/pages/Users/styles.tsx b/src/pages/AccessManagement/styles.tsx
similarity index 76%
rename from src/pages/Users/styles.tsx
rename to src/pages/AccessManagement/styles.tsx
index 9bfc96c9..86ec285f 100644
--- a/src/pages/Users/styles.tsx
+++ b/src/pages/AccessManagement/styles.tsx
@@ -1,15 +1,35 @@
-import { NAVBAR_WIDTH } from '@/constants/theme';
import { createStyles } from '@mantine/core';
export const useUsersStyles = createStyles((theme) => {
- const { spacing, colors } = theme;
- const { widths } = theme.other;
+ const { spacing,radius, colors } = theme;
const sColor = colors.brandSecondary[0];
+ const defaultRadius = radius[theme.defaultRadius as string];
+
return {
container: {
flex: 1,
- width: `calc(${widths.full} - ${NAVBAR_WIDTH}px)`,
+ width:"100%",
position: 'relative',
+ margin: '10px',
+ borderRadius: defaultRadius,
+ border: `1px solid ${colors.gray[2]}`,
},
+ header: {
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ padding: '20px',
+ borderBottom: `1px solid ${colors.gray[2]}`,
+ },
+
+ createBtn: {
+ height: '34px',
+ width: '150px',
+ padding: '0px',
+ marginInlineEnd: spacing.xs,
+ color: colors.gray[5],
+ borderColor: colors.gray[2],
+ },
+
actionBtn: {
'&:hover': {
color: sColor,
@@ -22,7 +42,7 @@ export const useUsersStyles = createStyles((theme) => {
borderColor: colors.gray[2],
},
tableContainer: {
- height: '100%',
+
},
tableStyle: {
overflow: 'scroll',
diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx
index 7b91a280..0671b2d8 100644
--- a/src/pages/Login/index.tsx
+++ b/src/pages/Login/index.tsx
@@ -1,11 +1,11 @@
import logo from '@/assets/images/brand/logo.svg';
import Loading from '@/components/Loading';
import { useLoginForm } from '@/hooks/useLoginForm';
-import { Box, Button, Image, PasswordInput, Text, TextInput, Transition } from '@mantine/core';
+import { Box, Button, Divider, Image, PasswordInput, Text, TextInput, Transition, rem } from '@mantine/core';
import { useDocumentTitle } from '@mantine/hooks';
import { FC } from 'react';
-import ForgotPassword from './ForgotPassword';
import { useLoginStyles } from './styles';
+const baseURL = import.meta.env.VITE_PARSEABLE_URL ?? '/';
const Login: FC = () => {
useDocumentTitle('Parseable | Login');
@@ -13,7 +13,7 @@ const Login: FC = () => {
const { getInputProps, isValid, loading, handleSubmit, error } = useLoginForm();
const { classes } = useLoginStyles();
- const { container, formContainer, titleStyle, descriptionStyle, formInput, loginBtnStyle, errorStyle } = classes;
+ const { container, formContainer, titleStyle, formInput, loginBtnStyle, errorStyle } = classes;
return (
@@ -23,11 +23,14 @@ const Login: FC = () => {
- Welcome!
+ Welcome to Parseable
-
+
+
+
+ {/*
Add your credentials to login
-
+ */}
{error && (
@@ -53,7 +56,20 @@ const Login: FC = () => {
Login
-
+
+ {/* */}
+
+
+
+
+ Login with OAuth
+
+
)}
diff --git a/src/routes/PrivateRoute.tsx b/src/routes/PrivateRoute.tsx
index 1157eae9..6d1ee552 100644
--- a/src/routes/PrivateRoute.tsx
+++ b/src/routes/PrivateRoute.tsx
@@ -1,11 +1,11 @@
import { LOGIN_ROUTE } from '@/constants/routes';
-import { useLocalStorage } from '@mantine/hooks';
import type { FC } from 'react';
import { Navigate, Outlet, useLocation } from 'react-router-dom';
+import Cookies from 'js-cookie';
-const PrivateRoute: FC = () => {
- const [auth] = useLocalStorage({ key: 'credentials', getInitialValueInEffect: false });
+const PrivateRoute: FC = () => {
+ const auth = Cookies.get('session')
const { pathname } = useLocation();
return auth ? (
diff --git a/src/routes/elements.tsx b/src/routes/elements.tsx
index 1f510bbe..43457dbf 100644
--- a/src/routes/elements.tsx
+++ b/src/routes/elements.tsx
@@ -70,7 +70,7 @@ export const ConfigElement: FC = () => {
);
};
-const Users = lazy(() => import('@/pages/Users'));
+const Users = lazy(() => import('@/pages/AccessManagement'));
export const UsersElement: FC = () => {
return (
@@ -78,4 +78,4 @@ export const UsersElement: FC = () => {
);
-}
\ No newline at end of file
+};
|