Skip to content

Commit

Permalink
feat(user bulk): error handling (#339)
Browse files Browse the repository at this point in the history
  • Loading branch information
nidhigarg-bmw authored Nov 13, 2023
1 parent b6e7c64 commit 275e501
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 36 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 1.7.0-RC3

- User Bulk Upload
- Error Handling
- Service Subscription sorting fix
- Change Company Role showing invalid Deselect
- Company Role
Expand All @@ -13,6 +15,11 @@

## 1.7.0-RC2

- App Subscription
- Autosetup Process Worker implementation (adjust overlay)
- Usermanagement
- User Invite IdP connection logic

### Change

- User Management screen for user invite block due to multiple active IdPs got enhanced inside the frontend-business-logic to exclude "MANAGED" idps
Expand Down
1 change: 1 addition & 0 deletions src/assets/locales/de/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@
"heading": "Upload form by selecting the form file with the user data"
},
"fileSizeError": "Uploaded file is too big. Maximum 100KB is allowed",
"fileHeaderError": "Bulk Upload list format wrong. Missing or incorrect header line. Recheck the download file to retrieve the expected format",
"uploadedFile": {
"fileHeading": "Prepared for upload:",
"addUserRolesHeading": "Add user roles for all users in bulk upload:",
Expand Down
1 change: 1 addition & 0 deletions src/assets/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,7 @@
"heading": "Upload form by selecting the form file with the user data"
},
"fileSizeError": "Uploaded file is too big. Maximum 100KB is allowed",
"fileHeaderError": "Bulk Upload list format wrong. Missing or incorrect header line. Recheck the download file to retrieve the expected format",
"uploadedFile": {
"fileHeading": "Prepared for upload:",
"addUserRolesHeading": "Add user roles for all users in bulk upload:",
Expand Down
101 changes: 66 additions & 35 deletions src/components/overlays/AddMultipleUser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { setRolesToAdd } from 'features/admin/userDeprecated/actions'
import {
type MultipleUsersResponse,
useAddMutipleUsersMutation,
type ErrorResponse,
} from 'features/appManagement/userManagementApiSlice'
import {
useFetchIDPListQuery,
Expand All @@ -62,6 +63,7 @@ import {
import './AddMultipleUser.scss'
import Papa from 'papaparse'
import { AddUserDeny } from '../AddUser/AddUserDeny'
import { error } from 'services/NotifyService'

const HelpPageURL =
'/documentation/?path=docs%2F03.+User+Management%2F01.+User+Account%2F04.+Create+new+user+account+%28bulk%29.md'
Expand All @@ -87,6 +89,9 @@ export default function AddMultipleUser() {
const [uploadAPIRResponse, setUploadAPIRResponse] =
useState<MultipleUsersResponse>()
const [tableErrorData, setTableErrorData] = useState<TableType>()
const [csvData, setCsvData] = useState<string[][]>([])

const CsvHeader = ['firstname', 'lastname', 'email']

useEffect(() => {
const rolesArray: AppRole[] = []
Expand All @@ -108,11 +113,20 @@ export default function AddMultipleUser() {
}, [idpsData])

useEffect(() => {
uploadAPIRResponse &&
if (uploadAPIRResponse) {
const errorMsgs = uploadAPIRResponse.errors.map(
(error: ErrorResponse) => [
`${csvData[error.line][0]} ${csvData[error.line][1]}, ${
csvData[error.line][2]
}`,
error.message,
]
)
setTableErrorData({
head: [''],
body: [uploadAPIRResponse.errors],
head: [],
body: errorMsgs,
})
}
}, [uploadAPIRResponse])

const handleSelectRole = (role: string, select: boolean) => {
Expand Down Expand Up @@ -167,6 +181,7 @@ export default function AddMultipleUser() {
const csvData: Array<Array<string>> = results.data as Array<
Array<string>
>
setCsvData(csvData)
csvData[0].push('Roles')
for (let i = 0; i < csvData.length; i++) {
if (i !== 0) csvData[i].push(roles.toString())
Expand All @@ -178,14 +193,23 @@ export default function AddMultipleUser() {
}

const onChangeFile = async (selectedFile: File) => {
setUploadedFile(selectedFile)

setUploadedFile(undefined)
Papa.parse(selectedFile, {
skipEmptyLines: true,
complete: function (results) {
const csvData: Array<Array<string>> = results.data as Array<
Array<string>
>
if (
!CsvHeader.reduce(
(a, c, i) => a && csvData[0][i].toLowerCase() === c.toLowerCase(),
true
)
) {
error(t('content.usermanagement.addMultipleUsers.fileHeaderError'))
return
}
setUploadedFile(selectedFile)
setTotalRowsInCSV(csvData.length - 1)
},
})
Expand Down Expand Up @@ -225,7 +249,7 @@ export default function AddMultipleUser() {
)}
</Typography>
</div>
{uploadAPIRResponse?.error && (
{uploadAPIRResponse && uploadAPIRResponse?.error >= 1 && (
<div className="userDetailsMain">
<div className="userError">
<Typography variant="body1" className="number">
Expand All @@ -240,7 +264,7 @@ export default function AddMultipleUser() {
</div>
)}
</div>
{tableErrorData && (
{tableErrorData && tableErrorData.body[0]?.length > 0 && (
<>
<div className="mb-30">
<Trans>
Expand All @@ -251,7 +275,7 @@ export default function AddMultipleUser() {
</Typography>
</Trans>
</div>
<StaticTable data={tableErrorData} horizontal={true} />
<StaticTable data={tableErrorData} horizontal={false} />
</>
)}
</div>
Expand Down Expand Up @@ -408,6 +432,9 @@ export default function AddMultipleUser() {
)}
DropStatusHeader={false}
DropArea={renderDropArea}
handleDelete={() => {
setUploadedFile(undefined)
}}
/>
</div>
</div>
Expand Down Expand Up @@ -437,34 +464,38 @@ export default function AddMultipleUser() {
onClick={() => dispatch(show(OVERLAYS.NONE))}
sx={{ textTransform: 'none' }}
>
{t('global.actions.cancel')}
{isSuccess ? t('global.actions.close') : t('global.actions.cancel')}
</Button>
{loading ? (
<LoadingButton
color="primary"
helperText=""
helperTextColor="success"
label=""
loadIndicator={t('global.actions.loading')}
loading
size="medium"
onButtonClick={() => {
// do nothing
}}
sx={{ marginLeft: '10px', textTransform: 'none' }}
/>
) : (
<Button
variant="contained"
onClick={handleConfirm}
disabled={
uploadedFile === undefined || (isFileUploaded && !roles.length)
}
sx={{ textTransform: 'none' }}
>
{isError ? t('global.actions.exit') : t('global.actions.confirm')}
</Button>
)}
{!isSuccess &&
(loading ? (
<LoadingButton
color="primary"
helperText=""
helperTextColor="success"
label=""
loadIndicator={t('global.actions.loading')}
loading
size="medium"
onButtonClick={() => {
// do nothing
}}
sx={{ marginLeft: '10px', textTransform: 'none' }}
/>
) : (
<Button
variant="contained"
onClick={handleConfirm}
disabled={
uploadedFile === undefined ||
(isFileUploaded && !roles.length)
}
sx={{ textTransform: 'none' }}
>
{isError
? t('global.actions.exit')
: t('global.actions.confirm')}
</Button>
))}
</DialogActions>
</>
) : (
Expand Down
8 changes: 7 additions & 1 deletion src/features/appManagement/userManagementApiSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ export type MultipleUsersRequest = {
identityProviderId?: string
}

export type ErrorResponse = {
details: string[]
line: number
message: string
}

export type MultipleUsersResponse = {
created: number
error: number
errors: string[]
errors: ErrorResponse[]
total: number
}

Expand Down

0 comments on commit 275e501

Please sign in to comment.