diff --git a/packages/webapp/src/client/index.ts b/packages/webapp/src/client/index.ts index 3ffe1658..039465d8 100644 --- a/packages/webapp/src/client/index.ts +++ b/packages/webapp/src/client/index.ts @@ -6,6 +6,13 @@ export type NewUser = { recaptcha: string | null; } +export type ImportMapInfo = { + title: string; + description?: string; + contentType?: string; + content?: ArrayBuffer | null | string; + +} export type Label = { id: number; title: string; @@ -55,6 +62,7 @@ export type AccountInfo = { } interface Client { + importMap(model: ImportMapInfo): Promise createMap(map: BasicMapInfo): Promise; deleteMaps(ids: number[]): Promise; deleteMap(id: number): Promise; @@ -67,7 +75,7 @@ interface Client { fetchLabels(): Promise; deleteLabel(id: number): Promise; - fetchAccountInfo():Promise; + fetchAccountInfo(): Promise; registerNewUser(user: NewUser): Promise; resetPassword(email: string): Promise; diff --git a/packages/webapp/src/client/mock-client/index.ts b/packages/webapp/src/client/mock-client/index.ts index d8b0c36e..a0bb2548 100644 --- a/packages/webapp/src/client/mock-client/index.ts +++ b/packages/webapp/src/client/mock-client/index.ts @@ -1,5 +1,4 @@ -import Client, { AccountInfo, BasicMapInfo, ChangeHistory, Label, MapInfo, NewUser } from '..'; - +import Client, { AccountInfo, BasicMapInfo, ChangeHistory, ImportMapInfo, Label, MapInfo, NewUser} from '..'; class MockClient implements Client { private maps: MapInfo[] = []; private labels: Label[] = []; @@ -8,7 +7,7 @@ class MockClient implements Client { // Remove, just for develop .... function createMapInfo( - id: number, + id: number, starred: boolean, title: string, labels: number[], @@ -34,6 +33,10 @@ class MockClient implements Client { ]; } + importMap(model: ImportMapInfo): Promise { + return Promise.resolve(10); + } + fetchAccountInfo(): Promise { return Promise.resolve({ firstName: 'Costme', diff --git a/packages/webapp/src/client/rest-client/index.ts b/packages/webapp/src/client/rest-client/index.ts index 5889b8e3..97846411 100644 --- a/packages/webapp/src/client/rest-client/index.ts +++ b/packages/webapp/src/client/rest-client/index.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import Client, { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label, ChangeHistory, AccountInfo } from '..'; +import Client, { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label, ChangeHistory, AccountInfo, ImportMapInfo } from '..'; export default class RestClient implements Client { private baseUrl: string; @@ -9,6 +9,20 @@ export default class RestClient implements Client { this.baseUrl = baseUrl; this.sessionExpired = sessionExpired; } + importMap(model: ImportMapInfo): Promise { + const handler = (success: (mapId: number) => void, reject: (error: ErrorInfo) => void) => { + axios.post(this.baseUrl + `/c/restful/maps?title=${model.title}&description=${model.description ? model.description : ''}`, + model.content, + { headers: { 'Content-Type': model.contentType } } + ).then(response => { + const mapId = response.headers.resourceid; + success(mapId); + }).catch(error => { + const errorInfo = this.parseResponseOnError(error.response); + reject(errorInfo); + }); + } + return new Promise(handler); } fetchAccountInfo(): Promise { const handler = (success: (account: AccountInfo) => void, reject: (error: ErrorInfo) => void) => { diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/base-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/base-dialog/index.tsx index 5f5cf3b0..beb12bef 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/base-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/base-dialog/index.tsx @@ -13,12 +13,14 @@ export type DialogProps = { title: string; description?: string; + submitButton?: string; + actionUrl?: string; } const BaseDialog = (props: DialogProps) => { const intl = useIntl(); - const { onClose, onSubmit } = props; + const { onClose, onSubmit, actionUrl = "" } = props; const handleOnSubmit = (e: React.FormEvent) => { e.preventDefault(); diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/import-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/import-dialog/index.tsx index 31d5a096..21a8bda4 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/import-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/import-dialog/index.tsx @@ -13,13 +13,15 @@ import BaseDialog from '../base-dialog'; export type ImportModel = { title: string; description?: string; + contentType?: string; + content?: ArrayBuffer | null | string; } export type CreateProps = { onClose: () => void } -const defaultModel: ImportModel = { title: '', description: '' }; +const defaultModel: ImportModel = { title: '' }; const ImportDialog = (props: CreateProps) => { const client: Client = useSelector(activeInstance); const [model, setModel] = React.useState(defaultModel); @@ -27,7 +29,7 @@ const ImportDialog = (props: CreateProps) => { const intl = useIntl(); const mutation = useMutation((model: ImportModel) => { - return client.createMap(model); + return client.importMap(model); }, { onSuccess: (mapId: number) => { @@ -55,9 +57,41 @@ const ImportDialog = (props: CreateProps) => { const name = event.target.name; const value = event.target.value; - setModel({ ...model, [name as keyof BasicMapInfo]: value }); + setModel({ ...model, [name as keyof ImportModel]: value }); } + const handleOnFileChange = (event: React.ChangeEvent) => { + const files = event?.target?.files; + const reader = new FileReader(); + + if (files) { + const file = files[0]; + var title = file.name; + title = title.substring(0, title.lastIndexOf(".")); + + // Closure to capture the file information. + reader.onload = (event) => { + const fileContent = event?.target?.result; + model.content = fileContent; + + // Suggest file name ... + const fileName = file.name; + if (fileName) { + var title = fileName.split('.')[0] + if (!model.title || 0 === model.title.length) { + model.title = title; + } + } + model.contentType = file.name.lastIndexOf(".wxml") != -1 ? "application/xml" : "application/freemind"; + setModel({...model}); + }; + + // Read in the image file as a data URL. + reader.readAsText(file); + } + + }; + return (
{ submitButton={intl.formatMessage({ id: 'import.button', defaultMessage: 'Create' })}> + + -