Skip to content
Open
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
2 changes: 2 additions & 0 deletions schematics/application/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import expectedCloudJanushFiles from "@janush-schematics/cloud/janush/data/expec
import expectedCloudTemplateFiles from "@janush-schematics/cloud/template/data/expectedNewFiles.json";
// Web files
import expectedWebAuthFiles from "@janush-schematics/web/authentication/data/expectedNewFiles.json";
import expectedWebUserManagementFiles from "@janush-schematics/web/authentication/userManagement/data/expectedNewFiles.json";
import expectedWebJanushFiles from "@janush-schematics/web/janush/data/expectedNewFiles.json";
import expectedWebTemplateFiles from "@janush-schematics/web/template/data/expectedNewFiles.json";

Expand Down Expand Up @@ -36,6 +37,7 @@ const expectedWebFiles = [
...expectedWebTemplateFiles,
...expectedWebJanushFiles,
...expectedWebAuthFiles,
...expectedWebUserManagementFiles,
];
const expectedCloudFiles = [
...expectedCloudTemplateFiles,
Expand Down
2 changes: 2 additions & 0 deletions schematics/web/authentication/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SchematicTestRunner } from "@angular-devkit/schematics/testing";
import * as path from "path";

import expectedAuthFiles from "@janush-schematics/web/authentication/data/expectedNewFiles.json";
import expectedWebUserManagementFiles from "@janush-schematics/web/authentication/userManagement/data/expectedNewFiles.json";
import expectedJanushFiles from "@janush-schematics/web/janush/data/expectedNewFiles.json";
import expectedTemplateFiles from "@janush-schematics/web/template/data/expectedNewFiles.json";
import { emptyJanush } from "@mocks/janush";
Expand All @@ -30,6 +31,7 @@ describe("web", () => {
...expectedTemplateFiles,
...expectedJanushFiles,
...expectedAuthFiles,
...expectedWebUserManagementFiles,
]);
});

Expand Down
1 change: 1 addition & 0 deletions schematics/web/authentication/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const webAuthenticationGenerator = (options: Schema): Rule => {
MergeStrategy.Default,
),
options.idP.length ? schematic(WebSchematic.IDP, options) : noop(),
options.userManagement ? schematic(WebSchematic.USER_MANAGEMENT, options) : noop(),
packageJsonExtender,
tsConfigExtender,
]);
Expand Down
6 changes: 6 additions & 0 deletions schematics/web/authentication/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
"description": "The name of the application",
"default": "janush-app"
},
"userManagement": {
"type": "boolean",
"description": "Add user management feature",
"default": true,
"x-prompt": "[WEB] Do you want add user management feature?"
},
"idP": {
"type": "array",
"description": "Sets additional identity providers for user pool.",
Expand Down
4 changes: 3 additions & 1 deletion schematics/web/authentication/schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { IdentityProviders } from "@enums/Module";
import { IdentityProviders, Module } from "@enums/Module";

import { Schema as AppSchema } from "../../application/schema";

export interface Schema extends Partial<AppSchema> {
userManagement: boolean;
idP: IdentityProviders[];
modules: Module[];
}
9 changes: 9 additions & 0 deletions schematics/web/authentication/userManagement/collection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "../../../../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"web.userManagement": {
"description": "User Management",
"factory": "./index#userManagementGenerator"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[
"/web/src/layouts/Modals/FormModalLayout/FormModalLayout.tsx",
"/web/src/layouts/UsersAdministrationLayout/UsersAdministrationLayout.tsx",
"/web/src/routing/Routes.tsx",
"/web/src/routing/paths.ts",
"/web/src/routing/routes/UsersAdministration/Groups/Groups.tsx",
"/web/src/routing/routes/UsersAdministration/Groups/GroupDetails/GroupDetails.tsx",
"/web/src/routing/routes/UsersAdministration/Groups/GroupsTable/GroupsTable.tsx",
"/web/src/routing/routes/UsersAdministration/Groups/Modals/AddToGroupModal/AddToGroupModal.tsx",
"/web/src/routing/routes/UsersAdministration/Groups/Modals/GroupModal/GroupModal.tsx",
"/web/src/routing/routes/UsersAdministration/Users/Users.tsx",
"/web/src/routing/routes/UsersAdministration/Users/Modals/UserModal/UserModal.tsx",
"/web/src/routing/routes/UsersAdministration/Users/UserDetails/UserDetails.tsx",
"/web/src/routing/routes/UsersAdministration/Users/UsersTable/UsersTable.tsx",
"/web/src/components/Button/Button.tsx",
"/web/src/components/ConfirmationDialog/ConfirmationDialog.tsx",
"/web/src/components/ErrorNotification/ErrorNotification.tsx",
"/web/src/components/FormInput/FormInput.tsx",
"/web/src/components/ListElement/ListElement.tsx",
"/web/src/components/Select/Select.tsx",
"/web/src/components/Table/Table.tsx",
"/web/src/components/Table/TableCell.tsx",
"/web/src/components/Table/TableRow.tsx",
"/web/src/components/icons/ArrowLeftIcon/ArrowLeftIcon.tsx",
"/web/src/components/icons/SearchIcon/SearchIcon.tsx",
"/web/src/types/group.ts",
"/web/src/types/user.ts",
"/web/src/utils/checkIsThisCurrentTab/checkIsThisCurrentTab.ts",
"/web/src/utils/getOptionsFromEnum/getOptionsFromEnum.ts",
"/web/src/validations/UserValidation.ts"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FC } from "react";

import { Button as MuiButton, Theme, ButtonProps } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { rgbaColors } from "@themes/palette";

export const Button: FC<ButtonProps> = ({ children, ...buttonProps }) => {
const theme = useTheme<Theme>();

return (
<MuiButton
{...buttonProps}
variant="contained"
sx={{
borderRadius: "4px",
py: 1.25,
px: 2,
lineHeight: theme.spacing(2),
color: "common.white",
borderColor: theme.palette.secondary.main,
textDecoration: "none",
":hover": {
textDecoration: "none",
borderColor: theme.palette.secondary.main,
},
"&.Mui-disabled": {
color: rgbaColors.grey.main,
border: `1px solid ${rgbaColors.grey.lighter}`,
background: "none",
py: 1.125,
},
...buttonProps.sx,
}}
>
{children}
</MuiButton>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { FC, ReactNode } from "react";

import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Theme,
Button,
} from "@mui/material";
import { useTheme } from "@mui/material/styles";

interface Props {
children: ReactNode;
isOpen: boolean;
onSubmit: () => void;
onCancelClick: () => void;
submitButtonTitle: string;
}

const ConfirmationDialogTitle: FC = ({ children }) => {
const theme = useTheme<Theme>();

return (
<DialogTitle
sx={{ fontSize: 24, lineHeight: theme.spacing(3), pt: 2.5, pb: 1.75 }}
>
{children}
</DialogTitle>
);
};

const ConfirmationDialogContent: FC = ({ children }) => {
const theme = useTheme<Theme>();

return (
<DialogContent sx={{ pb: 7.5, color: theme.palette.secondary.dark }}>
{children}
</DialogContent>
);
};

export const ConfirmationDialog = ({
children,
isOpen,
onSubmit,
onCancelClick,
submitButtonTitle,
}: Props) => {
const theme = useTheme<Theme>();

return (
<Dialog
onClose={onCancelClick}
open={isOpen}
sx={{
"& .MuiPaper-root": {
// TODO: Static width need to be removed while implementing RWD
width: "560px",
},
}}
>
{children}
<DialogActions sx={{ px: 1, pb: 1 }}>
<Button
sx={{ lineHeight: theme.spacing(2), p: 1 }}
variant="text"
onClick={onCancelClick}
>
Cancel
</Button>
<Button
sx={{ lineHeight: theme.spacing(2), p: 1 }}
variant="text"
onClick={onSubmit}
>
{submitButtonTitle}
</Button>
</DialogActions>
</Dialog>
);
};

ConfirmationDialog.Title = ConfirmationDialogTitle;
ConfirmationDialog.Content = ConfirmationDialogContent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { VFC } from "react";

import { Theme, Snackbar, Alert } from "@mui/material";
import { useTheme } from "@mui/material/styles";

interface Props {
content?: string;
show: boolean;
onClose: () => void;
}

export const ErrorNotification: VFC<Props> = ({ content, show, onClose }) => {
const theme = useTheme<Theme>();

return (
<Snackbar
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
open={show}
onClose={onClose}
// TODO: Static width need to be removed while implementing RWD
sx={{ width: "764px", "& .MuiPaper-root": { py: 0.75 } }}
>
<Alert
onClose={onClose}
severity="error"
sx={{
width: "100%",
backgroundColor: theme.palette.error.main,
color: "common.white",
}}
icon={false}
>
{content || "Something went wrong. Please try again."}
</Alert>
</Snackbar>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { VFC } from "react";

import { TextField, StandardTextFieldProps } from "@mui/material";

interface Props extends StandardTextFieldProps {
errorMessage?: string | undefined;
}

export const FormInput: VFC<Props> = ({
errorMessage,
...restProps
}: Props) => (
<TextField
fullWidth
error={Boolean(errorMessage)}
helperText={errorMessage}
variant="filled"
{...restProps}
/>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { VFC } from "react";

import { Box, Typography, Theme } from "@mui/material";
import { useTheme } from "@mui/material/styles";

interface Props {
label: string;
value: string;
}

export const ListElement: VFC<Props> = ({ label, value }) => {
const theme = useTheme<Theme>();

return (
<Box display="flex">
<Typography
width="120px"
color={theme.palette.secondary.dark}
fontSize={14}
lineHeight={theme.spacing(3)}
>
{label}
</Typography>
<Typography fontSize={14} fontWeight={600}>
{value}
</Typography>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FC } from "react";

import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import { Select as MuiSelect, MenuItem, SelectProps } from "@mui/material";

interface Option {
name: string;
label: string;
}

interface Props extends SelectProps {
options: Option[];
}

export const Select: FC<Props> = ({ options, ...selectProps }) => {
return (
<MuiSelect
variant="standard"
IconComponent={KeyboardArrowDownIcon}
{...selectProps}
>
{options.map((option) => (
<MenuItem value={option.name} key={option.name}>
{option.label}
</MenuItem>
))}
</MuiSelect>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ReactNode } from "react";

import {
Table as MuiTable,
TableContainer,
TableHead,
TableBody,
Paper,
} from "@mui/material";

import { TableCell } from "./TableCell";
import { TableRow } from "./TableRow";

interface Props {
children: ReactNode;
dataTestId?: string;
}

export const Table = ({ children, ...restProps }: Props) => (
<TableContainer component={Paper} sx={{ boxShadow: "none" }} {...restProps}>
<MuiTable sx={{ minWidth: 650 }}>{children}</MuiTable>
</TableContainer>
);

Table.TableCell = TableCell;
Table.TableBody = TableBody;
Table.TableHead = TableHead;
Table.TableRow = TableRow;
Loading