Skip to content

Commit

Permalink
Soroka-80: добавляет импорт карточек из csv-файла (#9)
Browse files Browse the repository at this point in the history
* [feat] Add csv into deps

* [fix] Fix db env getting

* [feat] Add express formidable into deps

* [feat] Add migrations for change FilledProperty fields: name, data

* [feat] Change max len for data field

* [feat] Add custom component for csv import action

* [fix] Delete name field from destruction

* [feat] Add csv import endpoint

* Добавляет скоупы, фиксит баги в авторизации (#10)

* [ref] Add scopes, fix auth errors

* [fix] Make date property nullable

* SOROKA-82: добавляет утилиту для пагинации и пагинацию для эндпоинта с карточками (#16)

* [feat] Add pagination on cards
  • Loading branch information
kantegory authored Jun 29, 2022
1 parent 5922ab8 commit 2819b47
Show file tree
Hide file tree
Showing 19 changed files with 474 additions and 32 deletions.
2 changes: 2 additions & 0 deletions .adminjs/.entry.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
AdminJS.UserComponents = {}
import Component1 from '../src/admin/components/import-action-component'
AdminJS.UserComponents.Component1 = Component1
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ services:
- 5432
volumes:
- ./dbs/postgres-data:/var/lib/postgresql
env_file:
- .env

backend:
container_name: soroka-backend
Expand Down
112 changes: 107 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@types/bcrypt": "^5.0.0",
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/express-formidable": "^1.2.0",
"@types/express-session": "^1.17.4",
"@types/flat": "^5.0.2",
"@types/node": "^17.0.8",
Expand Down Expand Up @@ -47,7 +48,9 @@
"bcrypt": "^5.0.1",
"body-parser": "^1.19.1",
"cors": "^2.8.5",
"csv": "^6.1.3",
"express": "^4.17.2",
"express-formidable": "^1.2.0",
"passport": "^0.5.2",
"passport-jwt": "^4.0.0",
"pg": "^8.7.3",
Expand Down
44 changes: 44 additions & 0 deletions src/admin/components/import-action-component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react'

const ImportAction = () => {
async function submitForm(form) {
const formData = new FormData(form)

const response = await fetch(
'/v1/admin/import-csv',
{
method: 'POST',
body: formData
}
)

if (response.status === 200) {
form.reset()

alert('Импорт завершён')
}
}

return (
<form
style={{display: "flex", flexDirection: "column"}}
onSubmit={(event) => {
event.preventDefault()
submitForm(event.target)
}}
>
<label style={{fontSize: "1.5rem"}} htmlFor="csvFile">
Choose CSV:
</label>
<input style={{marginTop: "1.5rem"}} name="csvFile" type="file" id="csvFile" />
<button
style={{marginTop: "1.5rem", maxWidth: "25%"}}
type="submit"
>
Отправить
</button>
</form>
)
}

export default ImportAction
8 changes: 6 additions & 2 deletions src/controllers/cards/Card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ class CardController implements ICardController {
}

getAll = async (request: Request, response: Response) => {
const cardsList = await this.cardService.getAll(request.user)
const cardsResponse = await this.cardService.getAll(
request.user,
Number(request.query.limit) || null,
Number(request.query.offset) || null
)

return response.send(cardsList)
return response.send(cardsResponse)
}

create = async (request: Request, response: Response) => {
Expand Down
12 changes: 6 additions & 6 deletions src/controllers/users/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ class UserController implements IUserController {
if (tokens) {
const { accessToken, refreshToken } = tokens

response.send({ accessToken, refreshToken })
return response.send({ accessToken, refreshToken })
}
}

response.status(401).send({ error: 'Login or password is incorrect!' })
return response.status(401).send({ error: 'Login or password is incorrect!' })
} catch (e: any) {
response.status(500).send({ error: e })
return response.status(500).send({ error: 'Internal server error' })
}
}

Expand All @@ -104,13 +104,13 @@ class UserController implements IUserController {
if (tokens) {
const { accessToken, refreshToken } = tokens

response.send({ accessToken, refreshToken })
return response.send({ accessToken, refreshToken })
}
}

response.status(401).send({ error: 'Invalid credentials' })
return response.status(401).send({ error: 'Invalid credentials' })
} catch (e) {
response.status(500).send({ error: e })
return response.status(500).send({ error: 'Internal server error' })
}
}
}
Expand Down
37 changes: 36 additions & 1 deletion src/core/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,29 @@
"get": {
"description": "Список карточек",
"tags": ["cards"],
"parameters": [
{
"name": "limit",
"in": "query",
"required": true,
"type": "number",
"example": 2
},
{
"name": "offset",
"in": "query",
"required": true,
"type": "number",
"example": 20
}
],
"responses": {
"200": {
"name": "obj",
"in": "body",
"description": "Список карточек",
"schema": {
"$ref": "#/definitions/CardsResponse"
"$ref": "#/definitions/PaginatedCardsResponse"
}
}
}
Expand Down Expand Up @@ -938,6 +954,25 @@
}
}
},
"PaginatedCardsResponse": {
"type": "object",
"properties": {
"total": {
"type": "number",
"example": 2200
},
"hasNextPage": {
"type": "boolean",
"example": true
},
"results": {
"type": "array",
"items": {
"$ref": "#/definitions/CardsResponse"
}
}
}
},
"CardData": {
"type": "object",
"properties": {
Expand Down
Loading

0 comments on commit 2819b47

Please sign in to comment.