Unverified Commit 6b55620c authored by pom421's avatar pom421 Committed by GitHub
Browse files

fix(export): bug on export (#154)

- the count control was invalid.
- use of date-fns to lighten the memory used
- message on the UI when the limit is reached
- LIMIT_EXPORT move in config.js to easily modify it for both UI and API
parent 166d1af6
Pipeline #111156 passed with stage
in 56 seconds
......@@ -4,6 +4,8 @@ const { publicRuntimeConfig } = getConfig() || {}
export const START_YEAR_MEDLE = 2020
export const LIMIT_EXPORT = 10000
// Timeout config : keep this timeout values in sync
export const timeout = {
cookie: 9 * 60 * 60,
......
import formatISO from "date-fns/formatISO"
import moment from "moment"
import { ISO_DATE } from "../utils/date"
......@@ -7,19 +8,19 @@ export const transform = (knexData) => {
return !knexData
? null
: {
asker: { id: knexData.asker_id, name: knexData.asker_name },
examinationDate: moment(knexData.examination_date).format(ISO_DATE),
hospital: { id: knexData.hospital_id, name: knexData.hospital_name },
id: knexData.id,
internalNumber: knexData.internal_number,
pvNumber: knexData.pv_number,
examinationDate: moment(knexData.examination_date).format(ISO_DATE),
profile: knexData.profile,
asker: { id: knexData.asker_id, name: knexData.asker_name },
pvNumber: knexData.pv_number,
user: {
id: knexData.added_by,
email: knexData.user_email,
firstName: knexData.user_first_name,
id: knexData.added_by,
lastName: knexData.user_last_name,
email: knexData.user_email,
},
hospital: { id: knexData.hospital_id, name: knexData.hospital_name },
...knexData.extra_data,
}
}
......@@ -28,14 +29,14 @@ export const transformForExport = (knexData) => {
return !knexData
? null
: {
asker: knexData.asker_name,
examinationDate: formatISO(knexData.examination_date, { representation: "date" }),
hospital: knexData.hospital_name,
id: knexData.id,
internalNumber: knexData.internal_number,
pvNumber: knexData.pv_number,
examinationDate: moment(knexData.examination_date).format(ISO_DATE),
profile: knexData.profile,
asker: knexData.asker_name,
pvNumber: knexData.pv_number,
user: knexData.user_email,
hospital: knexData.hospital_name,
...knexData.extra_data,
}
}
......@@ -48,14 +49,14 @@ export const untransform = (model) => {
const knexData = { extra_data: {} }
const mainKeys = {
addedBy: "added_by",
askerId: "asker_id",
examinationDate: "examination_date",
hospitalId: "hospital_id",
id: "id",
internalNumber: "internal_number",
pvNumber: "pv_number",
examinationDate: "examination_date",
profile: "profile",
askerId: "asker_id",
addedBy: "added_by",
hospitalId: "hospital_id",
pvNumber: "pv_number",
}
Object.keys(model).forEach((key) => {
......
......@@ -16,7 +16,7 @@ import Layout from "../../components/Layout"
import Pagination from "../../components/Pagination"
import { Title1 } from "../../components/StyledComponents"
import { VerticalList } from "../../components/VerticalList"
import { isOpenFeature } from "../../config"
import { isOpenFeature, LIMIT_EXPORT } from "../../config"
import { useDebounce } from "../../hooks/useDebounce"
import { usePaginatedData } from "../../hooks/usePaginatedData"
import { profiles as profilesConstants } from "../../utils/actsConstants"
......@@ -41,6 +41,7 @@ const ActsListPage = ({ paginatedData: initialPaginatedData, currentUser }) => {
const [search, setSearch] = useState("")
useDebounce(onChange, 500, [search])
const scope = useMemo(() => buildScope(currentUser), [currentUser])
const [errorExport, setErrorExport] = useState("")
const hospitalsChoices = useMemo(
() =>
......@@ -130,6 +131,7 @@ const ActsListPage = ({ paginatedData: initialPaginatedData, currentUser }) => {
function onChange() {
onSubmit(getValues())
setErrorExport("")
}
function onSubmit(formData) {
......@@ -137,6 +139,9 @@ const ActsListPage = ({ paginatedData: initialPaginatedData, currentUser }) => {
}
async function onExport() {
if (paginatedData.totalCount > LIMIT_EXPORT) {
setErrorExport(`Le nombre d'éléments dépasse ${LIMIT_EXPORT} 😅. Veuillez filtrer votre recherche, svp.`)
}
await fetchExport(getValues())
}
......@@ -305,11 +310,16 @@ const ActsListPage = ({ paginatedData: initialPaginatedData, currentUser }) => {
</Table>
<Pagination data={paginatedData} fn={fetchPage(getValues())} />
{isOpenFeature("export") && (
<div className="mt-5 d-flex justify-content-center">
<SearchButton className="btn-outline-primary" disabled={loading} onClick={onExport}>
<ListAltIcon /> Exporter les données
</SearchButton>
</div>
<>
<div className="mt-5 d-flex justify-content-center">
<SearchButton className="btn-outline-primary" disabled={loading} onClick={onExport}>
<ListAltIcon /> Exporter les données
</SearchButton>
</div>
<div style={{ color: "red" }} className="mt-3 text-center">
{errorExport}
</div>
</>
)}
</>
)}
......
import * as yup from "yup"
import { LIMIT_EXPORT } from "../../config"
import knex from "../../knex/knex"
import { transformAll, transformAllForExport } from "../../models/acts"
import { normalize } from "../../services/normalize"
......@@ -8,7 +9,6 @@ import { APIError } from "../../utils/errors"
import { STATUS_406_NOT_ACCEPTABLE } from "../../utils/http"
const LIMIT = 50
const LIMIT_EXPORT = 5000
export const makeWhereClause = ({
scope,
......@@ -133,8 +133,10 @@ export const searchForExport = async (params, currentUser) => {
const [actsCount] = await knex("acts").where(makeWhereClause(params)).count()
const count = actsCount?.count
// Limit the number of lines in export feature for security reason.
if (actsCount && actsCount > LIMIT_EXPORT)
if (count && count > LIMIT_EXPORT)
throw new APIError({
message: `Too many rows (limit is ${LIMIT_EXPORT})`,
status: STATUS_406_NOT_ACCEPTABLE,
......@@ -158,5 +160,5 @@ export const searchForExport = async (params, currentUser) => {
"users.last_name as user_last_name",
])
return { elements: transformAllForExport(acts), totalCount: actsCount }
return { elements: transformAllForExport(acts), totalCount: count }
}
......@@ -2724,6 +2724,11 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"
date-fns@^2.22.1:
version "2.22.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.22.1.tgz#1e5af959831ebb1d82992bf67b765052d8f0efc4"
integrity sha512-yUFPQjrxEmIsMqlHhAhmxkuH769baF21Kk+nZwZGyrMoyLA+LugaQtC0+Tqf9CBUUULWwUJt6Q5ySI3LJDDCGg==
dayjs@^1.8.34:
version "1.9.4"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.9.4.tgz#fcde984e227f4296f04e7b05720adad2e1071f1b"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment