diff --git a/.yarn/cache/@esbuild-darwin-arm64-npm-0.17.10-bbcdd44aeb-10.zip b/.yarn/cache/@esbuild-darwin-arm64-npm-0.17.10-bbcdd44aeb-10.zip new file mode 100644 index 0000000000..f824c8bfa8 Binary files /dev/null and b/.yarn/cache/@esbuild-darwin-arm64-npm-0.17.10-bbcdd44aeb-10.zip differ diff --git a/.yarn/cache/@esbuild-darwin-arm64-npm-0.19.8-b1920f84ba-10.zip b/.yarn/cache/@esbuild-darwin-arm64-npm-0.19.8-b1920f84ba-10.zip new file mode 100644 index 0000000000..7b01f936cf Binary files /dev/null and b/.yarn/cache/@esbuild-darwin-arm64-npm-0.19.8-b1920f84ba-10.zip differ diff --git a/.yarn/cache/@esbuild-linux-x64-npm-0.17.10-d4d92085d1-10.zip b/.yarn/cache/@esbuild-linux-x64-npm-0.17.10-d4d92085d1-10.zip deleted file mode 100644 index d6ba1c990c..0000000000 Binary files a/.yarn/cache/@esbuild-linux-x64-npm-0.17.10-d4d92085d1-10.zip and /dev/null differ diff --git a/.yarn/cache/@esbuild-linux-x64-npm-0.19.8-231d24e5e4-10.zip b/.yarn/cache/@esbuild-linux-x64-npm-0.19.8-231d24e5e4-10.zip deleted file mode 100644 index 7d73c21404..0000000000 Binary files a/.yarn/cache/@esbuild-linux-x64-npm-0.19.8-231d24e5e4-10.zip and /dev/null differ diff --git a/.yarn/cache/@rollup-rollup-darwin-arm64-npm-4.6.1-4e41987212-10.zip b/.yarn/cache/@rollup-rollup-darwin-arm64-npm-4.6.1-4e41987212-10.zip new file mode 100644 index 0000000000..8f17faf278 Binary files /dev/null and b/.yarn/cache/@rollup-rollup-darwin-arm64-npm-4.6.1-4e41987212-10.zip differ diff --git a/.yarn/cache/@rollup-rollup-darwin-arm64-npm-4.9.6-e7e3fa5308-10.zip b/.yarn/cache/@rollup-rollup-darwin-arm64-npm-4.9.6-e7e3fa5308-10.zip new file mode 100644 index 0000000000..f3b5e49d18 Binary files /dev/null and b/.yarn/cache/@rollup-rollup-darwin-arm64-npm-4.9.6-e7e3fa5308-10.zip differ diff --git a/.yarn/cache/@rollup-rollup-linux-x64-gnu-npm-4.6.1-dd3309cd92-10.zip b/.yarn/cache/@rollup-rollup-linux-x64-gnu-npm-4.6.1-dd3309cd92-10.zip deleted file mode 100644 index 31e29ca0c4..0000000000 Binary files a/.yarn/cache/@rollup-rollup-linux-x64-gnu-npm-4.6.1-dd3309cd92-10.zip and /dev/null differ diff --git a/.yarn/cache/@rollup-rollup-linux-x64-gnu-npm-4.9.6-c67944ac17-10.zip b/.yarn/cache/@rollup-rollup-linux-x64-gnu-npm-4.9.6-c67944ac17-10.zip deleted file mode 100644 index fb5849b067..0000000000 Binary files a/.yarn/cache/@rollup-rollup-linux-x64-gnu-npm-4.9.6-c67944ac17-10.zip and /dev/null differ diff --git a/.yarn/cache/@swc-core-linux-x64-gnu-npm-1.3.107-1986905504-10.zip b/.yarn/cache/@swc-core-darwin-arm64-npm-1.3.100-d327f936fd-10.zip similarity index 57% rename from .yarn/cache/@swc-core-linux-x64-gnu-npm-1.3.107-1986905504-10.zip rename to .yarn/cache/@swc-core-darwin-arm64-npm-1.3.100-d327f936fd-10.zip index 8870a8268a..85c86561ad 100644 Binary files a/.yarn/cache/@swc-core-linux-x64-gnu-npm-1.3.107-1986905504-10.zip and b/.yarn/cache/@swc-core-darwin-arm64-npm-1.3.100-d327f936fd-10.zip differ diff --git a/.yarn/cache/@swc-core-linux-x64-gnu-npm-1.3.100-d30180f514-10.zip b/.yarn/cache/@swc-core-darwin-arm64-npm-1.3.107-7cf917d486-10.zip similarity index 56% rename from .yarn/cache/@swc-core-linux-x64-gnu-npm-1.3.100-d30180f514-10.zip rename to .yarn/cache/@swc-core-darwin-arm64-npm-1.3.107-7cf917d486-10.zip index 802061c004..d379a5c7a3 100644 Binary files a/.yarn/cache/@swc-core-linux-x64-gnu-npm-1.3.100-d30180f514-10.zip and b/.yarn/cache/@swc-core-darwin-arm64-npm-1.3.107-7cf917d486-10.zip differ diff --git a/.yarn/cache/@types-file-saver-npm-2.0.7-39f33a4b39-c3d1cd80ea.zip b/.yarn/cache/@types-file-saver-npm-2.0.7-39f33a4b39-c3d1cd80ea.zip new file mode 100644 index 0000000000..d490284b8a Binary files /dev/null and b/.yarn/cache/@types-file-saver-npm-2.0.7-39f33a4b39-c3d1cd80ea.zip differ diff --git a/.yarn/cache/fsevents-patch-19706e7e35-10.zip b/.yarn/cache/fsevents-patch-19706e7e35-10.zip new file mode 100644 index 0000000000..aff1ab12ce Binary files /dev/null and b/.yarn/cache/fsevents-patch-19706e7e35-10.zip differ diff --git a/.yarn/cache/fsevents-patch-6b67494872-10.zip b/.yarn/cache/fsevents-patch-6b67494872-10.zip new file mode 100644 index 0000000000..9887ada72d Binary files /dev/null and b/.yarn/cache/fsevents-patch-6b67494872-10.zip differ diff --git a/packages/rc-service/package.json b/packages/rc-service/package.json index 3aea0f575e..bfa8347666 100644 --- a/packages/rc-service/package.json +++ b/packages/rc-service/package.json @@ -31,6 +31,7 @@ "@reapit/utils-react": "workspace:packages/utils-react", "@sentry/browser": "^7.84.0", "dayjs": "^1.11.10", + "file-saver": "^2.0.5", "just-debounce-it": "^1.5.0", "qrcode": "^1.5.3", "query-string": "5.1.1", @@ -47,6 +48,7 @@ "@reapit/ts-scripts": "workspace:packages/ts-scripts", "@reapit/ts-types": "workspace:packages/ts-types", "@testing-library/react": "^14.1.2", + "@types/file-saver": "^2", "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", "cross-env": "^6.0.3", diff --git a/packages/rc-service/src/components/users/index.tsx b/packages/rc-service/src/components/users/index.tsx index 97b1600f5e..7c47fd47a4 100644 --- a/packages/rc-service/src/components/users/index.tsx +++ b/packages/rc-service/src/components/users/index.tsx @@ -14,6 +14,8 @@ import { ToggleRadio, Select, BodyText, + ButtonGroup, + Button, } from '@reapit/elements' import { reapitConnectBrowserSession } from '../../core/connect-session' import { GroupModelPagedResult, UserModelPagedResult } from '@reapit/foundations-ts-definitions' @@ -24,6 +26,9 @@ import { GetActionNames, getActions, objectToQuery, useReapitGet } from '@reapit import debounce from 'just-debounce-it' import dayjs from 'dayjs' import { UserContent } from './user-content' +import { getPlatformHeaders, logger } from '@reapit/utils-react' +import fileSaver from 'file-saver' +import qs from 'qs' export interface UserFilters { email?: string @@ -45,6 +50,7 @@ export const UsersPage: FC = () => { const [userSearch, setUserSearch] = useState({}) const [pageNumber, setPageNumber] = useState(1) const { register, watch } = useForm({ mode: 'all' }) + const [csvLoading, setCsvLoading] = useState(false) const emailQuery = { email: userSearch.email ? encodeURIComponent(userSearch.email) : undefined, } @@ -67,6 +73,61 @@ export const UsersPage: FC = () => { fetchWhenTrue: [], }) + const downloadAsCSV = async () => { + if (csvLoading) return + setCsvLoading(true) + try { + const headers = await getPlatformHeaders(reapitConnectBrowserSession, 'latest') + if (headers) { + const response = await fetch( + `${getActions[GetActionNames.getUsers].api}${getActions[GetActionNames.getUsers].path}?${qs.stringify({ + ...queryParams, + pageSize: 2000, + })}`, + { + method: 'get', + headers, + }, + ) + const data = await response.json() + const rows = data._embedded.map( + ({ + email, + name, + organisationName, + organisationId, + agencyCloudNegotiatorId, + created, + firstLoginDate, + userGroups, + }) => + [ + name, + email, + organisationId, + organisationName, + agencyCloudNegotiatorId, + created, + firstLoginDate, + userGroups.map(({ groupId }) => groupId).join(' '), + ].join(','), + ) + + const file = new File( + ['email,name,company,companyId,negotiatorId,created,firstLoginDate,userGroups\r\n', rows.join('\r\n')], + 'rc-service-users.csv', + { + type: 'text/plain;charset=utf-8', + }, + ) + fileSaver.saveAs(file) + } + } catch (error) { + logger(error as Error) + } + setCsvLoading(false) + } + useEffect(handleSetAdminFilters(setUserSearch, watch), []) return ( @@ -185,6 +246,11 @@ export const UsersPage: FC = () => { ) : users?._embedded?.length ? ( <> Total Users: {users?.totalCount} + + + { diff --git a/yarn.lock b/yarn.lock index d75e3a6d67..cf33e06e71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12571,6 +12571,13 @@ __metadata: languageName: node linkType: hard +"@types/file-saver@npm:^2": + version: 2.0.7 + resolution: "@types/file-saver@npm:2.0.7" + checksum: c3d1cd80eab1214767922cabac97681f3fb688e82b74890450d70deaca49537949bbc96d80d363d91e8f0a4752c7164909cc8902d9721c5c4809baafc42a3801 + languageName: node + linkType: hard + "@types/fs-extra@npm:^9.0.13": version: 9.0.13 resolution: "@types/fs-extra@npm:9.0.13" @@ -31747,12 +31754,14 @@ __metadata: "@reapit/utils-react": "workspace:packages/utils-react" "@sentry/browser": "npm:^7.84.0" "@testing-library/react": "npm:^14.1.2" + "@types/file-saver": "npm:^2" "@typescript-eslint/eslint-plugin": "npm:^6.20.0" "@typescript-eslint/parser": "npm:^6.20.0" cross-env: "npm:^6.0.3" dayjs: "npm:^1.11.10" eslint: "npm:8.56.0" eslint-plugin-prettier: "npm:^5.1.3" + file-saver: "npm:^2.0.5" jest: "npm:^29.7.0" jest-coverage-badges: "npm:^1.1.2" just-debounce-it: "npm:^1.5.0"