Skip to content

Commit 4990b96

Browse files
committed
GAME-133 #comment integrate batch assign with API
1 parent 9ad4a80 commit 4990b96

File tree

7 files changed

+59
-7
lines changed

7 files changed

+59
-7
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tc_handle,badge_id,badge_name,awarded_by,awarded_at
2+
kirildev,858dafad-5fcd-4bc3-ab7c-849453d139ad,,kirildev,2022-08-15T07:25:43.187Z
3+
jcori,bc39b152-e0e3-4984-962b-f1eba67229dd,TCO22 Development Finalist,,2022-08-15T07:25:43.187Z
4+
amy_admin,bc39b152-e0e3-4984-962b-f1eba67229dd,TCO22 Development Finalist,,

src-ts/tools/gamification-admin/pages/badge-detail/AwardedMembersTab/AwardedMembersTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const AwardedMembersTab: FC<AwardedMembersTabProps> = (props: AwardedMembersTabP
2424
const pageHandler: InfinitePageHandler<MemberBadgeAward> = useGetGameBadgeAssigneesPage(props.badge, sort)
2525

2626
useEffect(() => {
27-
if (props.forceRefresh && pageHandler) {
27+
if (props.forceRefresh && pageHandler && !pageHandler.isValidating) {
2828
pageHandler.mutate()
2929
}
3030
}, [

src-ts/tools/gamification-admin/pages/badge-detail/BadgeDetailPage.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ const BadgeDetailPage: FC = () => {
264264
}
265265
}
266266

267-
function onManualAssign(): void {
267+
function onAssign(): void {
268268
// refresh awardedMembers data
269269
setForceAwardedMembersTabRefresh(true)
270270
setActiveTab(BadgeDetailsTabViews.awardedMembers)
@@ -279,11 +279,14 @@ const BadgeDetailPage: FC = () => {
279279
if (activeTab === BadgeDetailsTabViews.manualAward) {
280280
activeTabElement = <ManualAwardTab
281281
badge={badgeDetailsHandler.data as GameBadge}
282-
onManualAssign={onManualAssign}
282+
onManualAssign={onAssign}
283283
/>
284284
}
285285
if (activeTab === BadgeDetailsTabViews.batchAward) {
286-
activeTabElement = <BatchAwardTab />
286+
activeTabElement = <BatchAwardTab
287+
badge={badgeDetailsHandler.data as GameBadge}
288+
onBatchAssign={onAssign}
289+
/>
287290
}
288291

289292
// show page loader if we fetching results

src-ts/tools/gamification-admin/pages/badge-detail/BatchAwardTab/BatchAwardTab.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ $error-line-height: 14px;
1919
grid-template-columns: 1fr;
2020
}
2121

22+
.templateLink {
23+
text-transform: uppercase;
24+
color: $turq-160;
25+
font-weight: $font-weight-bold;
26+
margin-top: $space-lg;
27+
display: inline-block;
28+
}
29+
2230
.batchForm {
2331
display: flex;
2432
flex-direction: column;

src-ts/tools/gamification-admin/pages/badge-detail/BatchAwardTab/BatchAwardTab.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
// tslint:disable:no-null-keyword
12
import { Dispatch, FC, SetStateAction, useState } from 'react'
23

34
import { Button, IconSolid, InputFilePicker } from '../../../../../lib'
45
import { GameBadge } from '../../../game-lib'
56
import { BadgeAssignedModal } from '../../../game-lib/modals/badge-assigned-modal'
7+
import { batchAssignRequestAsync } from '../badge-details.functions'
68

79
import styles from './BatchAwardTab.module.scss'
810
interface BatchAwardTabProps {
@@ -14,7 +16,6 @@ const BatchAwardTab: FC<BatchAwardTabProps> = (props: BatchAwardTabProps) => {
1416

1517
const [showBadgeAssigned, setShowBadgeAssigned]: [boolean, Dispatch<SetStateAction<boolean>>] = useState<boolean>(false)
1618

17-
// tslint:disable-next-line:no-null-keyword
1819
const [files, setFiles]: [FileList | null, Dispatch<SetStateAction<FileList | null>>] = useState<FileList | null>(null)
1920

2021
const [errorText, setErrorText]: [string, Dispatch<SetStateAction<string>>] = useState<string>('')
@@ -29,14 +30,28 @@ const BatchAwardTab: FC<BatchAwardTabProps> = (props: BatchAwardTabProps) => {
2930
}
3031

3132
function onAward(): void {
32-
33+
batchAssignRequestAsync(files?.item(0) as File)
34+
.then(() => {
35+
setShowBadgeAssigned(true)
36+
setFiles(null)
37+
})
38+
.catch(e => {
39+
let message: string = e.message
40+
if (e.errors && e.errors[0] && e.errors[0].path === 'user_id') {
41+
message = `CSV file contains duplicate data. There are members included already owning this badge.`
42+
}
43+
setErrorText(message)
44+
})
3345
}
3446

3547
return (
3648
<div className={styles.tabWrap}>
3749
<h3>Batch Award</h3>
3850
<div className={styles.batchFormWrap}>
39-
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Neque ullamcorper neque sed orci, enim amet, sed.</p>
51+
<div>
52+
<p>If you would like to assign multiple people to multiple badges, this area is for you. Download the template below, populate the file with your data, and upload that file to the right once completed.</p>
53+
<a target={'_blank'} href='/gamification-admin/bulk.sample.csv' download='bulk.smaple.csv' className={styles.templateLink}>Download template CSV</a>
54+
</div>
4055
<div className={styles.batchForm}>
4156
<InputFilePicker
4257
fileConfig={{

src-ts/tools/gamification-admin/pages/badge-detail/badge-details.functions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { GamificationConfig } from '../../game-config'
22
import { GameBadge } from '../../game-lib'
33

4+
import { submitRequestAsync as submitBatchAssignRequestAsync } from './batch-assign-badge.store'
45
import { submitRequestAsync as submitBadgeAssingRequestAsync } from './manual-assign-badge.store'
56
import { submitRequestAsync as submitBadgeUpdateRequestAsync } from './update-badge.store'
67
import { UpdateBadgeRequest } from './updated-badge-request.model'
@@ -18,3 +19,7 @@ export function generateCSV(input: Array<Array<string | number>>): string {
1819
export async function manualAssignRequestAsync(csv: string): Promise<any> {
1920
return submitBadgeAssingRequestAsync(csv)
2021
}
22+
23+
export async function batchAssignRequestAsync(batchFile: File): Promise<any> {
24+
return submitBatchAssignRequestAsync(batchFile)
25+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { EnvironmentConfig } from '../../../../config'
2+
import { xhrPostAsync } from '../../../../lib'
3+
4+
export async function submitRequestAsync(batchFile: File): Promise<any> {
5+
const url: string = `${EnvironmentConfig.API.V5}/gamification/badges/assign`
6+
7+
const form: any = new FormData()
8+
9+
// fill the form
10+
form.append('file', batchFile)
11+
12+
return xhrPostAsync(url, form, {
13+
headers: {
14+
'Content-Type': 'multipart/form-data',
15+
},
16+
})
17+
}

0 commit comments

Comments
 (0)