Skip to content
40 changes: 38 additions & 2 deletions client/src/api/boards.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,25 @@ import http from './http';
import socket from './socket';
import { transformCard } from './cards';
import { transformAttachment } from './attachments';
import { getAccessToken } from '../utils/access-token-storage';
import Config from '../constants/Config';

/* Actions */

const createBoard = (projectId, data, headers) =>
socket.post(`/projects/${projectId}/boards`, data, headers);

const createBoardWithImport = (projectId, data, requestId, headers) =>
http.post(`/projects/${projectId}/boards?requestId=${requestId}`, data, headers);
const createBoardWithImport = (projectId, data, requestId, headers) => {
const { importMapping, ...formDataFields } = data;

let url = `/projects/${projectId}/boards?requestId=${requestId}`;
if (importMapping) {
url += `&importMapping=${encodeURIComponent(importMapping)}`;
}

return http.post(url, formDataFields, headers);
}


const getBoard = (id, subscribe, headers) =>
socket
Expand All @@ -32,10 +43,35 @@ const updateBoard = (id, data, headers) => socket.patch(`/boards/${id}`, data, h

const deleteBoard = (id, headers) => socket.delete(`/boards/${id}`, undefined, headers);

const previewFocalboardImport = (file) => {
const accessToken = getAccessToken();

const formData = new FormData();
formData.append('file', file);

return fetch(`${Config.SERVER_BASE_URL}/api/focalboard/preview`, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: formData,
credentials: 'include',
})
.then((response) => {
if (!response.ok) {
return response.json().then((body) => {
throw body;
});
}
return response.json();
});
};

export default {
createBoard,
createBoardWithImport,
getBoard,
updateBoard,
deleteBoard,
previewFocalboardImport,
};
12 changes: 6 additions & 6 deletions client/src/api/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ const http = {};
// TODO: add all methods
['GET', 'POST', 'DELETE'].forEach((method) => {
http[method.toLowerCase()] = (url, data, headers) => {
const formData =
data &&
Object.keys(data).reduce((result, key) => {
result.append(key, data[key]);

return result;
}, new FormData());
const formData =
data &&
Object.keys(data).reduce((result, key) => {
result.append(key, data[key]);
return result;
}, new FormData());

return fetch(`${Config.SERVER_BASE_URL}/api${url}`, {
method,
Expand Down
21 changes: 20 additions & 1 deletion client/src/components/boards/AddBoardStep/AddBoardStep.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const StepTypes = {
IMPORT: 'IMPORT',
};

const IMPORT_TYPE_ICONS = {
trello: 'trello',
focalboard: 'file',
};

const AddBoardStep = React.memo(({ onClose }) => {
const dispatch = useDispatch();
const [t] = useTranslation();
Expand All @@ -47,6 +52,17 @@ const AddBoardStep = React.memo(({ onClose }) => {
return;
}

// Transform import data for API
if (cleanData.import) {
const { type, file, mapping } = cleanData.import;
cleanData.import = {
type,
file,
// Include mapping for Focalboard imports
...(mapping && { mapping }),
};
}

dispatch(entryActions.createBoardInCurrentProject(cleanData));
onClose();
}, [onClose, dispatch, data, nameFieldRef]);
Expand All @@ -56,6 +72,7 @@ const AddBoardStep = React.memo(({ onClose }) => {
setData((prevData) => ({
...prevData,
import: nextImport,
name: nextImport.boardTitle || prevData.name,
}));
},
[setData],
Expand Down Expand Up @@ -84,6 +101,8 @@ const AddBoardStep = React.memo(({ onClose }) => {
return <ImportStep onSelect={handleImportSelect} onBack={handleImportBack} />;
}

const importIconName = data.import ? (IMPORT_TYPE_ICONS[data.import.type] || 'file') : 'arrow down';

return (
<>
<Popup.Header>
Expand Down Expand Up @@ -111,7 +130,7 @@ const AddBoardStep = React.memo(({ onClose }) => {
onClick={handleImportClick}
>
<Icon
name={data.import ? data.import.type : 'arrow down'}
name={importIconName}
className={styles.importButtonIcon}
/>
{data.import ? data.import.file.name : t('action.import')}
Expand Down
Loading