mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-08 08:34:20 +02:00
Factors redux tools to access the DB
This commit is contained in:
parent
b76fbc78ff
commit
bf62510d0a
@ -3,7 +3,7 @@ import { toast } from "react-toastify"
|
||||
|
||||
import { AppDispatch } from "../../store"
|
||||
|
||||
import { sendAddEnvie } from "../../store/envieAdd"
|
||||
import { fetchEnvieAdd } from "../../store/envieAdd"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
interface Props {
|
||||
@ -29,7 +29,7 @@ const AddEnvie = ({ dispatch }: Props) => {
|
||||
const onSavePostClicked = () => {
|
||||
if (domaine && envies) {
|
||||
dispatch(
|
||||
sendAddEnvie({
|
||||
fetchEnvieAdd({
|
||||
domaine,
|
||||
envies,
|
||||
precisions,
|
||||
|
@ -3,7 +3,7 @@ import { toast } from "react-toastify"
|
||||
|
||||
import { AppDispatch } from "../../store"
|
||||
|
||||
import { sendMembreSet } from "../../store/membreSet"
|
||||
import { fetchMembreSet } from "../../store/membreSet"
|
||||
import { Membre } from "../../services/membres"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
@ -24,7 +24,7 @@ const MembreSet = ({ dispatch, membre }: Props) => {
|
||||
const onSavePostClicked = () => {
|
||||
if (prenom && nom) {
|
||||
dispatch(
|
||||
sendMembreSet({
|
||||
fetchMembreSet({
|
||||
...membre,
|
||||
prenom,
|
||||
nom,
|
||||
|
@ -6,10 +6,9 @@ import { GoogleSpreadsheet, GoogleSpreadsheetWorksheet } from "google-spreadshee
|
||||
const SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]
|
||||
const CRED_PATH = path.resolve(process.cwd(), "access/gsheets.json")
|
||||
|
||||
type ElementWithId = unknown & { id: number }
|
||||
export type ElementWithId = unknown & { id: number }
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export async function getList<Element extends ElementWithId>(
|
||||
export async function listGet<Element extends ElementWithId>(
|
||||
sheetName: string,
|
||||
specimen: Element
|
||||
): Promise<Element[]> {
|
||||
@ -38,17 +37,15 @@ export async function getList<Element extends ElementWithId>(
|
||||
return elements
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export async function get<Element extends ElementWithId>(
|
||||
sheetName: string,
|
||||
membreId: number,
|
||||
specimen: Element
|
||||
): Promise<Element | undefined> {
|
||||
const list = await getList<Element>(sheetName, specimen)
|
||||
const list = await listGet<Element>(sheetName, specimen)
|
||||
return list.find((element) => element.id === membreId)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export async function setList<Element extends ElementWithId>(
|
||||
sheetName: string,
|
||||
elements: Element[]
|
||||
@ -101,7 +98,6 @@ export async function setList<Element extends ElementWithId>(
|
||||
return true
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export async function set<Element extends ElementWithId>(
|
||||
sheetName: string,
|
||||
element: Element
|
@ -1,33 +1,12 @@
|
||||
import { Request, Response, NextFunction } from "express"
|
||||
import { getList, add } from "./utils"
|
||||
import { listGetRequest, getRequest, setRequest, addRequest } from "./expressAccessors"
|
||||
import { Envie, EnvieWithoutId } from "../services/envies"
|
||||
|
||||
export const envieListGet = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const list = await getList<Envie>("Envies d'aider", new Envie())
|
||||
if (list) {
|
||||
response.status(200).json(list)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
const sheetName = "Envies d'aider"
|
||||
|
||||
export const envieAdd = async (
|
||||
request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const envie = await add<EnvieWithoutId, Envie>("Envies d'aider", request.body)
|
||||
if (envie) {
|
||||
response.status(200).json(envie)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
export const envieListGet = listGetRequest(sheetName, new Envie())
|
||||
|
||||
export const envieGet = getRequest(sheetName, new Envie())
|
||||
|
||||
export const envieAdd = addRequest<EnvieWithoutId, Envie>(sheetName)
|
||||
|
||||
export const envieSet = setRequest(sheetName)
|
||||
|
61
src/gsheets/expressAccessors.ts
Normal file
61
src/gsheets/expressAccessors.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { Request, Response, NextFunction } from "express"
|
||||
import { ElementWithId, get, listGet, add, set } from "./accessors"
|
||||
|
||||
export function getRequest<Element extends { id: number }>(sheetName: string, specimen: Element) {
|
||||
return async (request: Request, response: Response, _next: NextFunction): Promise<void> => {
|
||||
try {
|
||||
const id = parseInt(request.query.id as string, 10) || -1
|
||||
const elements = await get<Element>(sheetName, id, specimen)
|
||||
if (elements) {
|
||||
response.status(200).json(elements)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function addRequest<ElementNoId extends object, Element extends ElementNoId & ElementWithId>(
|
||||
sheetName: string
|
||||
) {
|
||||
return async (request: Request, response: Response, _next: NextFunction): Promise<void> => {
|
||||
try {
|
||||
const element = await add<ElementNoId, Element>(sheetName, request.body)
|
||||
if (element) {
|
||||
response.status(200).json(element)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function listGetRequest<Element extends { id: number }>(
|
||||
sheetName: string,
|
||||
specimen: Element
|
||||
) {
|
||||
return async (_request: Request, response: Response, _next: NextFunction): Promise<void> => {
|
||||
try {
|
||||
const elements = await listGet<Element>(sheetName, specimen)
|
||||
if (elements) {
|
||||
response.status(200).json(elements)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function setRequest<Element extends { id: number }>(sheetName: string) {
|
||||
return async (request: Request, response: Response, _next: NextFunction): Promise<void> => {
|
||||
try {
|
||||
const element = await set<Element>(sheetName, request.body)
|
||||
if (element) {
|
||||
response.status(200).json(element)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +1,12 @@
|
||||
import { Request, Response, NextFunction } from "express"
|
||||
import _ from "lodash"
|
||||
import { getList } from "./utils"
|
||||
import { JeuJav } from "../services/jeuJav"
|
||||
import { listGetRequest, getRequest, setRequest, addRequest } from "./expressAccessors"
|
||||
import { JeuJav, JeuJavWithoutId } from "../services/jeuxJav"
|
||||
|
||||
export const jeuJavListGet = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const list = await getList<JeuJav>("Jeux JAV", new JeuJav())
|
||||
if (list) {
|
||||
response.status(200).json(list)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
const sheetName = "Jeux JAV"
|
||||
|
||||
export const jeuJavGet = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
const list = await getList<JeuJav>("Jeux JAV", new JeuJav())
|
||||
const data = _.find(list, { id: 56 })
|
||||
if (data) {
|
||||
response.status(200).json(data)
|
||||
}
|
||||
}
|
||||
export const jeuJavListGet = listGetRequest(sheetName, new JeuJav())
|
||||
|
||||
export const jeuJavGet = getRequest(sheetName, new JeuJav())
|
||||
|
||||
export const jeuJavAdd = addRequest<JeuJavWithoutId, JeuJav>(sheetName)
|
||||
|
||||
export const jeuJavSet = setRequest(sheetName)
|
||||
|
@ -1,62 +1,12 @@
|
||||
import { Request, Response, NextFunction } from "express"
|
||||
import { getList, get, set, add } from "./utils"
|
||||
import { listGetRequest, getRequest, setRequest, addRequest } from "./expressAccessors"
|
||||
import { Membre, MembreWithoutId } from "../services/membres"
|
||||
|
||||
export const membreListGet = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const list = await getList<Membre>("Membres", new Membre())
|
||||
if (list) {
|
||||
response.status(200).json(list)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
const sheetName = "Membres"
|
||||
|
||||
export const membreGet = async (
|
||||
request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const id = parseInt(request.query.id as string, 10) || -1
|
||||
const membre = await get<Membre>("Membres", id, new Membre())
|
||||
response.status(200).json(membre)
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
export const membreListGet = listGetRequest(sheetName, new Membre())
|
||||
|
||||
export const membreSet = async (
|
||||
request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const envie = await set<Membre>("Membres", request.body)
|
||||
if (envie) {
|
||||
response.status(200).json(envie)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
export const membreGet = getRequest(sheetName, new Membre())
|
||||
|
||||
export const membreAdd = async (
|
||||
request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const membre = await add<MembreWithoutId, Membre>("Membres", request.body)
|
||||
if (membre) {
|
||||
response.status(200).json(membre)
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
response.status(400).json(e)
|
||||
}
|
||||
}
|
||||
export const membreAdd = addRequest<MembreWithoutId, Membre>(sheetName)
|
||||
|
||||
export const membreSet = setRequest(sheetName)
|
||||
|
@ -4,7 +4,7 @@ import { useDispatch, useSelector, shallowEqual } from "react-redux"
|
||||
import { Helmet } from "react-helmet"
|
||||
|
||||
import { AppState, AppThunk } from "../../store"
|
||||
import { fetchMembreDataIfNeed } from "../../store/membre"
|
||||
import { fetchMembreIfNeed } from "../../store/membre"
|
||||
import { MembreInfo, MembreSet } from "../../components"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
@ -17,7 +17,7 @@ const MembrePage = ({ match }: Props): JSX.Element => {
|
||||
const membre = useSelector((state: AppState) => state.membre, shallowEqual)
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchMembreDataIfNeed(id))
|
||||
dispatch(fetchMembreIfNeed(id))
|
||||
}, [dispatch, id])
|
||||
|
||||
const renderInfo = () => {
|
||||
@ -48,6 +48,6 @@ interface LoadDataArgs {
|
||||
params: { id: number }
|
||||
}
|
||||
|
||||
export const loadData = ({ params }: LoadDataArgs): AppThunk[] => [fetchMembreDataIfNeed(params.id)]
|
||||
export const loadData = ({ params }: LoadDataArgs): AppThunk[] => [fetchMembreIfNeed(params.id)]
|
||||
|
||||
export default memo(MembrePage)
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { render } from "@testing-library/react"
|
||||
import { MemoryRouter } from "react-router-dom"
|
||||
|
||||
import { fetchMembreDataIfNeed } from "../../../store/membre"
|
||||
import { fetchMembreIfNeed } from "../../../store/membre"
|
||||
import mockStore from "../../../utils/mockStore"
|
||||
import MembrePage from "../MembrePage"
|
||||
|
||||
@ -45,7 +45,7 @@ describe("<MembrePage />", () => {
|
||||
const { dispatch } = renderHelper()
|
||||
|
||||
expect(dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(dispatch.mock.calls[0][0].toString()).toBe(fetchMembreDataIfNeed(id).toString())
|
||||
expect(dispatch.mock.calls[0][0].toString()).toBe(fetchMembreIfNeed(id).toString())
|
||||
})
|
||||
|
||||
it("renders the loading status if data invalid", () => {
|
||||
|
85
src/services/accessors.ts
Normal file
85
src/services/accessors.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import axios from "axios"
|
||||
|
||||
import config from "../config"
|
||||
|
||||
export type ElementWithId = unknown & { id: number }
|
||||
|
||||
export function get<Element>(elementName: string): (id: number) => Promise<{
|
||||
data?: Element
|
||||
error?: Error
|
||||
}> {
|
||||
interface ElementGetResponse {
|
||||
data?: Element
|
||||
error?: Error
|
||||
}
|
||||
return async (id: number): Promise<ElementGetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/${elementName}Get`, {
|
||||
params: { id },
|
||||
})
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function listGet<Element>(elementName: string): () => Promise<{
|
||||
data?: Element[]
|
||||
error?: Error
|
||||
}> {
|
||||
interface ElementListGetResponse {
|
||||
data?: Element[]
|
||||
error?: Error
|
||||
}
|
||||
return async (): Promise<ElementListGetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/${elementName}ListGet`)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function add<ElementNoId extends object, Element extends ElementNoId & ElementWithId>(
|
||||
elementName: string
|
||||
): (membreWithoutId: ElementNoId) => Promise<{
|
||||
data?: Element
|
||||
error?: Error
|
||||
}> {
|
||||
interface ElementGetResponse {
|
||||
data?: Element
|
||||
error?: Error
|
||||
}
|
||||
return async (membreWithoutId: ElementNoId): Promise<ElementGetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.post(
|
||||
`${config.API_URL}/${elementName}Add`,
|
||||
membreWithoutId
|
||||
)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function set<Element>(elementName: string): (membre: Element) => Promise<{
|
||||
data?: Element
|
||||
error?: Error
|
||||
}> {
|
||||
interface ElementGetResponse {
|
||||
data?: Element
|
||||
error?: Error
|
||||
}
|
||||
return async (membre: Element): Promise<ElementGetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.post(`${config.API_URL}/${elementName}Set`, membre)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
import axios from "axios"
|
||||
|
||||
import config from "../config"
|
||||
import { get, listGet, add, set } from "./accessors"
|
||||
|
||||
export class Envie {
|
||||
id = 0
|
||||
@ -15,30 +13,13 @@ export class Envie {
|
||||
|
||||
dateAjout = ""
|
||||
}
|
||||
|
||||
export type EnvieWithoutId = Omit<Envie, "id">
|
||||
|
||||
export interface EnvieListGetResponse {
|
||||
data?: Envie[]
|
||||
error?: Error
|
||||
}
|
||||
export const envieListGet = async (): Promise<EnvieListGetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/EnvieListGet`)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
export const envieGet = get<Envie>("Envie")
|
||||
|
||||
export interface EnvieAddResponse {
|
||||
data?: Envie
|
||||
error?: Error
|
||||
}
|
||||
export const envieAdd = async (envieWithoutId: EnvieWithoutId): Promise<EnvieAddResponse> => {
|
||||
try {
|
||||
const { data } = await axios.post(`${config.API_URL}/EnvieAdd`, envieWithoutId)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
export const envieListGet = listGet<Envie>("Envie")
|
||||
|
||||
export const envieAdd = add<EnvieWithoutId, Envie>("Envie")
|
||||
|
||||
export const envieSet = set<Envie>("Envie")
|
||||
|
@ -1,61 +0,0 @@
|
||||
import axios from "axios"
|
||||
|
||||
import config from "../config"
|
||||
|
||||
export class JeuJav {
|
||||
id = 0
|
||||
|
||||
titre = ""
|
||||
|
||||
auteur = ""
|
||||
|
||||
editeur = ""
|
||||
|
||||
minJoueurs = 0
|
||||
|
||||
maxJoueurs = 0
|
||||
|
||||
duree = 0
|
||||
|
||||
type: "Ambiance" | "Famille" | "Expert" | "" = ""
|
||||
|
||||
poufpaf = ""
|
||||
|
||||
bggId = 0
|
||||
|
||||
exemplaires = 1
|
||||
|
||||
dispoPret = 0
|
||||
|
||||
nonRangee = 0
|
||||
|
||||
ean = ""
|
||||
|
||||
bggPhoto = ""
|
||||
}
|
||||
|
||||
export interface JeuJavListResponse {
|
||||
data?: JeuJav[]
|
||||
error?: Error
|
||||
}
|
||||
export const getJeuJavList = async (): Promise<JeuJavListResponse> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/JeuJavListGet`)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
|
||||
export interface JeuJavResponse {
|
||||
data?: JeuJav
|
||||
error?: Error
|
||||
}
|
||||
export const getJeuJavData = async (id: string): Promise<JeuJavResponse> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/JeuJavGet`, { params: { id } })
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
43
src/services/jeuxJav.ts
Normal file
43
src/services/jeuxJav.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { get, listGet, add, set } from "./accessors"
|
||||
|
||||
export class JeuJav {
|
||||
id = 0
|
||||
|
||||
titre = ""
|
||||
|
||||
auteur = ""
|
||||
|
||||
editeur = ""
|
||||
|
||||
minJoueurs = 0
|
||||
|
||||
maxJoueurs = 0
|
||||
|
||||
duree = 0
|
||||
|
||||
type: "Ambiance" | "Famille" | "Expert" | "" = ""
|
||||
|
||||
poufpaf = ""
|
||||
|
||||
bggId = 0
|
||||
|
||||
exemplaires = 1
|
||||
|
||||
dispoPret = 0
|
||||
|
||||
nonRangee = 0
|
||||
|
||||
ean = ""
|
||||
|
||||
bggPhoto = ""
|
||||
}
|
||||
|
||||
export type JeuJavWithoutId = Omit<JeuJav, "id">
|
||||
|
||||
export const jeuJavGet = get<JeuJav>("JeuJav")
|
||||
|
||||
export const jeuJavListGet = listGet<JeuJav>("JeuJav")
|
||||
|
||||
export const jeuJavAdd = add<JeuJavWithoutId, JeuJav>("JeuJav")
|
||||
|
||||
export const jeuJavSet = set<JeuJav>("JeuJav")
|
@ -1,6 +1,4 @@
|
||||
import axios from "axios"
|
||||
|
||||
import config from "../config"
|
||||
import { get, listGet, add, set } from "./accessors"
|
||||
|
||||
export class Membre {
|
||||
id = 0
|
||||
@ -29,56 +27,13 @@ export class Membre {
|
||||
|
||||
passe = ""
|
||||
}
|
||||
|
||||
export type MembreWithoutId = Omit<Membre, "id">
|
||||
|
||||
export interface MembreListGetResponse {
|
||||
data?: Membre[]
|
||||
error?: Error
|
||||
}
|
||||
export const membreListGet = async (): Promise<MembreListGetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/MembreListGet`)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
export const membreGet = get<Membre>("Membre")
|
||||
|
||||
export interface MembreGetResponse {
|
||||
data?: Membre
|
||||
error?: Error
|
||||
}
|
||||
export const membreGet = async (id: number): Promise<MembreGetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/MembreGet`, { params: { id } })
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
export const membreListGet = listGet<Membre>("Membre")
|
||||
|
||||
export interface MembreSetResponse {
|
||||
data?: Membre
|
||||
error?: Error
|
||||
}
|
||||
export const membreSet = async (membre: Membre): Promise<MembreSetResponse> => {
|
||||
try {
|
||||
const { data } = await axios.post(`${config.API_URL}/MembreSet`, membre)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
export const membreAdd = add<MembreWithoutId, Membre>("Membre")
|
||||
|
||||
export interface MembreAddResponse {
|
||||
data?: Membre
|
||||
error?: Error
|
||||
}
|
||||
export const membreAdd = async (membreWithoutId: MembreWithoutId): Promise<MembreAddResponse> => {
|
||||
try {
|
||||
const { data } = await axios.post(`${config.API_URL}/MembreAdd`, membreWithoutId)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
export const membreSet = set<Membre>("Membre")
|
||||
|
@ -1,13 +1,7 @@
|
||||
import axios from "axios"
|
||||
|
||||
import mockStore from "../../utils/mockStore"
|
||||
import membre, {
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
fetchMembreData,
|
||||
initialState,
|
||||
} from "../membre"
|
||||
import membre, { getRequesting, getSuccess, getFailure, fetchMembre, initialState } from "../membre"
|
||||
|
||||
jest.mock("axios")
|
||||
|
||||
@ -71,7 +65,7 @@ describe("membre action", () => {
|
||||
// @ts-expect-error
|
||||
axios.get.mockResolvedValue({ data: mockData })
|
||||
|
||||
await dispatch(fetchMembreData(id))
|
||||
await dispatch(fetchMembre(id))
|
||||
expect(getActions()).toEqual(expectedActions)
|
||||
})
|
||||
|
||||
@ -85,7 +79,7 @@ describe("membre action", () => {
|
||||
// @ts-expect-error
|
||||
axios.get.mockRejectedValue({ message: mockError })
|
||||
|
||||
await dispatch(fetchMembreData(id))
|
||||
await dispatch(fetchMembre(id))
|
||||
expect(getActions()).toEqual(expectedActions)
|
||||
})
|
||||
})
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { StateRequest } from "./utils"
|
||||
import { Envie, EnvieWithoutId, envieAdd } from "../services/envies"
|
||||
import { AppThunk } from "."
|
||||
import { StateRequest, toastError, toastSuccess, elementAddFetch } from "./utils"
|
||||
import { Envie, envieAdd } from "../services/envies"
|
||||
|
||||
const envieAdapter = createEntityAdapter<Envie>({
|
||||
selectId: (envie) => envie.id,
|
||||
})
|
||||
const envieAdapter = createEntityAdapter<Envie>()
|
||||
|
||||
const envieAddSlice = createSlice({
|
||||
name: "addEnvie",
|
||||
@ -32,34 +28,11 @@ const envieAddSlice = createSlice({
|
||||
export default envieAddSlice.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = envieAddSlice.actions
|
||||
|
||||
export const sendAddEnvie =
|
||||
(envieWithoutId: EnvieWithoutId): AppThunk =>
|
||||
async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await envieAdd(envieWithoutId)
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
toast.error(`Erreur lors de l'ajout d'une envie: ${error.message}`, {
|
||||
position: "top-center",
|
||||
autoClose: 6000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
} else {
|
||||
dispatch(getSuccess(data as Envie))
|
||||
toast.success("Envie ajoutée !", {
|
||||
position: "top-center",
|
||||
autoClose: 3000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
}
|
||||
}
|
||||
export const fetchEnvieAdd = elementAddFetch(
|
||||
envieAdd,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors de l'ajout d'une envie: ${error.message}`),
|
||||
() => toastSuccess("Envie ajoutée !")
|
||||
)
|
||||
|
@ -1,13 +1,10 @@
|
||||
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { StateRequest } from "./utils"
|
||||
import { StateRequest, toastError, elementListFetch } from "./utils"
|
||||
import { Envie, envieListGet } from "../services/envies"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
const envieAdapter = createEntityAdapter<Envie>({
|
||||
selectId: (envie) => envie.id,
|
||||
})
|
||||
const envieAdapter = createEntityAdapter<Envie>()
|
||||
|
||||
const envieList = createSlice({
|
||||
name: "getEnvieList",
|
||||
@ -32,26 +29,13 @@ const envieList = createSlice({
|
||||
export default envieList.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = envieList.actions
|
||||
|
||||
export const fetchEnvieList = (): AppThunk => async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await envieListGet()
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
toast.error(`Erreur lors du chargement des envies: ${error.message}`, {
|
||||
position: "top-center",
|
||||
autoClose: 6000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
} else {
|
||||
dispatch(getSuccess(data as Envie[]))
|
||||
}
|
||||
}
|
||||
export const fetchEnvieList = elementListFetch(
|
||||
envieListGet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement des envies: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchEnvieList = (state: AppState) => state.envieList.readyStatus !== "success"
|
||||
|
||||
|
@ -1,13 +1,10 @@
|
||||
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { StateRequest } from "./utils"
|
||||
import { JeuJav, getJeuJavList } from "../services/jeuJav"
|
||||
import { StateRequest, toastError, elementListFetch } from "./utils"
|
||||
import { JeuJav, jeuJavListGet } from "../services/jeuxJav"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
const jeuJavAdapter = createEntityAdapter<JeuJav>({
|
||||
selectId: (jeuJav) => jeuJav.id,
|
||||
})
|
||||
const jeuJavAdapter = createEntityAdapter<JeuJav>()
|
||||
|
||||
export const initialState = jeuJavAdapter.getInitialState({
|
||||
readyStatus: "idle",
|
||||
@ -34,26 +31,13 @@ const jeuJavList = createSlice({
|
||||
export default jeuJavList.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = jeuJavList.actions
|
||||
|
||||
export const fetchJeuJavList = (): AppThunk => async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await getJeuJavList()
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
toast.error(`Erreur lors du chargement des jeux JAV: ${error.message}`, {
|
||||
position: "top-center",
|
||||
autoClose: 6000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
} else {
|
||||
dispatch(getSuccess(data as JeuJav[]))
|
||||
}
|
||||
}
|
||||
export const fetchJeuJavList = elementListFetch(
|
||||
jeuJavListGet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement des jeux JAV: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchJeuJavList = (state: AppState) => state.jeuJavList.readyStatus !== "success"
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { StateRequest } from "./utils"
|
||||
import { StateRequest, toastError, elementFetch } from "./utils"
|
||||
import { Membre, membreGet } from "../services/membres"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
@ -32,36 +31,21 @@ const membre = createSlice({
|
||||
export default membre.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = membre.actions
|
||||
|
||||
export const fetchMembreData =
|
||||
(id: number): AppThunk =>
|
||||
async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
export const fetchMembre = elementFetch(
|
||||
membreGet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement d'un membre: ${error.message}`)
|
||||
)
|
||||
|
||||
const { error, data } = await membreGet(id)
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
toast.error(`Erreur lors du chargement du membre ${id}: ${error.message}`, {
|
||||
position: "top-center",
|
||||
autoClose: 6000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
} else {
|
||||
dispatch(getSuccess(data as Membre))
|
||||
}
|
||||
}
|
||||
|
||||
const shouldFetchMembreData = (state: AppState, id: number) =>
|
||||
const shouldFetchMembre = (state: AppState, id: number) =>
|
||||
state.membre.readyStatus !== "success" || (state.membre.entity && state.membre.entity.id !== id)
|
||||
|
||||
export const fetchMembreDataIfNeed =
|
||||
export const fetchMembreIfNeed =
|
||||
(id: number): AppThunk =>
|
||||
(dispatch, getState) => {
|
||||
if (shouldFetchMembreData(getState(), id)) return dispatch(fetchMembreData(id))
|
||||
if (shouldFetchMembre(getState(), id)) return dispatch(fetchMembre(id))
|
||||
|
||||
return null
|
||||
}
|
||||
|
38
src/store/membreAdd.ts
Normal file
38
src/store/membreAdd.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
|
||||
|
||||
import { StateRequest, toastError, toastSuccess, elementAddFetch } from "./utils"
|
||||
import { Membre, membreAdd } from "../services/membres"
|
||||
|
||||
const membreAdapter = createEntityAdapter<Membre>()
|
||||
|
||||
const membreAddSlice = createSlice({
|
||||
name: "addMembre",
|
||||
initialState: membreAdapter.getInitialState({
|
||||
readyStatus: "idle",
|
||||
} as StateRequest),
|
||||
reducers: {
|
||||
getRequesting: (state) => {
|
||||
state.readyStatus = "request"
|
||||
},
|
||||
getSuccess: (state, { payload }: PayloadAction<Membre>) => {
|
||||
state.readyStatus = "success"
|
||||
membreAdapter.addOne(state, payload)
|
||||
},
|
||||
getFailure: (state, { payload }: PayloadAction<string>) => {
|
||||
state.readyStatus = "failure"
|
||||
state.error = payload
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default membreAddSlice.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = membreAddSlice.actions
|
||||
|
||||
export const fetchMembreAdd = elementAddFetch(
|
||||
membreAdd,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors de l'ajout d'une membre: ${error.message}`),
|
||||
() => toastSuccess("Membre ajoutée !")
|
||||
)
|
@ -1,7 +1,6 @@
|
||||
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { StateRequest } from "./utils"
|
||||
import { StateRequest, toastError, elementListFetch } from "./utils"
|
||||
import { Membre, membreListGet } from "../services/membres"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
@ -32,26 +31,13 @@ const membreList = createSlice({
|
||||
export default membreList.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = membreList.actions
|
||||
|
||||
export const fetchMembreList = (): AppThunk => async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await membreListGet()
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
toast.error(`Erreur lors du chargement des utilisateurs: ${error.message}`, {
|
||||
position: "top-center",
|
||||
autoClose: 6000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
} else {
|
||||
dispatch(getSuccess(data as Membre[]))
|
||||
}
|
||||
}
|
||||
export const fetchMembreList = elementListFetch(
|
||||
membreListGet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement des membres: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchMembreList = (state: AppState) => state.membreList.readyStatus !== "success"
|
||||
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { StateRequest } from "./utils"
|
||||
import { StateRequest, toastError, toastSuccess, elementSet } from "./utils"
|
||||
import { Membre, membreSet } from "../services/membres"
|
||||
import { AppThunk } from "."
|
||||
|
||||
const membreAdapter = createEntityAdapter<Membre>({
|
||||
selectId: (membre) => membre.id,
|
||||
})
|
||||
const membreAdapter = createEntityAdapter<Membre>()
|
||||
|
||||
const membreSetSlice = createSlice({
|
||||
name: "membreSet",
|
||||
@ -20,7 +16,7 @@ const membreSetSlice = createSlice({
|
||||
},
|
||||
getSuccess: (state, { payload }: PayloadAction<Membre>) => {
|
||||
state.readyStatus = "success"
|
||||
membreAdapter.addOne(state, payload)
|
||||
membreAdapter.setOne(state, payload)
|
||||
},
|
||||
getFailure: (state, { payload }: PayloadAction<string>) => {
|
||||
state.readyStatus = "failure"
|
||||
@ -32,34 +28,11 @@ const membreSetSlice = createSlice({
|
||||
export default membreSetSlice.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = membreSetSlice.actions
|
||||
|
||||
export const sendMembreSet =
|
||||
(membre: Membre): AppThunk =>
|
||||
async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await membreSet(membre)
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
toast.error(`Erreur lors de la modification d'un membre: ${error.message}`, {
|
||||
position: "top-center",
|
||||
autoClose: 6000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
} else {
|
||||
dispatch(getSuccess(data as Membre))
|
||||
toast.success("Membre modifié !", {
|
||||
position: "top-center",
|
||||
autoClose: 3000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
}
|
||||
}
|
||||
export const fetchMembreSet = elementSet(
|
||||
membreSet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors de la modification d'un membre: ${error.message}`),
|
||||
() => toastSuccess("Membre modifié !")
|
||||
)
|
||||
|
@ -1,18 +1,24 @@
|
||||
import { History } from "history"
|
||||
import { connectRouter } from "connected-react-router"
|
||||
|
||||
import membreList from "./membreList"
|
||||
import membre from "./membre"
|
||||
import jeuJavList from "./jeuJavList"
|
||||
import envieAdd from "./envieAdd"
|
||||
import envieList from "./envieList"
|
||||
import jeuJavList from "./jeuJavList"
|
||||
import membre from "./membre"
|
||||
import membreAdd from "./membreAdd"
|
||||
import membreList from "./membreList"
|
||||
import membreSet from "./membreSet"
|
||||
|
||||
// Use inferred return type for making correctly Redux types
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default (history: History) => ({
|
||||
membreList,
|
||||
membre,
|
||||
jeuJavList,
|
||||
envieAdd,
|
||||
envieList,
|
||||
jeuJavList,
|
||||
membre,
|
||||
membreAdd,
|
||||
membreList,
|
||||
membreSet,
|
||||
router: connectRouter(history) as any,
|
||||
// Register more reducers...
|
||||
})
|
||||
|
@ -1,4 +1,156 @@
|
||||
import { ActionCreatorWithoutPayload, ActionCreatorWithPayload } from "@reduxjs/toolkit"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { AppThunk } from "."
|
||||
|
||||
export interface StateRequest {
|
||||
readyStatus: "idle" | "request" | "success" | "failure"
|
||||
error?: string
|
||||
}
|
||||
|
||||
export function toastError(message: string): void {
|
||||
toast.error(message, {
|
||||
position: "top-center",
|
||||
autoClose: 6000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
}
|
||||
|
||||
export function toastSuccess(message: string): void {
|
||||
toast.success(message, {
|
||||
position: "top-center",
|
||||
autoClose: 3000,
|
||||
hideProgressBar: true,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
})
|
||||
}
|
||||
|
||||
export function elementFetch<Element>(
|
||||
elementService: (id: number) => Promise<{
|
||||
data?: Element | undefined
|
||||
error?: Error | undefined
|
||||
}>,
|
||||
getRequesting: ActionCreatorWithoutPayload<string>,
|
||||
getSuccess: ActionCreatorWithPayload<Element, string>,
|
||||
getFailure: ActionCreatorWithPayload<string, string>,
|
||||
errorMessage: (error: Error) => void = (_error) => {
|
||||
/* Meant to be empty */
|
||||
},
|
||||
successMessage: () => void = () => {
|
||||
/* Meant to be empty */
|
||||
}
|
||||
): (id: number) => AppThunk {
|
||||
return (id: number): AppThunk =>
|
||||
async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await elementService(id)
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
errorMessage(error)
|
||||
} else {
|
||||
dispatch(getSuccess(data as Element))
|
||||
successMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function elementAddFetch<Element>(
|
||||
elementAddService: (membreWithoutId: Omit<Element, "id">) => Promise<{
|
||||
data?: Element | undefined
|
||||
error?: Error | undefined
|
||||
}>,
|
||||
getRequesting: ActionCreatorWithoutPayload<string>,
|
||||
getSuccess: ActionCreatorWithPayload<Element, string>,
|
||||
getFailure: ActionCreatorWithPayload<string, string>,
|
||||
errorMessage: (error: Error) => void = (_error) => {
|
||||
/* Meant to be empty */
|
||||
},
|
||||
successMessage: () => void = () => {
|
||||
/* Meant to be empty */
|
||||
}
|
||||
): (membreWithoutId: Omit<Element, "id">) => AppThunk {
|
||||
return (membreWithoutId: Omit<Element, "id">): AppThunk =>
|
||||
async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await elementAddService(membreWithoutId)
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
errorMessage(error)
|
||||
} else {
|
||||
dispatch(getSuccess(data as Element))
|
||||
successMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function elementListFetch<Element>(
|
||||
elementListService: () => Promise<{
|
||||
data?: Element[] | undefined
|
||||
error?: Error | undefined
|
||||
}>,
|
||||
getRequesting: ActionCreatorWithoutPayload<string>,
|
||||
getSuccess: ActionCreatorWithPayload<Element[], string>,
|
||||
getFailure: ActionCreatorWithPayload<string, string>,
|
||||
errorMessage: (error: Error) => void = (_error) => {
|
||||
/* Meant to be empty */
|
||||
},
|
||||
successMessage: () => void = () => {
|
||||
/* Meant to be empty */
|
||||
}
|
||||
): () => AppThunk {
|
||||
return (): AppThunk => async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await elementListService()
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
errorMessage(error)
|
||||
} else {
|
||||
dispatch(getSuccess(data as Element[]))
|
||||
successMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function elementSet<Element>(
|
||||
elementSetService: (membre: Element) => Promise<{
|
||||
data?: Element | undefined
|
||||
error?: Error | undefined
|
||||
}>,
|
||||
getRequesting: ActionCreatorWithoutPayload<string>,
|
||||
getSuccess: ActionCreatorWithPayload<Element, string>,
|
||||
getFailure: ActionCreatorWithPayload<string, string>,
|
||||
errorMessage: (error: Error) => void = (_error) => {
|
||||
/* Meant to be empty */
|
||||
},
|
||||
successMessage: () => void = () => {
|
||||
/* Meant to be empty */
|
||||
}
|
||||
): (element: Element) => AppThunk {
|
||||
return (element: Element): AppThunk =>
|
||||
async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await elementSetService(element)
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
errorMessage(error)
|
||||
} else {
|
||||
dispatch(getSuccess(data as Element))
|
||||
successMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user