diff --git a/packages/webapp/lang/en.json b/packages/webapp/lang/en.json index a54c4a1b..c75a1e8d 100644 --- a/packages/webapp/lang/en.json +++ b/packages/webapp/lang/en.json @@ -74,6 +74,9 @@ "create.title": { "defaultMessage": "Create a new mindmap" }, + "deletem.title": { + "defaultMessage": "All selected maps will be deleted" + }, "duplicate.title": { "defaultMessage": "Duplicate" }, @@ -143,6 +146,45 @@ "import.title": { "defaultMessage": "Import existing mindmap" }, + "info.basic-info": { + "defaultMessage": "Basic Info" + }, + "info.button": { + "defaultMessage": "Accept" + }, + "info.creation-time": { + "defaultMessage": "Creation Date" + }, + "info.creator": { + "defaultMessage": "Creator" + }, + "info.description": { + "defaultMessage": "Description" + }, + "info.description-msg": { + "defaultMessage": "By publishing the map you make it visible to everyone on the Internet." + }, + "info.modified-time": { + "defaultMessage": "Last Modified Date" + }, + "info.modified-tny": { + "defaultMessage": "Last Modified By" + }, + "info.name": { + "defaultMessage": "Name" + }, + "info.public-visibility": { + "defaultMessage": "Publicly Visible" + }, + "info.sharing": { + "defaultMessage": "Sharing" + }, + "info.starred": { + "defaultMessage": "Starred" + }, + "info.title": { + "defaultMessage": "Info" + }, "login.desc": { "defaultMessage": "Log into your account" }, @@ -189,6 +231,9 @@ "map.name": { "defaultMessage": "Name" }, + "maps.create-tooltip": { + "defaultMessage": "Create a New Map" + }, "maps.empty-result": { "defaultMessage": "No matching record found with the current filter criteria." }, diff --git a/packages/webapp/src/client/index.ts b/packages/webapp/src/client/index.ts index f35f1b85..9bc9c583 100644 --- a/packages/webapp/src/client/index.ts +++ b/packages/webapp/src/client/index.ts @@ -51,11 +51,12 @@ export type ErrorInfo = { interface Client { createMap(map: BasicMapInfo): Promise; + deleteMaps(ids: number[]): Promise; deleteMap(id: number): Promise; renameMap(id: number, basicInfo: BasicMapInfo): Promise; fetchAllMaps(): Promise; duplicateMap(id: number, basicInfo: BasicMapInfo): Promise; - fetchMapInfo(id: number): Promise; + changeStarred(id: number, starred: boolean): Promise; updateMapToPublic(id: number, starred: boolean): Promise; diff --git a/packages/webapp/src/client/mock-client/index.ts b/packages/webapp/src/client/mock-client/index.ts index fd25ffa1..98006913 100644 --- a/packages/webapp/src/client/mock-client/index.ts +++ b/packages/webapp/src/client/mock-client/index.ts @@ -25,7 +25,7 @@ class MockClient implements Client { this.maps = [ createMapInfo(1, true, "El Mapa", [], "Paulo", "2008-06-02T00:00:00Z", "Berna", "2008-06-02T00:00:00Z", "", true, 'owner'), createMapInfo(11, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "Berna", "2008-06-02T00:00:00Z", "", false, 'editor'), - createMapInfo(12, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "Berna", "2008-06-02T00:00:00Z","", false, 'editor') + createMapInfo(12, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "Berna", "2008-06-02T00:00:00Z", "", false, 'editor') ]; this.labels = [ @@ -34,6 +34,10 @@ class MockClient implements Client { ]; } + deleteMaps(ids: number[]): Promise { + ids.forEach(id => this.deleteMap(id)); + return Promise.resolve(); + } revertHistory(id: number, cid: number): Promise { return Promise.resolve(); } @@ -65,10 +69,6 @@ class MockClient implements Client { return Promise.resolve(); } - fetchMapInfo(id: number): Promise { - return Promise.resolve({ title: 'My Map', description: 'My Description' }); - } - renameMap(id: number, basicInfo: BasicMapInfo): Promise { const exists = this.maps.find(m => m.title == basicInfo.title) != undefined; @@ -171,7 +171,7 @@ class MockClient implements Client { console.log("Label delete:" + this.labels); return Promise.resolve(); } - + deleteMap(id: number): Promise { this.maps = this.maps.filter(m => m.id != id); return Promise.resolve(); @@ -181,7 +181,7 @@ class MockClient implements Client { return Promise.resolve(); } - fetchAllMaps(): Promise { + fetchAllMaps(): Promise { console.log("Fetching maps from server") return Promise.resolve(this.maps); } diff --git a/packages/webapp/src/client/rest-client/index.ts b/packages/webapp/src/client/rest-client/index.ts index b387e9d2..31929869 100644 --- a/packages/webapp/src/client/rest-client/index.ts +++ b/packages/webapp/src/client/rest-client/index.ts @@ -6,30 +6,32 @@ export default class RestClient implements Client { private baseUrl: string; private sessionExpired: () => void - constructor(baseUrl: string, sessionExpired: () => void) { this.baseUrl = baseUrl; this.sessionExpired = sessionExpired; } - updateMapToPublic(id: number, isPublic: boolean): Promise { - /* - jQuery.ajax("c/restful/maps/${mindmap.id}/publish", { - async:false, - dataType:'json', - data:$('#dialogMainForm #enablePublicView')[0].checked ? 'true' : 'false', - type:'PUT', - contentType:"text/plain", - success:function (data, textStatus, jqXHR) { - $('#publish-dialog-modal').modal('hide'); - }, - */ + deleteMaps(ids: number[]): Promise { + const handler = (success: () => void, reject: (error: ErrorInfo) => void) => { + axios.delete(this.baseUrl + `/c/restful/maps/batch?ids=${ids.join()}`, + { headers: { 'Content-Type': 'text/plain' } } + ).then(() => { + success(); + }).catch(error => { + const response = error.response; + const errorInfo = this.parseResponseOnError(response); + reject(errorInfo); + }); + } + return new Promise(handler); + } + updateMapToPublic(id: number, isPublic: boolean): Promise { const handler = (success: () => void, reject: (error: ErrorInfo) => void) => { axios.put(`${this.baseUrl}/c/restful/maps/${id}/publish`, isPublic, { headers: { 'Content-Type': 'text/plain' } } - ).then(response => { + ).then(() => { // All was ok, let's sent to success page ...; success(); }).catch(error => { @@ -45,60 +47,11 @@ export default class RestClient implements Client { throw new Error('Method not implemented.'); } + fetchHistory(id: number): Promise { throw new Error('Method not implemented.'); } - fetchMapInfo(id: number): Promise { - throw new Error('Method not implemented.'); - } - - private parseResponseOnError = (response: any): ErrorInfo => { - const intl = useIntl(); - - let result: ErrorInfo | undefined; - if (response) { - const status: number = response.status; - const data = response.data; - console.log(data); - - switch (status) { - case 401: - case 302: - this.sessionExpired(); - result = { msg: intl.formatMessage({ id: "expired.description", defaultMessage: "Your current session has expired. Please, sign in and try again." }) } - break; - default: - if (data) { - // Set global errors ... - result = {}; - let globalErrors = data.globalErrors; - if (globalErrors && globalErrors.length > 0) { - result.msg = globalErrors[0]; - } - - // Set field errors ... - if (data.fieldErrors && Object.keys(data.fieldErrors).length > 0) { - result.fields = data.fieldErrors; - if (!result.msg) { - const key = Object.keys(data.fieldErrors)[0]; - result.msg = data.fieldErrors[key]; - } - } - - } else { - result = { msg: response.statusText }; - } - } - } - - // Network related problem ... - if (!result) { - result = { msg: 'Unexpected error. Please, try latter' }; - } - - return result; - } renameMap(id: number, basicInfo: BasicMapInfo): Promise { throw "Method not implemented yet"; @@ -283,5 +236,53 @@ export default class RestClient implements Client { } return new Promise(handler); } + + private parseResponseOnError = (response: any): ErrorInfo => { + const intl = useIntl(); + + let result: ErrorInfo | undefined; + if (response) { + const status: number = response.status; + const data = response.data; + console.log(data); + + switch (status) { + case 401: + case 302: + this.sessionExpired(); + result = { msg: intl.formatMessage({ id: "expired.description", defaultMessage: "Your current session has expired. Please, sign in and try again." }) } + break; + default: + if (data) { + // Set global errors ... + result = {}; + let globalErrors = data.globalErrors; + if (globalErrors && globalErrors.length > 0) { + result.msg = globalErrors[0]; + } + + // Set field errors ... + if (data.fieldErrors && Object.keys(data.fieldErrors).length > 0) { + result.fields = data.fieldErrors; + if (!result.msg) { + const key = Object.keys(data.fieldErrors)[0]; + result.msg = data.fieldErrors[key]; + } + } + + } else { + result = { msg: response.statusText }; + } + } + } + + // Network related problem ... + if (!result) { + result = { msg: 'Unexpected error. Please, try latter' }; + } + + return result; + } + } diff --git a/packages/webapp/src/compiled-lang/en.json b/packages/webapp/src/compiled-lang/en.json index 79296854..724e6a8b 100644 --- a/packages/webapp/src/compiled-lang/en.json +++ b/packages/webapp/src/compiled-lang/en.json @@ -149,6 +149,12 @@ "value": "Create a new mindmap" } ], + "deletem.title": [ + { + "type": 0, + "value": "All selected maps will be deleted" + } + ], "duplicate.title": [ { "type": 0, @@ -287,6 +293,84 @@ "value": "Import existing mindmap" } ], + "info.basic-info": [ + { + "type": 0, + "value": "Basic Info" + } + ], + "info.button": [ + { + "type": 0, + "value": "Accept" + } + ], + "info.creation-time": [ + { + "type": 0, + "value": "Creation Date" + } + ], + "info.creator": [ + { + "type": 0, + "value": "Creator" + } + ], + "info.description": [ + { + "type": 0, + "value": "Description" + } + ], + "info.description-msg": [ + { + "type": 0, + "value": "By publishing the map you make it visible to everyone on the Internet." + } + ], + "info.modified-time": [ + { + "type": 0, + "value": "Last Modified Date" + } + ], + "info.modified-tny": [ + { + "type": 0, + "value": "Last Modified By" + } + ], + "info.name": [ + { + "type": 0, + "value": "Name" + } + ], + "info.public-visibility": [ + { + "type": 0, + "value": "Publicly Visible" + } + ], + "info.sharing": [ + { + "type": 0, + "value": "Sharing" + } + ], + "info.starred": [ + { + "type": 0, + "value": "Starred" + } + ], + "info.title": [ + { + "type": 0, + "value": "Info" + } + ], "login.desc": [ { "type": 0, @@ -377,6 +461,12 @@ "value": "Name" } ], + "maps.create-tooltip": [ + { + "type": 0, + "value": "Create a New Map" + } + ], "maps.empty-result": [ { "type": 0, diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/create-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/create-dialog/index.tsx index 2968de6b..0ac25121 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/create-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/create-dialog/index.tsx @@ -16,7 +16,6 @@ export type CreateModel = { } export type CreateProps = { - open: boolean, onClose: () => void } diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/delete-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/delete-dialog/index.tsx index 3761d52d..916a11c1 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/delete-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/delete-dialog/index.tsx @@ -5,24 +5,24 @@ import { useMutation, useQueryClient } from "react-query"; import { useSelector } from "react-redux"; import Client from "../../../../client"; import { activeInstance } from '../../../../redux/clientSlice'; -import { DialogProps, fetchMapById, handleOnMutationSuccess } from ".."; +import { SimpleDialogProps, fetchMapById, handleOnMutationSuccess } from ".."; import BaseDialog from "../base-dialog"; -const DeleteDialog = (props: DialogProps) => { +const DeleteDialog = (props: SimpleDialogProps) => { const intl = useIntl(); + const { mapId, onClose } = props; - const service: Client = useSelector(activeInstance); + const client: Client = useSelector(activeInstance); const queryClient = useQueryClient(); - const mutation = useMutation((id: number) => service.deleteMap(id), + const mutation = useMutation((id: number) => client.deleteMap(id), { - onSuccess: () => handleOnMutationSuccess(props.onClose, queryClient) + onSuccess: () => handleOnMutationSuccess(onClose, queryClient) } ); - const mapId = props.mapId; const handleOnClose = (): void => { - props.onClose(); + onClose(); }; const handleOnSubmit = (): void => { @@ -37,10 +37,12 @@ const DeleteDialog = (props: DialogProps) => { onClose={handleOnClose} onSubmit={handleOnSubmit} title={intl.formatMessage({ id: "action.delete-title", defaultMessage: "Delete" })} submitButton={intl.formatMessage({ id: "action.delete-title", defaultMessage: "Delete" })} > + Delete '{map?.title}' + ); diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/delete-multiselect-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/delete-multiselect-dialog/index.tsx new file mode 100644 index 00000000..be39b58a --- /dev/null +++ b/packages/webapp/src/components/maps-page/action-dispatcher/delete-multiselect-dialog/index.tsx @@ -0,0 +1,52 @@ +import { Alert, AlertTitle } from "@material-ui/lab"; +import React from "react"; +import { FormattedMessage, useIntl } from "react-intl"; +import { useMutation, useQueryClient } from "react-query"; +import { useSelector } from "react-redux"; +import Client from "../../../../client"; +import { activeInstance } from '../../../../redux/clientSlice'; +import { handleOnMutationSuccess } from ".."; +import BaseDialog from "../base-dialog"; + +export type DeleteMultiselectDialogProps = { + mapsId: number[], + onClose: () => void +} + +const DeleteMultiselectDialog = (props: DeleteMultiselectDialogProps) => { + const { onClose, mapsId } = props; + const intl = useIntl(); + const client: Client = useSelector(activeInstance); + const queryClient = useQueryClient(); + + const mutation = useMutation((ids: number[]) => client.deleteMaps(ids), + { + onSuccess: () => handleOnMutationSuccess(props.onClose, queryClient) + } + ); + + const handleOnClose = (): void => { + onClose(); + }; + + const handleOnSubmit = (): void => { + mutation.mutate(mapsId); + } + + return ( +
+ + + + + + +
+ ); +} + + +export default DeleteMultiselectDialog; \ No newline at end of file diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/duplicate-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/duplicate-dialog/index.tsx index e2156939..0872c357 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/duplicate-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/duplicate-dialog/index.tsx @@ -7,7 +7,7 @@ import { useSelector } from "react-redux"; import Client, { BasicMapInfo, ErrorInfo } from "../../../../client"; import { activeInstance } from '../../../../redux/clientSlice'; import Input from "../../../form/input"; -import { DialogProps, fetchMapById } from ".."; +import { SimpleDialogProps, fetchMapById } from ".."; import BaseDialog from "../base-dialog"; export type DuplicateModel = { @@ -17,14 +17,13 @@ export type DuplicateModel = { } const defaultModel: DuplicateModel = { title: '', description: '', id: -1 }; -const DuplicateDialog = (props: DialogProps) => { +const DuplicateDialog = (props: SimpleDialogProps) => { const service: Client = useSelector(activeInstance); const [model, setModel] = React.useState(defaultModel); const [error, setError] = React.useState(); - const { mapId, open } = props; + const { mapId, onClose } = props; const intl = useIntl(); - const queryClient = useQueryClient(); const mutation = useMutation((model: DuplicateModel) => { const { id, ...rest } = model; @@ -41,9 +40,7 @@ const DuplicateDialog = (props: DialogProps) => { ); const handleOnClose = (): void => { - props.onClose(); - setModel(defaultModel); - setError(undefined); + onClose(); }; const handleOnSubmit = (event: React.FormEvent): void => { diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/history-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/history-dialog/index.tsx index 92a3680c..d753efd2 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/history-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/history-dialog/index.tsx @@ -4,13 +4,13 @@ import { useQuery } from "react-query"; import { useSelector } from "react-redux"; import Client, { ChangeHistory } from "../../../../client"; import { activeInstance } from '../../../../redux/clientSlice'; -import { DialogProps } from ".."; +import { SimpleDialogProps } from ".."; import BaseDialog from "../base-dialog"; import { Link, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tooltip } from "@material-ui/core"; import moment from "moment"; -const HistoryDialog = (props: DialogProps) => { +const HistoryDialog = (props: SimpleDialogProps) => { const intl = useIntl(); const mapId = props.mapId; 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 1c1b7a4c..cb46aa6d 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 @@ -16,7 +16,6 @@ export type ImportModel = { } export type CreateProps = { - open: boolean, onClose: () => void } diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/index.tsx index 0bc540ac..496f84c7 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/index.tsx @@ -8,12 +8,12 @@ import { useSelector } from "react-redux"; import { QueryClient, useQuery } from 'react-query'; import { activeInstance } from '../../../redux/clientSlice'; import DuplicateDialog from './duplicate-dialog'; -import { useHistory } from 'react-router-dom'; import CreateDialog from './create-dialog'; import HistoryDialog from './history-dialog'; import ImportDialog from './import-dialog'; import PublishDialog from './publish-dialog'; import InfoDialog from './info-dialog'; +import DeleteMultiselectDialog from './delete-multiselect-dialog'; export type BasicMapInfo = { name: string; @@ -22,13 +22,12 @@ export type BasicMapInfo = { type ActionDialogProps = { action?: ActionType, - mapId: number, + mapsId: number[], onClose: () => void } const ActionDispatcher = (props: ActionDialogProps) => { - const history = useHistory(); - const mapId = props.mapId; + const mapsId = props.mapsId; const action = props.action; const handleOnClose = (): void => { @@ -37,24 +36,26 @@ const ActionDispatcher = (props: ActionDialogProps) => { switch (action) { case 'open': - window.location.href = `/c/maps/${mapId}/edit`; + window.location.href = `/c/maps/${mapsId}/edit`; break; case 'print': - window.open(`/c/maps/${mapId}/print`, 'print'); + window.open(`/c/maps/${mapsId}/print`, 'print'); break; } return ( - {action === 'create' && } - {action === 'delete' &&} - {action === 'rename' && } - {action === 'duplicate' && } - {action === 'history' && } - {action === 'import' && } - {action === 'publish' && } - {action === 'info' && } + {action === 'create' && } + {(action === 'delete' && mapsId.length == 1) && } + {(action === 'delete' && mapsId.length > 1) && } + {action === 'rename' && } + {action === 'duplicate' && } + {action === 'history' && } + {action === 'import' && } + {action === 'publish' && } + {action === 'info' && } + {action === 'create' && } ); @@ -83,8 +84,7 @@ export const handleOnMutationSuccess = (onClose: () => void, queryClient: QueryC onClose(); } -export type DialogProps = { - open: boolean, +export type SimpleDialogProps = { mapId: number, onClose: () => void } diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/info-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/info-dialog/index.tsx index 1e26494c..3400c5ba 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/info-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/info-dialog/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; -import { useMutation, useQueryClient } from 'react-query'; +import { useQueryClient } from 'react-query'; import { useSelector } from 'react-redux'; import { Card, List, ListItem, Paper, Typography } from '@material-ui/core'; @@ -8,37 +8,28 @@ import { Card, List, ListItem, Paper, Typography } from '@material-ui/core'; import Client, { ErrorInfo } from '../../../../client'; import { activeInstance } from '../../../../redux/clientSlice'; import BaseDialog from '../base-dialog'; -import { fetchMapById, handleOnMutationSuccess } from '..'; +import { fetchMapById, SimpleDialogProps } from '..'; import { useStyles } from './style'; import moment from 'moment'; -export type InfoProps = { - mapId: number, - onClose: () => void -} - -const InfoDialog = (props: InfoProps) => { +const InfoDialog = (props: SimpleDialogProps) => { const { mapId, onClose } = props; const { map } = fetchMapById(mapId); - - const client: Client = useSelector(activeInstance); - const [model, setModel] = React.useState(map ? map.isPublic : false); const [error, setError] = React.useState(); const [] = React.useState('1'); - const queryClient = useQueryClient(); - const intl = useIntl(); + const intl = useIntl(); const classes = useStyles(); const handleOnClose = (): void => { - props.onClose(); + onClose(); setError(undefined); }; return ( diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/publish-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/publish-dialog/index.tsx index c8d88a06..4ffe5a76 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/publish-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/publish-dialog/index.tsx @@ -9,15 +9,11 @@ import Client, { ErrorInfo } from '../../../../client'; import { activeInstance } from '../../../../redux/clientSlice'; import BaseDialog from '../base-dialog'; import { TabContext, TabList, TabPanel } from '@material-ui/lab'; -import { fetchMapById, handleOnMutationSuccess } from '..'; +import { fetchMapById, handleOnMutationSuccess, SimpleDialogProps } from '..'; import { useStyles } from './style'; -export type PublishProps = { - mapId: number, - onClose: () => void -} -const PublishDialog = (props: PublishProps) => { +const PublishDialog = (props: SimpleDialogProps) => { const { mapId, onClose } = props; const { map } = fetchMapById(mapId); diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/rename-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/rename-dialog/index.tsx index ec462220..c8107b40 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/rename-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/rename-dialog/index.tsx @@ -4,7 +4,7 @@ import { useMutation, useQueryClient } from "react-query"; import { useSelector } from "react-redux"; import Client, { BasicMapInfo, ErrorInfo } from "../../../../client"; import { activeInstance } from '../../../../redux/clientSlice'; -import { DialogProps, fetchMapById, handleOnMutationSuccess } from ".."; +import { SimpleDialogProps, fetchMapById, handleOnMutationSuccess } from ".."; import Input from "../../../form/input"; import { FormControl } from "@material-ui/core"; import BaseDialog from "../base-dialog"; @@ -16,11 +16,11 @@ export type RenameModel = { } const defaultModel: RenameModel = { title: '', description: '', id: -1 }; -const RenameDialog = (props: DialogProps) => { +const RenameDialog = (props: SimpleDialogProps) => { const service: Client = useSelector(activeInstance); const [model, setModel] = React.useState(defaultModel); const [error, setError] = React.useState(); - const { mapId, open } = props; + const { mapId } = props; const intl = useIntl(); const queryClient = useQueryClient(); diff --git a/packages/webapp/src/components/maps-page/index.tsx b/packages/webapp/src/components/maps-page/index.tsx index 5633d20c..e6f726e9 100644 --- a/packages/webapp/src/components/maps-page/index.tsx +++ b/packages/webapp/src/components/maps-page/index.tsx @@ -11,7 +11,7 @@ import { useStyles } from './style'; import { AccountCircle, AcUnitTwoTone, AddCircleTwoTone, CloudUploadTwoTone, DeleteOutlineTwoTone, EmailOutlined, EmojiPeopleOutlined, ExitToAppOutlined, FeedbackOutlined, Help, LabelTwoTone, PeopleAltTwoTone, PersonAddTwoTone, PersonOutlineTwoTone, PersonTwoTone, PolicyOutlined, PublicTwoTone, SettingsApplicationsOutlined, ShareTwoTone, StarTwoTone } from '@material-ui/icons'; import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Link, ListItemSecondaryAction, ListItemText, Menu, MenuItem, Tooltip } from '@material-ui/core'; import { MapsList } from './maps-list'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, useIntl } from 'react-intl'; import { useQuery, useMutation, useQueryClient } from 'react-query'; import { activeInstance, activeInstanceStatus, ClientStatus } from '../../redux/clientSlice'; import { useSelector } from 'react-redux'; @@ -46,6 +46,7 @@ const MapsPage = () => { const client: Client = useSelector(activeInstance); const queryClient = useQueryClient(); const [activeDialog, setActiveDialog] = React.useState(undefined); + const intl = useIntl(); useEffect(() => { document.title = 'Maps | WiseMapping'; @@ -59,7 +60,6 @@ const MapsPage = () => { ); const handleMenuClick = (filter: Filter) => { - // Force reload ... queryClient.invalidateQueries('maps'); setFilter(filter); }; @@ -115,7 +115,7 @@ const MapsPage = () => { elevation={0}> - + - setActiveDialog(undefined)} mapId={-1} /> + setActiveDialog(undefined)} mapsId={[]} />
diff --git a/packages/webapp/src/components/maps-page/maps-list/index.tsx b/packages/webapp/src/components/maps-page/maps-list/index.tsx index 365bed20..edeb2100 100644 --- a/packages/webapp/src/components/maps-page/maps-list/index.tsx +++ b/packages/webapp/src/components/maps-page/maps-list/index.tsx @@ -203,6 +203,9 @@ export const MapsList = (props: MapsListProps) => { const client: Client = useSelector(activeInstance); const intl = useIntl(); + const queryClient = useQueryClient(); + + useEffect(() => { setSelected([]); setPage(0); @@ -218,7 +221,7 @@ export const MapsList = (props: MapsListProps) => { const [activeRowAction, setActiveRowAction] = React.useState(undefined); type ActiveDialog = { actionType: ActionType; - mapId: number + mapsId: number[]; }; const [activeDialog, setActiveDialog] = React.useState(undefined); @@ -278,7 +281,6 @@ export const MapsList = (props: MapsListProps) => { }; }; - const queryClient = useQueryClient(); const starredMultation = useMutation((id: number) => { const map = mapsInfo.find(m => m.id == id); @@ -289,7 +291,6 @@ export const MapsList = (props: MapsListProps) => { queryClient.invalidateQueries('maps'); }, onError: (error) => { - // @todo ... // setError(error); } } @@ -306,7 +307,7 @@ export const MapsList = (props: MapsListProps) => { setActiveDialog({ actionType: action as ActionType, - mapId: mapId as number + mapsId: [mapId] as number[] }); } setActiveRowAction(undefined); @@ -316,6 +317,13 @@ export const MapsList = (props: MapsListProps) => { setSearchCondition(e.target.value); } + const handleDeleteClick = (event: React.MouseEvent) => { + setActiveDialog({ + actionType: 'delete', + mapsId: selected + }); + } + const isSelected = (id: number) => selected.indexOf(id) !== -1; return (
@@ -333,7 +341,9 @@ export const MapsList = (props: MapsListProps) => { variant="outlined" type="button" disableElevation={true} - startIcon={}> + onClick={handleDeleteClick} + startIcon={}> @@ -481,7 +491,7 @@ export const MapsList = (props: MapsListProps) => { - setActiveDialog(undefined)} mapId={activeDialog ? activeDialog.mapId : -1} /> + setActiveDialog(undefined)} mapsId={activeDialog ? activeDialog.mapsId : []} />
); }