mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-25 23:54:55 +01:00
Finish import
This commit is contained in:
parent
1c7dbb8af5
commit
1c5d6342e5
@ -6,6 +6,13 @@ export type NewUser = {
|
|||||||
recaptcha: string | null;
|
recaptcha: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ImportMapInfo = {
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
contentType?: string;
|
||||||
|
content?: ArrayBuffer | null | string;
|
||||||
|
|
||||||
|
}
|
||||||
export type Label = {
|
export type Label = {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
@ -55,6 +62,7 @@ export type AccountInfo = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Client {
|
interface Client {
|
||||||
|
importMap(model: ImportMapInfo): Promise<number>
|
||||||
createMap(map: BasicMapInfo): Promise<number>;
|
createMap(map: BasicMapInfo): Promise<number>;
|
||||||
deleteMaps(ids: number[]): Promise<void>;
|
deleteMaps(ids: number[]): Promise<void>;
|
||||||
deleteMap(id: number): Promise<void>;
|
deleteMap(id: number): Promise<void>;
|
||||||
@ -67,7 +75,7 @@ interface Client {
|
|||||||
|
|
||||||
fetchLabels(): Promise<Label[]>;
|
fetchLabels(): Promise<Label[]>;
|
||||||
deleteLabel(id: number): Promise<void>;
|
deleteLabel(id: number): Promise<void>;
|
||||||
fetchAccountInfo():Promise<AccountInfo>;
|
fetchAccountInfo(): Promise<AccountInfo>;
|
||||||
|
|
||||||
registerNewUser(user: NewUser): Promise<void>;
|
registerNewUser(user: NewUser): Promise<void>;
|
||||||
resetPassword(email: string): Promise<void>;
|
resetPassword(email: string): Promise<void>;
|
||||||
|
@ -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 {
|
class MockClient implements Client {
|
||||||
private maps: MapInfo[] = [];
|
private maps: MapInfo[] = [];
|
||||||
private labels: Label[] = [];
|
private labels: Label[] = [];
|
||||||
@ -34,6 +33,10 @@ class MockClient implements Client {
|
|||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
importMap(model: ImportMapInfo): Promise<number> {
|
||||||
|
return Promise.resolve(10);
|
||||||
|
}
|
||||||
|
|
||||||
fetchAccountInfo(): Promise<AccountInfo> {
|
fetchAccountInfo(): Promise<AccountInfo> {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
firstName: 'Costme',
|
firstName: 'Costme',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import axios from 'axios';
|
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 {
|
export default class RestClient implements Client {
|
||||||
private baseUrl: string;
|
private baseUrl: string;
|
||||||
@ -9,6 +9,20 @@ export default class RestClient implements Client {
|
|||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
this.sessionExpired = sessionExpired;
|
this.sessionExpired = sessionExpired;
|
||||||
}
|
}
|
||||||
|
importMap(model: ImportMapInfo): Promise<number> {
|
||||||
|
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<AccountInfo> {
|
fetchAccountInfo(): Promise<AccountInfo> {
|
||||||
const handler = (success: (account: AccountInfo) => void, reject: (error: ErrorInfo) => void) => {
|
const handler = (success: (account: AccountInfo) => void, reject: (error: ErrorInfo) => void) => {
|
||||||
|
@ -13,12 +13,14 @@ export type DialogProps = {
|
|||||||
|
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
submitButton?: string;
|
submitButton?: string;
|
||||||
|
actionUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BaseDialog = (props: DialogProps) => {
|
const BaseDialog = (props: DialogProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { onClose, onSubmit } = props;
|
const { onClose, onSubmit, actionUrl = "" } = props;
|
||||||
|
|
||||||
const handleOnSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
const handleOnSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -13,13 +13,15 @@ import BaseDialog from '../base-dialog';
|
|||||||
export type ImportModel = {
|
export type ImportModel = {
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
contentType?: string;
|
||||||
|
content?: ArrayBuffer | null | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CreateProps = {
|
export type CreateProps = {
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultModel: ImportModel = { title: '', description: '' };
|
const defaultModel: ImportModel = { title: '' };
|
||||||
const ImportDialog = (props: CreateProps) => {
|
const ImportDialog = (props: CreateProps) => {
|
||||||
const client: Client = useSelector(activeInstance);
|
const client: Client = useSelector(activeInstance);
|
||||||
const [model, setModel] = React.useState<ImportModel>(defaultModel);
|
const [model, setModel] = React.useState<ImportModel>(defaultModel);
|
||||||
@ -27,7 +29,7 @@ const ImportDialog = (props: CreateProps) => {
|
|||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const mutation = useMutation<number, ErrorInfo, ImportModel>((model: ImportModel) => {
|
const mutation = useMutation<number, ErrorInfo, ImportModel>((model: ImportModel) => {
|
||||||
return client.createMap(model);
|
return client.importMap(model);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: (mapId: number) => {
|
onSuccess: (mapId: number) => {
|
||||||
@ -55,9 +57,41 @@ const ImportDialog = (props: CreateProps) => {
|
|||||||
|
|
||||||
const name = event.target.name;
|
const name = event.target.name;
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
setModel({ ...model, [name as keyof BasicMapInfo]: value });
|
setModel({ ...model, [name as keyof ImportModel]: value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleOnFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<BaseDialog onClose={handleOnClose} onSubmit={handleOnSubmit} error={error}
|
<BaseDialog onClose={handleOnClose} onSubmit={handleOnSubmit} error={error}
|
||||||
@ -66,21 +100,24 @@ const ImportDialog = (props: CreateProps) => {
|
|||||||
submitButton={intl.formatMessage({ id: 'import.button', defaultMessage: 'Create' })}>
|
submitButton={intl.formatMessage({ id: 'import.button', defaultMessage: 'Create' })}>
|
||||||
|
|
||||||
<FormControl fullWidth={true}>
|
<FormControl fullWidth={true}>
|
||||||
|
<input
|
||||||
|
accept=".wxml,.mm"
|
||||||
|
id="contained-button-file"
|
||||||
|
type="file"
|
||||||
|
required={true}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
onChange={handleOnFileChange}
|
||||||
|
/>
|
||||||
|
|
||||||
<Input name="title" type="text" label={intl.formatMessage({ id: "action.rename-name-placeholder", defaultMessage: "Name" })}
|
<Input name="title" type="text" label={intl.formatMessage({ id: "action.rename-name-placeholder", defaultMessage: "Name" })}
|
||||||
value={model.title} onChange={handleOnChange} error={error} fullWidth={true} />
|
value={model.title} onChange={handleOnChange} error={error} fullWidth={true} />
|
||||||
|
|
||||||
<Input name="description" type="text" label={intl.formatMessage({ id: "action.rename-description-placeholder", defaultMessage: "Description" })}
|
<Input name="description" type="text" label={intl.formatMessage({ id: "action.rename-description-placeholder", defaultMessage: "Description" })}
|
||||||
value={model.description} onChange={handleOnChange} required={false} fullWidth={true} />
|
value={model.description} onChange={handleOnChange} required={false} fullWidth={true} />
|
||||||
|
|
||||||
<input
|
|
||||||
accept="image/*"
|
|
||||||
id="contained-button-file"
|
|
||||||
type="file"
|
|
||||||
style={{display: 'none'}}
|
|
||||||
/>
|
|
||||||
<label htmlFor="contained-button-file">
|
<label htmlFor="contained-button-file">
|
||||||
<Button variant="outlined" color="primary" component="span" style={{margin: '10px 5px', width: '100%'}}>
|
<Button variant="outlined" color="primary" component="span" style={{ margin: '10px 5px', width: '100%' }}>
|
||||||
<FormattedMessage id="maps.choose-file" defaultMessage="Choose a file"/>
|
<FormattedMessage id="maps.choose-file" defaultMessage="Choose a file" />
|
||||||
</Button>
|
</Button>
|
||||||
</label>
|
</label>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
Loading…
Reference in New Issue
Block a user