Add Boards management to sitesettings (#107)

This commit is contained in:
Riccardo Graziosi
2022-05-08 16:36:35 +02:00
committed by GitHub
parent 7b8a4d6709
commit 6be2394dc5
44 changed files with 1464 additions and 112 deletions

View File

@@ -0,0 +1,69 @@
import { Action } from "redux";
import { ThunkAction } from "redux-thunk";
import HttpStatus from "../../constants/http_status";
import buildRequestHeaders from "../../helpers/buildRequestHeaders";
import { State } from "../../reducers/rootReducer";
export const BOARD_DELETE_START = 'BOARD_DELETE_START';
interface BoardDeleteStartAction {
type: typeof BOARD_DELETE_START;
}
export const BOARD_DELETE_SUCCESS = 'BOARD_DELETE_SUCCESS';
interface BoardDeleteSuccessAction {
type: typeof BOARD_DELETE_SUCCESS;
id: number;
}
export const BOARD_DELETE_FAILURE = 'BOARD_DELETE_FAILURE';
interface BoardDeleteFailureAction {
type: typeof BOARD_DELETE_FAILURE;
error: string;
}
export type BoardDeleteActionTypes =
BoardDeleteStartAction |
BoardDeleteSuccessAction |
BoardDeleteFailureAction;
const boardDeleteStart = (): BoardDeleteStartAction => ({
type: BOARD_DELETE_START,
});
const boardDeleteSuccess = (
id: number,
): BoardDeleteSuccessAction => ({
type: BOARD_DELETE_SUCCESS,
id,
});
const boardDeleteFailure = (error: string): BoardDeleteFailureAction => ({
type: BOARD_DELETE_FAILURE,
error,
});
export const deleteBoard = (
id: number,
authenticityToken: string,
): ThunkAction<void, State, null, Action<string>> => (
async (dispatch) => {
dispatch(boardDeleteStart());
try {
const res = await fetch(`/boards/${id}`, {
method: 'DELETE',
headers: buildRequestHeaders(authenticityToken),
});
const json = await res.json();
if (res.status === HttpStatus.Accepted) {
dispatch(boardDeleteSuccess(id));
} else {
dispatch(boardDeleteFailure(json.error));
}
} catch (e) {
dispatch(boardDeleteFailure(e));
}
}
);

View File

@@ -0,0 +1,59 @@
import { Action } from 'redux';
import { ThunkAction } from 'redux-thunk';
import IBoard from '../../interfaces/IBoard';
import { State } from '../../reducers/rootReducer';
export const BOARDS_REQUEST_START = 'BOARDS_REQUEST_START';
interface BoardsRequestStartAction {
type: typeof BOARDS_REQUEST_START;
}
export const BOARDS_REQUEST_SUCCESS = 'BOARDS_REQUEST_SUCCESS';
interface BoardsRequestSuccessAction {
type: typeof BOARDS_REQUEST_SUCCESS;
boards: Array<IBoard>;
}
export const BOARDS_REQUEST_FAILURE = 'BOARDS_REQUEST_FAILURE';
interface BoardsRequestFailureAction {
type: typeof BOARDS_REQUEST_FAILURE;
error: string;
}
export type BoardsRequestActionTypes =
BoardsRequestStartAction |
BoardsRequestSuccessAction |
BoardsRequestFailureAction;
const boardsRequestStart = (): BoardsRequestActionTypes => ({
type: BOARDS_REQUEST_START,
});
const boardsRequestSuccess = (
boards: Array<IBoard>
): BoardsRequestActionTypes => ({
type: BOARDS_REQUEST_SUCCESS,
boards,
});
const boardsRequestFailure = (error: string): BoardsRequestActionTypes => ({
type: BOARDS_REQUEST_FAILURE,
error,
});
export const requestBoards = (): ThunkAction<void, State, null, Action<string>> => (
async (dispatch) => {
dispatch(boardsRequestStart());
try {
const response = await fetch('/boards');
const json = await response.json();
dispatch(boardsRequestSuccess(json));
} catch (e) {
dispatch(boardsRequestFailure(e));
}
}
)

View File

@@ -0,0 +1,79 @@
import { Action } from "redux";
import { ThunkAction } from "redux-thunk";
import HttpStatus from "../../constants/http_status";
import buildRequestHeaders from "../../helpers/buildRequestHeaders";
import IBoardJSON from "../../interfaces/json/IBoard";
import { State } from "../../reducers/rootReducer";
export const BOARD_SUBMIT_START = 'BOARD_SUBMIT_START';
interface BoardSubmitStartAction {
type: typeof BOARD_SUBMIT_START;
}
export const BOARD_SUBMIT_SUCCESS = 'BOARD_SUBMIT_SUCCESS';
interface BoardSubmitSuccessAction {
type: typeof BOARD_SUBMIT_SUCCESS;
board: IBoardJSON;
}
export const BOARD_SUBMIT_FAILURE = 'BOARD_SUBMIT_FAILURE';
interface BoardSubmitFailureAction {
type: typeof BOARD_SUBMIT_FAILURE;
error: string;
}
export type BoardSubmitActionTypes =
BoardSubmitStartAction |
BoardSubmitSuccessAction |
BoardSubmitFailureAction;
const boardSubmitStart = (): BoardSubmitStartAction => ({
type: BOARD_SUBMIT_START,
});
const boardSubmitSuccess = (
boardJSON: IBoardJSON,
): BoardSubmitSuccessAction => ({
type: BOARD_SUBMIT_SUCCESS,
board: boardJSON,
});
const boardSubmitFailure = (error: string): BoardSubmitFailureAction => ({
type: BOARD_SUBMIT_FAILURE,
error,
});
export const submitBoard = (
name: string,
description: string,
authenticityToken: string,
): ThunkAction<void, State, null, Action<string>> => async (dispatch) => {
dispatch(boardSubmitStart());
try {
const res = await fetch(`/boards`, {
method: 'POST',
headers: buildRequestHeaders(authenticityToken),
body: JSON.stringify({
board: {
name,
description,
},
}),
});
const json = await res.json();
if (res.status === HttpStatus.Created) {
dispatch(boardSubmitSuccess(json));
} else {
dispatch(boardSubmitFailure(json.error));
}
return Promise.resolve(res);
} catch (e) {
dispatch(boardSubmitFailure(e));
return Promise.resolve(null);
}
};

View File

@@ -0,0 +1,80 @@
import { Action } from "redux";
import { ThunkAction } from "redux-thunk";
import HttpStatus from "../../constants/http_status";
import buildRequestHeaders from "../../helpers/buildRequestHeaders";
import IBoardJSON from "../../interfaces/json/IBoard";
import { State } from "../../reducers/rootReducer";
export const BOARD_UPDATE_START = 'BOARD_UPDATE_START';
interface BoardUpdateStartAction {
type: typeof BOARD_UPDATE_START;
}
export const BOARD_UPDATE_SUCCESS = 'BOARD_UPDATE_SUCCESS';
interface BoardUpdateSuccessAction {
type: typeof BOARD_UPDATE_SUCCESS;
board: IBoardJSON;
}
export const BOARD_UPDATE_FAILURE = 'BOARD_UPDATE_FAILURE';
interface BoardUpdateFailureAction {
type: typeof BOARD_UPDATE_FAILURE;
error: string;
}
export type BoardUpdateActionTypes =
BoardUpdateStartAction |
BoardUpdateSuccessAction |
BoardUpdateFailureAction;
const boardUpdateStart = (): BoardUpdateStartAction => ({
type: BOARD_UPDATE_START,
});
const boardUpdateSuccess = (
boardJSON: IBoardJSON,
): BoardUpdateSuccessAction => ({
type: BOARD_UPDATE_SUCCESS,
board: boardJSON,
});
const boardUpdateFailure = (error: string): BoardUpdateFailureAction => ({
type: BOARD_UPDATE_FAILURE,
error,
});
export const updateBoard = (
id: number,
name: string,
description: string,
authenticityToken: string,
): ThunkAction<void, State, null, Action<string>> => async (dispatch) => {
dispatch(boardUpdateStart());
try {
const res = await fetch(`/boards/${id}`, {
method: 'PATCH',
headers: buildRequestHeaders(authenticityToken),
body: JSON.stringify({
board: {
name,
description,
},
}),
});
const json = await res.json();
if (res.status === HttpStatus.OK) {
dispatch(boardUpdateSuccess(json));
} else {
dispatch(boardUpdateFailure(json.error));
}
return Promise.resolve(res);
} catch (e) {
dispatch(boardUpdateFailure(e));
return Promise.resolve(null);
}
};

View File

@@ -0,0 +1,89 @@
import { Action } from "redux";
import { ThunkAction } from "redux-thunk";
import HttpStatus from "../../constants/http_status";
import buildRequestHeaders from "../../helpers/buildRequestHeaders";
import createNewOrdering from "../../helpers/createNewOrdering";
import IBoard from "../../interfaces/IBoard";
import { State } from "../../reducers/rootReducer";
export const BOARD_ORDER_UPDATE_START = 'BOARD_ORDER_UPDATE_START';
interface BoardOrderUpdateStartAction {
type: typeof BOARD_ORDER_UPDATE_START;
newOrder: Array<IBoard>;
}
export const BOARD_ORDER_UPDATE_SUCCESS = 'BOARD_ORDER_UPDATE_SUCCESS';
interface BoardOrderUpdateSuccessAction {
type: typeof BOARD_ORDER_UPDATE_SUCCESS;
}
export const BOARD_ORDER_UPDATE_FAILURE = 'BOARD_ORDER_UPDATE_FAILURE';
interface BoardOrderUpdateFailureAction {
type: typeof BOARD_ORDER_UPDATE_FAILURE;
error: string;
oldOrder: Array<IBoard>;
}
export type BoardOrderUpdateActionTypes =
BoardOrderUpdateStartAction |
BoardOrderUpdateSuccessAction |
BoardOrderUpdateFailureAction;
const boardOrderUpdateStart = (
newOrder: Array<IBoard>
): BoardOrderUpdateStartAction => ({
type: BOARD_ORDER_UPDATE_START,
newOrder,
});
const boardOrderUpdateSuccess = (): BoardOrderUpdateSuccessAction => ({
type: BOARD_ORDER_UPDATE_SUCCESS,
});
const boardOrderUpdateFailure = (
error: string,
oldOrder: Array<IBoard>
): BoardOrderUpdateFailureAction => ({
type: BOARD_ORDER_UPDATE_FAILURE,
error,
oldOrder,
});
export const updateBoardOrder = (
id: number,
boards: Array<IBoard>,
sourceIndex: number,
destinationIndex: number,
authenticityToken: string,
): ThunkAction<void, State, null, Action<string>> => async (dispatch) => {
const oldOrder = boards;
let newOrder = createNewOrdering(boards, sourceIndex, destinationIndex);
dispatch(boardOrderUpdateStart(newOrder));
try {
const res = await fetch(`/boards/update_order`, {
method: 'PATCH',
headers: buildRequestHeaders(authenticityToken),
body: JSON.stringify({
board: {
id: id,
src_index: sourceIndex,
dst_index: destinationIndex,
},
}),
});
const json = await res.json();
if (res.status === HttpStatus.OK) {
dispatch(boardOrderUpdateSuccess());
} else {
dispatch(boardOrderUpdateFailure(json.error, oldOrder));
}
} catch (e) {
dispatch(boardOrderUpdateFailure(e, oldOrder));
}
};

View File

@@ -1,5 +1,6 @@
import { Action } from "redux";
import { ThunkAction } from "redux-thunk";
import HttpStatus from "../../constants/http_status";
import buildRequestHeaders from "../../helpers/buildRequestHeaders";
import { State } from "../../reducers/rootReducer";
@@ -49,12 +50,17 @@ export const deletePostStatus = (
dispatch(postStatusDeleteStart());
try {
const response = await fetch(`/post_statuses/${id}`, {
const res = await fetch(`/post_statuses/${id}`, {
method: 'DELETE',
headers: buildRequestHeaders(authenticityToken),
});
const json = await response.json();
dispatch(postStatusDeleteSuccess(id));
const json = await res.json();
if (res.status === HttpStatus.Accepted) {
dispatch(postStatusDeleteSuccess(id));
} else {
dispatch(postStatusDeleteFailure(json.error));
}
} catch (e) {
dispatch(postStatusDeleteFailure(e));
}

View File

@@ -25,7 +25,7 @@ interface PostStatusesRequestFailureAction {
export type PostStatusesRequestActionTypes =
PostStatusesRequestStartAction |
PostStatusesRequestSuccessAction |
PostStatusesRequestFailureAction
PostStatusesRequestFailureAction;
const postStatusesRequestStart = (): PostStatusesRequestActionTypes => ({

View File

@@ -3,6 +3,7 @@ import { ThunkAction } from "redux-thunk";
import HttpStatus from "../../constants/http_status";
import buildRequestHeaders from "../../helpers/buildRequestHeaders";
import createNewOrdering from "../../helpers/createNewOrdering";
import IPostStatus from "../../interfaces/IPostStatus";
import { State } from "../../reducers/rootReducer";
@@ -21,6 +22,7 @@ export const POSTSTATUS_ORDER_UPDATE_FAILURE = 'POSTSTATUS_ORDER_UPDATE_FAILURE'
interface PostStatusOrderUpdateFailureAction {
type: typeof POSTSTATUS_ORDER_UPDATE_FAILURE;
error: string;
oldOrder: Array<IPostStatus>;
}
export type PostStatusOrderUpdateActionTypes =
@@ -40,10 +42,12 @@ const postStatusOrderUpdateSuccess = (): PostStatusOrderUpdateSuccessAction => (
});
const postStatusOrderUpdateFailure = (
error: string
error: string,
oldOrder: Array<IPostStatus>
): PostStatusOrderUpdateFailureAction => ({
type: POSTSTATUS_ORDER_UPDATE_FAILURE,
error,
oldOrder,
});
export const updatePostStatusOrder = (
@@ -54,7 +58,8 @@ export const updatePostStatusOrder = (
authenticityToken: string,
): ThunkAction<void, State, null, Action<string>> => async (dispatch) => {
let newOrder = createNewOrder(postStatuses, sourceIndex, destinationIndex);
const oldOrder = postStatuses;
let newOrder = createNewOrdering(postStatuses, sourceIndex, destinationIndex);
dispatch(postStatusOrderUpdateStart(newOrder));
@@ -75,22 +80,10 @@ export const updatePostStatusOrder = (
if (res.status === HttpStatus.OK) {
dispatch(postStatusOrderUpdateSuccess());
} else {
dispatch(postStatusOrderUpdateFailure(json.error));
dispatch(postStatusOrderUpdateFailure(json.error, oldOrder));
}
} catch (e) {
dispatch(postStatusOrderUpdateFailure(e));
dispatch(postStatusOrderUpdateFailure(e, oldOrder));
}
};
function createNewOrder(
oldOrder: Array<IPostStatus>,
sourceIndex: number,
destinationIndex: number
) {
let newOrder = JSON.parse(JSON.stringify(oldOrder));
const [reorderedItem] = newOrder.splice(sourceIndex, 1);
newOrder.splice(destinationIndex, 0, reorderedItem);
return newOrder;
}