mirror of
https://github.com/ershisan99/it-incubator-todolist-ts-17-live-2024-08-17.git
synced 2025-12-16 20:59:30 +00:00
chore: rename types to remove word "Type"
This commit is contained in:
@@ -14,22 +14,21 @@ const instance = axios.create({
|
|||||||
// api
|
// api
|
||||||
export const todolistsAPI = {
|
export const todolistsAPI = {
|
||||||
getTodolists() {
|
getTodolists() {
|
||||||
const promise = instance.get<TodolistType[]>('todo-lists')
|
const promise = instance.get<Todolist[]>('todo-lists')
|
||||||
return promise
|
return promise
|
||||||
},
|
},
|
||||||
createTodolist(title: string) {
|
createTodolist(title: string) {
|
||||||
const promise = instance.post<ResponseType<{ item: TodolistType }>>(
|
const promise = instance.post<Response<{ item: Todolist }>>('todo-lists', {
|
||||||
'todo-lists',
|
title: title,
|
||||||
{ title: title }
|
})
|
||||||
)
|
|
||||||
return promise
|
return promise
|
||||||
},
|
},
|
||||||
deleteTodolist(id: string) {
|
deleteTodolist(id: string) {
|
||||||
const promise = instance.delete<ResponseType>(`todo-lists/${id}`)
|
const promise = instance.delete<Response>(`todo-lists/${id}`)
|
||||||
return promise
|
return promise
|
||||||
},
|
},
|
||||||
updateTodolist(id: string, title: string) {
|
updateTodolist(id: string, title: string) {
|
||||||
const promise = instance.put<ResponseType>(`todo-lists/${id}`, {
|
const promise = instance.put<Response>(`todo-lists/${id}`, {
|
||||||
title: title,
|
title: title,
|
||||||
})
|
})
|
||||||
return promise
|
return promise
|
||||||
@@ -38,25 +37,23 @@ export const todolistsAPI = {
|
|||||||
return instance.get<GetTasksResponse>(`todo-lists/${todolistId}/tasks`)
|
return instance.get<GetTasksResponse>(`todo-lists/${todolistId}/tasks`)
|
||||||
},
|
},
|
||||||
deleteTask(todolistId: string, taskId: string) {
|
deleteTask(todolistId: string, taskId: string) {
|
||||||
return instance.delete<ResponseType>(
|
return instance.delete<Response>(`todo-lists/${todolistId}/tasks/${taskId}`)
|
||||||
`todo-lists/${todolistId}/tasks/${taskId}`
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
createTask(todolistId: string, taskTitile: string) {
|
createTask(todolistId: string, taskTitile: string) {
|
||||||
return instance.post<ResponseType<{ item: TaskType }>>(
|
return instance.post<Response<{ item: TaskEntity }>>(
|
||||||
`todo-lists/${todolistId}/tasks`,
|
`todo-lists/${todolistId}/tasks`,
|
||||||
{ title: taskTitile }
|
{ title: taskTitile }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
updateTask(todolistId: string, taskId: string, model: UpdateTaskModelType) {
|
updateTask(todolistId: string, taskId: string, model: UpdateTaskModel) {
|
||||||
return instance.put<ResponseType<TaskType>>(
|
return instance.put<Response<TaskEntity>>(
|
||||||
`todo-lists/${todolistId}/tasks/${taskId}`,
|
`todo-lists/${todolistId}/tasks/${taskId}`,
|
||||||
model
|
model
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LoginParamsType = {
|
export type LoginParams = {
|
||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
rememberMe: boolean
|
rememberMe: boolean
|
||||||
@@ -64,21 +61,20 @@ export type LoginParamsType = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const authAPI = {
|
export const authAPI = {
|
||||||
login(data: LoginParamsType) {
|
login(data: LoginParams) {
|
||||||
const promise = instance.post<ResponseType<{ userId?: number }>>(
|
const promise = instance.post<Response<{ userId?: number }>>(
|
||||||
'auth/login',
|
'auth/login',
|
||||||
data
|
data
|
||||||
)
|
)
|
||||||
return promise
|
return promise
|
||||||
},
|
},
|
||||||
logout() {
|
logout() {
|
||||||
const promise =
|
const promise = instance.delete<Response<{ userId?: number }>>('auth/login')
|
||||||
instance.delete<ResponseType<{ userId?: number }>>('auth/login')
|
|
||||||
return promise
|
return promise
|
||||||
},
|
},
|
||||||
me() {
|
me() {
|
||||||
const promise =
|
const promise =
|
||||||
instance.get<ResponseType<{ id: number; email: string; login: string }>>(
|
instance.get<Response<{ id: number; email: string; login: string }>>(
|
||||||
'auth/me'
|
'auth/me'
|
||||||
)
|
)
|
||||||
return promise
|
return promise
|
||||||
@@ -86,13 +82,13 @@ export const authAPI = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// types
|
// types
|
||||||
export type TodolistType = {
|
export type Todolist = {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
addedDate: string
|
addedDate: string
|
||||||
order: number
|
order: number
|
||||||
}
|
}
|
||||||
export type ResponseType<D = {}> = {
|
export type Response<D = {}> = {
|
||||||
resultCode: number
|
resultCode: number
|
||||||
messages: Array<string>
|
messages: Array<string>
|
||||||
data: D
|
data: D
|
||||||
@@ -113,7 +109,7 @@ export enum TaskPriorities {
|
|||||||
Later = 4,
|
Later = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TaskType = {
|
export type TaskEntity = {
|
||||||
description: string
|
description: string
|
||||||
title: string
|
title: string
|
||||||
status: TaskStatuses
|
status: TaskStatuses
|
||||||
@@ -125,7 +121,7 @@ export type TaskType = {
|
|||||||
order: number
|
order: number
|
||||||
addedDate: string
|
addedDate: string
|
||||||
}
|
}
|
||||||
export type UpdateTaskModelType = {
|
export type UpdateTaskModel = {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
status: TaskStatuses
|
status: TaskStatuses
|
||||||
@@ -136,5 +132,5 @@ export type UpdateTaskModelType = {
|
|||||||
type GetTasksResponse = {
|
type GetTasksResponse = {
|
||||||
error: string | null
|
error: string | null
|
||||||
totalCount: number
|
totalCount: number
|
||||||
items: TaskType[]
|
items: TaskEntity[]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import './App.css'
|
|||||||
import { TodolistsList } from 'features/TodolistsList/TodolistsList'
|
import { TodolistsList } from 'features/TodolistsList/TodolistsList'
|
||||||
import { ErrorSnackbar } from 'components/ErrorSnackbar/ErrorSnackbar'
|
import { ErrorSnackbar } from 'components/ErrorSnackbar/ErrorSnackbar'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from 'react-redux'
|
||||||
import { AppRootStateType } from './store'
|
import { AppRootState } from './store'
|
||||||
import { initializeAppTC, RequestStatusType } from './app-reducer'
|
import { initializeAppTC, RequestStatus } from './app-reducer'
|
||||||
import { BrowserRouter, Route, Routes } from 'react-router-dom'
|
import { BrowserRouter, Route, Routes } from 'react-router-dom'
|
||||||
import { Login } from 'features/Login/Login'
|
import { Login } from 'features/Login/Login'
|
||||||
import { logoutTC } from 'features/Login/auth-reducer'
|
import { logoutTC } from 'features/Login/auth-reducer'
|
||||||
@@ -20,18 +20,18 @@ import {
|
|||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import { Menu } from '@mui/icons-material'
|
import { Menu } from '@mui/icons-material'
|
||||||
|
|
||||||
type PropsType = {
|
type Props = {
|
||||||
demo?: boolean
|
demo?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
function App({ demo = false }: PropsType) {
|
function App({ demo = false }: Props) {
|
||||||
const status = useSelector<AppRootStateType, RequestStatusType>(
|
const status = useSelector<AppRootState, RequestStatus>(
|
||||||
(state) => state.app.status
|
(state) => state.app.status
|
||||||
)
|
)
|
||||||
const isInitialized = useSelector<AppRootStateType, boolean>(
|
const isInitialized = useSelector<AppRootState, boolean>(
|
||||||
(state) => state.app.isInitialized
|
(state) => state.app.isInitialized
|
||||||
)
|
)
|
||||||
const isLoggedIn = useSelector<AppRootStateType, boolean>(
|
const isLoggedIn = useSelector<AppRootState, boolean>(
|
||||||
(state) => state.auth.isLoggedIn
|
(state) => state.auth.isLoggedIn
|
||||||
)
|
)
|
||||||
const dispatch = useDispatch<any>()
|
const dispatch = useDispatch<any>()
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
appReducer,
|
appReducer,
|
||||||
InitialStateType,
|
InitialState,
|
||||||
setAppError,
|
setAppError,
|
||||||
setAppStatus,
|
setAppStatus,
|
||||||
} from './app-reducer'
|
} from './app-reducer'
|
||||||
|
|
||||||
let startState: InitialStateType
|
let startState: InitialState
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
startState = {
|
startState = {
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ import { authAPI } from 'api/todolists-api'
|
|||||||
import { setIsLoggedIn } from 'features/Login/auth-reducer'
|
import { setIsLoggedIn } from 'features/Login/auth-reducer'
|
||||||
import { AppThunk } from 'app/store'
|
import { AppThunk } from 'app/store'
|
||||||
|
|
||||||
export type RequestStatusType = 'idle' | 'loading' | 'succeeded' | 'failed'
|
export type RequestStatus = 'idle' | 'loading' | 'succeeded' | 'failed'
|
||||||
|
|
||||||
export type InitialStateType = {
|
export type InitialState = {
|
||||||
// происходит ли сейчас взаимодействие с сервером
|
// происходит ли сейчас взаимодействие с сервером
|
||||||
status: RequestStatusType
|
status: RequestStatus
|
||||||
// если ошибка какая-то глобальная произойдёт - мы запишем текст ошибки сюда
|
// если ошибка какая-то глобальная произойдёт - мы запишем текст ошибки сюда
|
||||||
error: string | null
|
error: string | null
|
||||||
// true когда приложение проинициализировалось (проверили юзера, настройки получили и т.д.)
|
// true когда приложение проинициализировалось (проверили юзера, настройки получили и т.д.)
|
||||||
isInitialized: boolean
|
isInitialized: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: InitialStateType = {
|
const initialState: InitialState = {
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: null,
|
||||||
isInitialized: false,
|
isInitialized: false,
|
||||||
@@ -27,7 +27,7 @@ const appSlice = createSlice({
|
|||||||
setAppError(state, action: PayloadAction<string | null>) {
|
setAppError(state, action: PayloadAction<string | null>) {
|
||||||
return { ...state, error: action.payload }
|
return { ...state, error: action.payload }
|
||||||
},
|
},
|
||||||
setAppStatus(state, action: PayloadAction<RequestStatusType>) {
|
setAppStatus(state, action: PayloadAction<RequestStatus>) {
|
||||||
return { ...state, status: action.payload }
|
return { ...state, status: action.payload }
|
||||||
},
|
},
|
||||||
setAppInitialized(state, action: PayloadAction<boolean>) {
|
setAppInitialized(state, action: PayloadAction<boolean>) {
|
||||||
|
|||||||
@@ -17,20 +17,16 @@ const rootReducer = combineReducers({
|
|||||||
// const store = createStore(rootReducer, applyMiddleware(thunkMiddleware));
|
// const store = createStore(rootReducer, applyMiddleware(thunkMiddleware));
|
||||||
export const store = configureStore({ reducer: rootReducer })
|
export const store = configureStore({ reducer: rootReducer })
|
||||||
|
|
||||||
export type AppRootStateType = ReturnType<typeof rootReducer>
|
export type AppRootState = ReturnType<typeof rootReducer>
|
||||||
|
|
||||||
// ❗ UnknownAction вместо AnyAction
|
// ❗ UnknownAction вместо AnyAction
|
||||||
export type AppThunk<ReturnType = void> = ThunkAction<
|
export type AppThunk<ReturnType = void> = ThunkAction<
|
||||||
ReturnType,
|
ReturnType,
|
||||||
AppRootStateType,
|
AppRootState,
|
||||||
unknown,
|
unknown,
|
||||||
UnknownAction
|
UnknownAction
|
||||||
>
|
>
|
||||||
|
|
||||||
// export type AppDispatch = typeof store.dispatch
|
// export type AppDispatch = typeof store.dispatch
|
||||||
// ❗ UnknownAction вместо AnyAction
|
// ❗ UnknownAction вместо AnyAction
|
||||||
export type AppDispatch = ThunkDispatch<
|
export type AppDispatch = ThunkDispatch<AppRootState, unknown, UnknownAction>
|
||||||
AppRootStateType,
|
|
||||||
unknown,
|
|
||||||
UnknownAction
|
|
||||||
>
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { ChangeEvent, KeyboardEvent, useState } from 'react'
|
|||||||
import { IconButton, TextField } from '@mui/material'
|
import { IconButton, TextField } from '@mui/material'
|
||||||
import { AddBox } from '@mui/icons-material'
|
import { AddBox } from '@mui/icons-material'
|
||||||
|
|
||||||
type AddItemFormPropsType = {
|
type AddItemFormProps = {
|
||||||
addItem: (title: string) => void
|
addItem: (title: string) => void
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ type AddItemFormPropsType = {
|
|||||||
export const AddItemForm = React.memo(function ({
|
export const AddItemForm = React.memo(function ({
|
||||||
addItem,
|
addItem,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
}: AddItemFormPropsType) {
|
}: AddItemFormProps) {
|
||||||
let [title, setTitle] = useState('')
|
let [title, setTitle] = useState('')
|
||||||
let [error, setError] = useState<string | null>(null)
|
let [error, setError] = useState<string | null>(null)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import React, { ChangeEvent, useState } from 'react'
|
import React, { ChangeEvent, useState } from 'react'
|
||||||
import { TextField } from '@mui/material'
|
import { TextField } from '@mui/material'
|
||||||
|
|
||||||
type EditableSpanPropsType = {
|
type EditableSpanProps = {
|
||||||
value: string
|
value: string
|
||||||
onChange: (newValue: string) => void
|
onChange: (newValue: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EditableSpan = React.memo(function (props: EditableSpanPropsType) {
|
export const EditableSpan = React.memo(function (props: EditableSpanProps) {
|
||||||
let [editMode, setEditMode] = useState(false)
|
let [editMode, setEditMode] = useState(false)
|
||||||
let [title, setTitle] = useState(props.value)
|
let [title, setTitle] = useState(props.value)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from 'react-redux'
|
||||||
import { AppRootStateType } from 'app/store'
|
import { AppRootState } from 'app/store'
|
||||||
import { setAppError } from 'app/app-reducer'
|
import { setAppError } from 'app/app-reducer'
|
||||||
import { AlertProps, Snackbar } from '@mui/material'
|
import { AlertProps, Snackbar } from '@mui/material'
|
||||||
import MuiAlert from '@mui/material/Alert'
|
import MuiAlert from '@mui/material/Alert'
|
||||||
@@ -19,7 +19,7 @@ const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
|
|||||||
)
|
)
|
||||||
|
|
||||||
export function ErrorSnackbar() {
|
export function ErrorSnackbar() {
|
||||||
const error = useSelector<AppRootStateType, string | null>(
|
const error = useSelector<AppRootState, string | null>(
|
||||||
(state) => state.app.error
|
(state) => state.app.error
|
||||||
)
|
)
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import { useFormik } from 'formik'
|
import { useFormik } from 'formik'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { loginTC } from './auth-reducer'
|
import { loginTC } from './auth-reducer'
|
||||||
import { AppRootStateType } from 'app/store'
|
import { AppRootState } from 'app/store'
|
||||||
import { Navigate } from 'react-router-dom'
|
import { Navigate } from 'react-router-dom'
|
||||||
import { useAppDispatch } from 'hooks/useAppDispatch'
|
import { useAppDispatch } from 'hooks/useAppDispatch'
|
||||||
import {
|
import {
|
||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
export const Login = () => {
|
export const Login = () => {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
const isLoggedIn = useSelector<AppRootStateType, boolean>(
|
const isLoggedIn = useSelector<AppRootState, boolean>(
|
||||||
(state) => state.auth.isLoggedIn
|
(state) => state.auth.isLoggedIn
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
import { authAPI, LoginParamsType } from 'api/todolists-api'
|
import { authAPI, LoginParams } from 'api/todolists-api'
|
||||||
import { setAppStatus } from 'app/app-reducer'
|
import { setAppStatus } from 'app/app-reducer'
|
||||||
import {
|
import {
|
||||||
handleServerAppError,
|
handleServerAppError,
|
||||||
@@ -7,11 +7,11 @@ import {
|
|||||||
} from 'utils/error-utils'
|
} from 'utils/error-utils'
|
||||||
import { AppThunk } from 'app/store'
|
import { AppThunk } from 'app/store'
|
||||||
|
|
||||||
type InitialStateType = {
|
type InitialState = {
|
||||||
isLoggedIn: boolean
|
isLoggedIn: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: InitialStateType = {
|
const initialState: InitialState = {
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export const { setIsLoggedIn } = authSlice.actions
|
|||||||
|
|
||||||
// thunks
|
// thunks
|
||||||
export const loginTC =
|
export const loginTC =
|
||||||
(data: LoginParamsType): AppThunk =>
|
(data: LoginParams): AppThunk =>
|
||||||
(dispatch) => {
|
(dispatch) => {
|
||||||
dispatch(setAppStatus('loading'))
|
dispatch(setAppStatus('loading'))
|
||||||
authAPI
|
authAPI
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import React, { ChangeEvent, useCallback } from 'react'
|
|||||||
import { Checkbox, IconButton } from '@mui/material'
|
import { Checkbox, IconButton } from '@mui/material'
|
||||||
import { EditableSpan } from 'components/EditableSpan/EditableSpan'
|
import { EditableSpan } from 'components/EditableSpan/EditableSpan'
|
||||||
import { Delete } from '@mui/icons-material'
|
import { Delete } from '@mui/icons-material'
|
||||||
import { TaskStatuses, TaskType } from 'api/todolists-api'
|
import { TaskStatuses, TaskEntity } from 'api/todolists-api'
|
||||||
|
|
||||||
type TaskPropsType = {
|
type TaskProps = {
|
||||||
task: TaskType
|
task: TaskEntity
|
||||||
todolistId: string
|
todolistId: string
|
||||||
changeTaskStatus: (
|
changeTaskStatus: (
|
||||||
id: string,
|
id: string,
|
||||||
@@ -19,7 +19,7 @@ type TaskPropsType = {
|
|||||||
) => void
|
) => void
|
||||||
removeTask: (taskId: string, todolistId: string) => void
|
removeTask: (taskId: string, todolistId: string) => void
|
||||||
}
|
}
|
||||||
export const Task = React.memo((props: TaskPropsType) => {
|
export const Task = React.memo((props: TaskProps) => {
|
||||||
const onClickHandler = useCallback(
|
const onClickHandler = useCallback(
|
||||||
() => props.removeTask(props.task.id, props.todolistId),
|
() => props.removeTask(props.task.id, props.todolistId),
|
||||||
[props.task.id, props.todolistId]
|
[props.task.id, props.todolistId]
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import React, { useCallback, useEffect } from 'react'
|
|||||||
import { AddItemForm } from 'components/AddItemForm/AddItemForm'
|
import { AddItemForm } from 'components/AddItemForm/AddItemForm'
|
||||||
import { EditableSpan } from 'components/EditableSpan/EditableSpan'
|
import { EditableSpan } from 'components/EditableSpan/EditableSpan'
|
||||||
import { Task } from './Task/Task'
|
import { Task } from './Task/Task'
|
||||||
import { TaskStatuses, TaskType } from 'api/todolists-api'
|
import { TaskStatuses, TaskEntity } from 'api/todolists-api'
|
||||||
import { FilterValuesType, TodolistDomainType } from '../todolists-reducer'
|
import { FilterValues, TodolistDomain } from '../todolists-reducer'
|
||||||
import { fetchTasksTC } from '../tasks-reducer'
|
import { fetchTasksTC } from '../tasks-reducer'
|
||||||
import { useAppDispatch } from 'hooks/useAppDispatch'
|
import { useAppDispatch } from 'hooks/useAppDispatch'
|
||||||
import { Button, IconButton } from '@mui/material'
|
import { Button, IconButton } from '@mui/material'
|
||||||
import { Delete } from '@mui/icons-material'
|
import { Delete } from '@mui/icons-material'
|
||||||
|
|
||||||
type PropsType = {
|
type Props = {
|
||||||
todolist: TodolistDomainType
|
todolist: TodolistDomain
|
||||||
tasks: Array<TaskType>
|
tasks: Array<TaskEntity>
|
||||||
changeFilter: (value: FilterValuesType, todolistId: string) => void
|
changeFilter: (value: FilterValues, todolistId: string) => void
|
||||||
addTask: (title: string, todolistId: string) => void
|
addTask: (title: string, todolistId: string) => void
|
||||||
changeTaskStatus: (
|
changeTaskStatus: (
|
||||||
id: string,
|
id: string,
|
||||||
@@ -33,7 +33,7 @@ type PropsType = {
|
|||||||
export const Todolist = React.memo(function ({
|
export const Todolist = React.memo(function ({
|
||||||
demo = false,
|
demo = false,
|
||||||
...props
|
...props
|
||||||
}: PropsType) {
|
}: Props) {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import React, { useCallback, useEffect } from 'react'
|
import React, { useCallback, useEffect } from 'react'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { AppRootStateType } from 'app/store'
|
import { AppRootState } from 'app/store'
|
||||||
import {
|
import {
|
||||||
addTodolistTC,
|
addTodolistTC,
|
||||||
changeTodolistFilter,
|
changeTodolistFilter,
|
||||||
changeTodolistTitleTC,
|
changeTodolistTitleTC,
|
||||||
fetchTodolistsTC,
|
fetchTodolistsTC,
|
||||||
FilterValuesType,
|
FilterValues,
|
||||||
removeTodolistTC,
|
removeTodolistTC,
|
||||||
TodolistDomainType,
|
TodolistDomain,
|
||||||
} from './todolists-reducer'
|
} from './todolists-reducer'
|
||||||
import {
|
import {
|
||||||
addTaskTC,
|
addTaskTC,
|
||||||
removeTaskTC,
|
removeTaskTC,
|
||||||
TasksStateType,
|
TasksState,
|
||||||
updateTaskTC,
|
updateTaskTC,
|
||||||
} from './tasks-reducer'
|
} from './tasks-reducer'
|
||||||
import { TaskStatuses } from 'api/todolists-api'
|
import { TaskStatuses } from 'api/todolists-api'
|
||||||
@@ -23,18 +23,16 @@ import { Todolist } from './Todolist/Todolist'
|
|||||||
import { Navigate } from 'react-router-dom'
|
import { Navigate } from 'react-router-dom'
|
||||||
import { useAppDispatch } from 'hooks/useAppDispatch'
|
import { useAppDispatch } from 'hooks/useAppDispatch'
|
||||||
|
|
||||||
type PropsType = {
|
type Props = {
|
||||||
demo?: boolean
|
demo?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TodolistsList: React.FC<PropsType> = ({ demo = false }) => {
|
export const TodolistsList: React.FC<Props> = ({ demo = false }) => {
|
||||||
const todolists = useSelector<AppRootStateType, Array<TodolistDomainType>>(
|
const todolists = useSelector<AppRootState, Array<TodolistDomain>>(
|
||||||
(state) => state.todolists
|
(state) => state.todolists
|
||||||
)
|
)
|
||||||
const tasks = useSelector<AppRootStateType, TasksStateType>(
|
const tasks = useSelector<AppRootState, TasksState>((state) => state.tasks)
|
||||||
(state) => state.tasks
|
const isLoggedIn = useSelector<AppRootState, boolean>(
|
||||||
)
|
|
||||||
const isLoggedIn = useSelector<AppRootStateType, boolean>(
|
|
||||||
(state) => state.auth.isLoggedIn
|
(state) => state.auth.isLoggedIn
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ export const TodolistsList: React.FC<PropsType> = ({ demo = false }) => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const changeFilter = useCallback(function (
|
const changeFilter = useCallback(function (
|
||||||
value: FilterValuesType,
|
value: FilterValues,
|
||||||
todolistId: string
|
todolistId: string
|
||||||
) {
|
) {
|
||||||
const action = changeTodolistFilter({ id: todolistId, filter: value })
|
const action = changeTodolistFilter({ id: todolistId, filter: value })
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import {
|
|||||||
removeTask,
|
removeTask,
|
||||||
setTasks,
|
setTasks,
|
||||||
tasksReducer,
|
tasksReducer,
|
||||||
TasksStateType,
|
TasksState,
|
||||||
updateTask,
|
updateTask,
|
||||||
} from './tasks-reducer'
|
} from './tasks-reducer'
|
||||||
|
|
||||||
import { addTodolist, removeTodolist, setTodolists } from './todolists-reducer'
|
import { addTodolist, removeTodolist, setTodolists } from './todolists-reducer'
|
||||||
import { TaskPriorities, TaskStatuses } from 'api/todolists-api'
|
import { TaskPriorities, TaskStatuses } from 'api/todolists-api'
|
||||||
|
|
||||||
let startState: TasksStateType = {}
|
let startState: TasksState = {}
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
startState = {
|
startState = {
|
||||||
todolistId1: [
|
todolistId1: [
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
TaskPriorities,
|
TaskPriorities,
|
||||||
TaskStatuses,
|
TaskStatuses,
|
||||||
TaskType,
|
TaskEntity,
|
||||||
todolistsAPI,
|
todolistsAPI,
|
||||||
UpdateTaskModelType,
|
UpdateTaskModel,
|
||||||
} from 'api/todolists-api'
|
} from 'api/todolists-api'
|
||||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
import {
|
import {
|
||||||
@@ -11,14 +11,14 @@ import {
|
|||||||
removeTodolist,
|
removeTodolist,
|
||||||
setTodolists,
|
setTodolists,
|
||||||
} from 'features/TodolistsList/todolists-reducer'
|
} from 'features/TodolistsList/todolists-reducer'
|
||||||
import { AppRootStateType, AppThunk } from 'app/store'
|
import { AppRootState, AppThunk } from 'app/store'
|
||||||
import { setAppStatus } from 'app/app-reducer'
|
import { setAppStatus } from 'app/app-reducer'
|
||||||
import {
|
import {
|
||||||
handleServerAppError,
|
handleServerAppError,
|
||||||
handleServerNetworkError,
|
handleServerNetworkError,
|
||||||
} from 'utils/error-utils'
|
} from 'utils/error-utils'
|
||||||
|
|
||||||
export type UpdateDomainTaskModelType = {
|
export type UpdateDomainTaskModel = {
|
||||||
title?: string
|
title?: string
|
||||||
description?: string
|
description?: string
|
||||||
status?: TaskStatuses
|
status?: TaskStatuses
|
||||||
@@ -27,11 +27,11 @@ export type UpdateDomainTaskModelType = {
|
|||||||
deadline?: string
|
deadline?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TasksStateType = {
|
export type TasksState = {
|
||||||
[key: string]: Array<TaskType>
|
[key: string]: Array<TaskEntity>
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: TasksStateType = {}
|
const initialState: TasksState = {}
|
||||||
|
|
||||||
const tasksSlice = createSlice({
|
const tasksSlice = createSlice({
|
||||||
name: 'tasks',
|
name: 'tasks',
|
||||||
@@ -51,7 +51,7 @@ const tasksSlice = createSlice({
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addTask(state, action: PayloadAction<TaskType>) {
|
addTask(state, action: PayloadAction<TaskEntity>) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[action.payload.todoListId]: [
|
[action.payload.todoListId]: [
|
||||||
@@ -64,7 +64,7 @@ const tasksSlice = createSlice({
|
|||||||
state,
|
state,
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
taskId: string
|
taskId: string
|
||||||
model: UpdateDomainTaskModelType
|
model: UpdateDomainTaskModel
|
||||||
todolistId: string
|
todolistId: string
|
||||||
}>
|
}>
|
||||||
) {
|
) {
|
||||||
@@ -81,7 +81,7 @@ const tasksSlice = createSlice({
|
|||||||
setTasks(
|
setTasks(
|
||||||
state,
|
state,
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
tasks: Array<TaskType>
|
tasks: Array<TaskEntity>
|
||||||
todolistId: string
|
todolistId: string
|
||||||
}>
|
}>
|
||||||
) {
|
) {
|
||||||
@@ -156,10 +156,10 @@ export const addTaskTC =
|
|||||||
export const updateTaskTC =
|
export const updateTaskTC =
|
||||||
(
|
(
|
||||||
taskId: string,
|
taskId: string,
|
||||||
domainModel: UpdateDomainTaskModelType,
|
domainModel: UpdateDomainTaskModel,
|
||||||
todolistId: string
|
todolistId: string
|
||||||
): AppThunk =>
|
): AppThunk =>
|
||||||
(dispatch, getState: () => AppRootStateType) => {
|
(dispatch, getState: () => AppRootState) => {
|
||||||
const state = getState()
|
const state = getState()
|
||||||
const task = state.tasks[todolistId].find((t) => t.id === taskId)
|
const task = state.tasks[todolistId].find((t) => t.id === taskId)
|
||||||
if (!task) {
|
if (!task) {
|
||||||
@@ -168,7 +168,7 @@ export const updateTaskTC =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiModel: UpdateTaskModelType = {
|
const apiModel: UpdateTaskModel = {
|
||||||
deadline: task.deadline,
|
deadline: task.deadline,
|
||||||
description: task.description,
|
description: task.description,
|
||||||
priority: task.priority,
|
priority: task.priority,
|
||||||
|
|||||||
@@ -3,19 +3,19 @@ import {
|
|||||||
changeTodolistEntityStatus,
|
changeTodolistEntityStatus,
|
||||||
changeTodolistFilter,
|
changeTodolistFilter,
|
||||||
changeTodolistTitle,
|
changeTodolistTitle,
|
||||||
FilterValuesType,
|
FilterValues,
|
||||||
removeTodolist,
|
removeTodolist,
|
||||||
setTodolists,
|
setTodolists,
|
||||||
TodolistDomainType,
|
TodolistDomain,
|
||||||
todolistsReducer,
|
todolistsReducer,
|
||||||
} from './todolists-reducer'
|
} from './todolists-reducer'
|
||||||
import { v1 } from 'uuid'
|
import { v1 } from 'uuid'
|
||||||
import { TodolistType } from 'api/todolists-api'
|
import { Todolist } from 'api/todolists-api'
|
||||||
import { RequestStatusType } from 'app/app-reducer'
|
import { RequestStatus } from 'app/app-reducer'
|
||||||
|
|
||||||
let todolistId1: string
|
let todolistId1: string
|
||||||
let todolistId2: string
|
let todolistId2: string
|
||||||
let startState: Array<TodolistDomainType> = []
|
let startState: Array<TodolistDomain> = []
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
todolistId1 = v1()
|
todolistId1 = v1()
|
||||||
@@ -48,7 +48,7 @@ test('correct todolist should be removed', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('correct todolist should be added', () => {
|
test('correct todolist should be added', () => {
|
||||||
let todolist: TodolistType = {
|
let todolist: Todolist = {
|
||||||
title: 'New Todolist',
|
title: 'New Todolist',
|
||||||
id: 'any id',
|
id: 'any id',
|
||||||
addedDate: '',
|
addedDate: '',
|
||||||
@@ -77,7 +77,7 @@ test('correct todolist should change its name', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('correct filter of todolist should be changed', () => {
|
test('correct filter of todolist should be changed', () => {
|
||||||
let newFilter: FilterValuesType = 'completed'
|
let newFilter: FilterValues = 'completed'
|
||||||
|
|
||||||
const action = changeTodolistFilter({ id: todolistId2, filter: newFilter })
|
const action = changeTodolistFilter({ id: todolistId2, filter: newFilter })
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ test('todolists should be added', () => {
|
|||||||
expect(endState.length).toBe(2)
|
expect(endState.length).toBe(2)
|
||||||
})
|
})
|
||||||
test('correct entity status of todolist should be changed', () => {
|
test('correct entity status of todolist should be changed', () => {
|
||||||
let newStatus: RequestStatusType = 'loading'
|
let newStatus: RequestStatus = 'loading'
|
||||||
|
|
||||||
const action = changeTodolistEntityStatus({
|
const action = changeTodolistEntityStatus({
|
||||||
id: todolistId2,
|
id: todolistId2,
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
import { todolistsAPI, TodolistType } from 'api/todolists-api'
|
import { todolistsAPI, Todolist } from 'api/todolists-api'
|
||||||
import { RequestStatusType, setAppStatus } from 'app/app-reducer'
|
import { RequestStatus, setAppStatus } from 'app/app-reducer'
|
||||||
import { AppThunk } from 'app/store'
|
import { AppThunk } from 'app/store'
|
||||||
import { handleServerNetworkError } from 'utils/error-utils'
|
import { handleServerNetworkError } from 'utils/error-utils'
|
||||||
|
|
||||||
export type FilterValuesType = 'all' | 'active' | 'completed'
|
export type FilterValues = 'all' | 'active' | 'completed'
|
||||||
export type TodolistDomainType = TodolistType & {
|
export type TodolistDomain = Todolist & {
|
||||||
filter: FilterValuesType
|
filter: FilterValues
|
||||||
entityStatus: RequestStatusType
|
entityStatus: RequestStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: Array<TodolistDomainType> = []
|
const initialState: Array<TodolistDomain> = []
|
||||||
|
|
||||||
const todolistsSlice = createSlice({
|
const todolistsSlice = createSlice({
|
||||||
name: 'todolists',
|
name: 'todolists',
|
||||||
@@ -19,7 +19,7 @@ const todolistsSlice = createSlice({
|
|||||||
removeTodolist(state, action: PayloadAction<string>) {
|
removeTodolist(state, action: PayloadAction<string>) {
|
||||||
return state.filter((tl) => tl.id != action.payload)
|
return state.filter((tl) => tl.id != action.payload)
|
||||||
},
|
},
|
||||||
addTodolist(state, action: PayloadAction<TodolistType>) {
|
addTodolist(state, action: PayloadAction<Todolist>) {
|
||||||
return [
|
return [
|
||||||
{ ...action.payload, filter: 'all', entityStatus: 'idle' },
|
{ ...action.payload, filter: 'all', entityStatus: 'idle' },
|
||||||
...state,
|
...state,
|
||||||
@@ -42,7 +42,7 @@ const todolistsSlice = createSlice({
|
|||||||
state,
|
state,
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
id: string
|
id: string
|
||||||
filter: FilterValuesType
|
filter: FilterValues
|
||||||
}>
|
}>
|
||||||
) {
|
) {
|
||||||
return state.map((tl) =>
|
return state.map((tl) =>
|
||||||
@@ -55,7 +55,7 @@ const todolistsSlice = createSlice({
|
|||||||
state,
|
state,
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
id: string
|
id: string
|
||||||
status: RequestStatusType
|
status: RequestStatus
|
||||||
}>
|
}>
|
||||||
) {
|
) {
|
||||||
return state.map((tl) =>
|
return state.map((tl) =>
|
||||||
@@ -64,7 +64,7 @@ const todolistsSlice = createSlice({
|
|||||||
: tl
|
: tl
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
setTodolists(state, action: PayloadAction<Array<TodolistType>>) {
|
setTodolists(state, action: PayloadAction<Array<Todolist>>) {
|
||||||
return action.payload.map((tl) => ({
|
return action.payload.map((tl) => ({
|
||||||
...tl,
|
...tl,
|
||||||
filter: 'all',
|
filter: 'all',
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import {
|
import {
|
||||||
addTodolist,
|
addTodolist,
|
||||||
TodolistDomainType,
|
TodolistDomain,
|
||||||
todolistsReducer,
|
todolistsReducer,
|
||||||
} from './todolists-reducer'
|
} from './todolists-reducer'
|
||||||
import { tasksReducer, TasksStateType } from './tasks-reducer'
|
import { tasksReducer, TasksState } from './tasks-reducer'
|
||||||
import { TodolistType } from 'api/todolists-api'
|
import { Todolist } from 'api/todolists-api'
|
||||||
|
|
||||||
test('ids should be equals', () => {
|
test('ids should be equals', () => {
|
||||||
const startTasksState: TasksStateType = {}
|
const startTasksState: TasksState = {}
|
||||||
const startTodolistsState: Array<TodolistDomainType> = []
|
const startTodolistsState: Array<TodolistDomain> = []
|
||||||
|
|
||||||
let todolist: TodolistType = {
|
let todolist: Todolist = {
|
||||||
title: 'new todolist',
|
title: 'new todolist',
|
||||||
id: 'any id',
|
id: 'any id',
|
||||||
addedDate: '',
|
addedDate: '',
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { setAppError, setAppStatus } from 'app/app-reducer'
|
import { setAppError, setAppStatus } from 'app/app-reducer'
|
||||||
import { ResponseType } from 'api/todolists-api'
|
import { Response } from 'api/todolists-api'
|
||||||
import { Dispatch } from 'redux'
|
import { Dispatch } from 'redux'
|
||||||
|
|
||||||
export const handleServerAppError = <D>(
|
export const handleServerAppError = <D>(
|
||||||
data: ResponseType<D>,
|
data: Response<D>,
|
||||||
dispatch: Dispatch
|
dispatch: Dispatch
|
||||||
) => {
|
) => {
|
||||||
if (data.messages.length) {
|
if (data.messages.length) {
|
||||||
|
|||||||
Reference in New Issue
Block a user