Complete info dialog.

This commit is contained in:
Paulo Gustavo Veiga 2021-02-06 17:47:34 -08:00
parent 16c2d1baaf
commit fe9f40b73b
9 changed files with 213 additions and 53 deletions

View File

@ -18,8 +18,10 @@ export type MapInfo = {
starred: boolean; starred: boolean;
title: string; title: string;
labels: number[]; labels: number[];
creator: string; createdBy: string;
modified: string; creationTime: string;
lastModificationBy: string;
lastModificationTime: string;
description: string; description: string;
isPublic: boolean; isPublic: boolean;
role: 'owner' | 'editor' | 'viewer' role: 'owner' | 'editor' | 'viewer'
@ -27,8 +29,8 @@ export type MapInfo = {
export type ChangeHistory = { export type ChangeHistory = {
id: number; id: number;
creator: string; lastModificationBy: string;
modified: string; lastModificationTime: string;
} }
export type BasicMapInfo = { export type BasicMapInfo = {

View File

@ -13,26 +13,19 @@ class MockClient implements Client {
title: string, title: string,
labels: number[], labels: number[],
creator: string, creator: string,
modified: string, creationTime: string,
modifiedByUser: string,
modifiedTime: string,
description: string, description: string,
isPublic: boolean, isPublic: boolean,
role: 'owner' | 'viewer' | 'editor' role: 'owner' | 'viewer' | 'editor'
): MapInfo { ): MapInfo {
return { id, title, labels, creator, modified, starred, description, isPublic, role }; return { id, title, labels, createdBy: creator, creationTime, lastModificationBy: modifiedByUser, lastModificationTime: modifiedTime, starred, description, isPublic, role };
} }
this.maps = [ this.maps = [
createMapInfo(1, true, "El Mapa", [], "Paulo", "2008-06-02T00:00:00Z", "", true, 'owner'), createMapInfo(1, true, "El Mapa", [], "Paulo", "2008-06-02T00:00:00Z", "Berna", "2008-06-02T00:00:00Z", "", true, 'owner'),
createMapInfo(2, false, "El Mapa2", [], "Paulo2", "2008-06-02T00:00:00Z", "", false, 'editor'), createMapInfo(11, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "Berna", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(3, false, "El Mapa3", [], "Paulo3", "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(4, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(5, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(6, false, "/El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(7, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(8, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(9, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(10, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(11, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor'),
createMapInfo(12, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "", false, 'editor')
]; ];
this.labels = [ this.labels = [
@ -103,39 +96,39 @@ class MockClient implements Client {
fetchHistory(id: number): Promise<ChangeHistory[]> { fetchHistory(id: number): Promise<ChangeHistory[]> {
const result = [{ const result = [{
id: 1, id: 1,
creator: 'Paulo', lastModificationBy: 'Paulo',
modified: '2008-06-02T00:00:00Z' lastModificationTime: '2008-06-02T00:00:00Z'
}, },
{ {
id: 2, id: 2,
creator: 'Paulo', lastModificationBy: 'Paulo',
modified: '2008-06-02T00:00:00Z' lastModificationTime: '2008-06-02T00:00:00Z'
} }
, ,
{ {
id: 3, id: 3,
creator: 'Paulo', lastModificationBy: 'Paulo',
modified: '2008-06-02T00:00:00Z' lastModificationTime: '2008-06-02T00:00:00Z'
}, },
{ {
id: 4, id: 4,
creator: 'Paulo', lastModificationBy: 'Paulo',
modified: '2008-06-02T00:00:00Z' lastModificationTime: '2008-06-02T00:00:00Z'
}, },
{ {
id: 5, id: 5,
creator: 'Paulo', lastModificationBy: 'Paulo',
modified: '2008-06-02T00:00:00Z' lastModificationTime: '2008-06-02T00:00:00Z'
}, },
{ {
id: 6, id: 6,
creator: 'Paulo', lastModificationBy: 'Paulo',
modified: '2008-06-02T00:00:00Z' lastModificationTime: '2008-06-02T00:00:00Z'
}, },
{ {
id: 7, id: 7,
creator: 'Paulo', lastModificationBy: 'Paulo',
modified: '2008-06-02T00:00:00Z' lastModificationTime: '2008-06-02T00:00:00Z'
} }
] ]
return Promise.resolve(result); return Promise.resolve(result);
@ -151,9 +144,11 @@ class MockClient implements Client {
description: String(basicInfo.description), description: String(basicInfo.description),
title: basicInfo.title, title: basicInfo.title,
starred: false, starred: false,
creator: "current user", createdBy: "current user",
labels: [], labels: [],
modified: "2008-06-02T00:00:00Z", lastModificationTime: "2008-06-02T00:00:00Z",
lastModificationBy: "Berna",
creationTime: "2008-06-02T00:00:00Z",
isPublic: false, isPublic: false,
role: 'owner' role: 'owner'
}; };

View File

@ -136,8 +136,10 @@ export default class RestClient implements Client {
starred: Boolean(m.starred), starred: Boolean(m.starred),
title: m.title, title: m.title,
labels: m.labels, labels: m.labels,
creator: m.creator, createdBy: m.creator,
modified: m.lastModificationTime, creationTime: m.creationTime,
lastModificationBy: m.lastModifierUser,
lastModificationTime: m.lastModificationTime,
description: m.description, description: m.description,
isPublic: m['public'], isPublic: m['public'],
role: m.role role: m.role

View File

@ -39,7 +39,8 @@ const HistoryDialog = (props: DialogProps) => {
onClose={handleOnClose} onClose={handleOnClose}
title={intl.formatMessage({ id: "action.history-title", defaultMessage: "Version history" })} title={intl.formatMessage({ id: "action.history-title", defaultMessage: "Version history" })}
description={intl.formatMessage({ id: "action.history-description", defaultMessage: "List of changes introduced in the last 90 days." })} > description={intl.formatMessage({ id: "action.history-description", defaultMessage: "List of changes introduced in the last 90 days." })} >
<TableContainer component={Paper} style={{ maxHeight: '200px' }}>
<TableContainer component={Paper} style={{ maxHeight: '200px' }} variant="outlined">
<Table size="small" stickyHeader> <Table size="small" stickyHeader>
<TableHead> <TableHead>
<TableRow> <TableRow>
@ -59,10 +60,10 @@ const HistoryDialog = (props: DialogProps) => {
) : ) :
changeHistory.map((row) => ( changeHistory.map((row) => (
<TableRow key={row.id}> <TableRow key={row.id}>
<TableCell align="left">{row.creator}</TableCell> <TableCell align="left">{row.lastModificationBy}</TableCell>
<TableCell align="left"> <TableCell align="left">
<Tooltip title={moment(row.modified).format("lll")} placement="bottom-start"> <Tooltip title={moment(row.lastModificationTime).format("lll")} placement="bottom-start">
<span>{moment(row.modified).fromNow()}</span> <span>{moment(row.lastModificationTime).fromNow()}</span>
</Tooltip> </Tooltip>
</TableCell> </TableCell>
<TableCell align="left"><Link href={`c/maps/${mapId}/${row.id}/view`} target="history"><FormattedMessage id="maps.view" defaultMessage="View" /></Link></TableCell> <TableCell align="left"><Link href={`c/maps/${mapId}/${row.id}/view`} target="history"><FormattedMessage id="maps.view" defaultMessage="View" /></Link></TableCell>

View File

@ -13,6 +13,7 @@ import CreateDialog from './create-dialog';
import HistoryDialog from './history-dialog'; import HistoryDialog from './history-dialog';
import ImportDialog from './import-dialog'; import ImportDialog from './import-dialog';
import PublishDialog from './publish-dialog'; import PublishDialog from './publish-dialog';
import InfoDialog from './info-dialog';
export type BasicMapInfo = { export type BasicMapInfo = {
name: string; name: string;
@ -53,6 +54,7 @@ const ActionDispatcher = (props: ActionDialogProps) => {
{action === 'history' && <HistoryDialog open={true} onClose={handleOnClose} mapId={mapId} />} {action === 'history' && <HistoryDialog open={true} onClose={handleOnClose} mapId={mapId} />}
{action === 'import' && <ImportDialog open={true} onClose={handleOnClose} />} {action === 'import' && <ImportDialog open={true} onClose={handleOnClose} />}
{action === 'publish' && <PublishDialog onClose={handleOnClose} mapId={mapId}/>} {action === 'publish' && <PublishDialog onClose={handleOnClose} mapId={mapId}/>}
{action === 'info' && <InfoDialog onClose={handleOnClose} mapId={mapId}/>}
</span > </span >
); );

View File

@ -0,0 +1,142 @@
import React from 'react';
import { FormattedMessage, useIntl } from 'react-intl';
import { useMutation, useQueryClient } from 'react-query';
import { useSelector } from 'react-redux';
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 { useStyles } from './style';
import moment from 'moment';
export type InfoProps = {
mapId: number,
onClose: () => void
}
const InfoDialog = (props: InfoProps) => {
const { mapId, onClose } = props;
const { map } = fetchMapById(mapId);
const client: Client = useSelector(activeInstance);
const [model, setModel] = React.useState<boolean>(map ? map.isPublic : false);
const [error, setError] = React.useState<ErrorInfo>();
const [] = React.useState('1');
const queryClient = useQueryClient();
const intl = useIntl();
const classes = useStyles();
const handleOnClose = (): void => {
props.onClose();
setError(undefined);
};
return (
<BaseDialog onClose={handleOnClose} error={error}
title={intl.formatMessage({ id: 'info.title', defaultMessage: 'Info' })}
description={intl.formatMessage({ id: 'info.description', defaultMessage: 'By publishing the map you make it visible to everyone on the Internet.' })}
submitButton={intl.formatMessage({ id: 'info.button', defaultMessage: 'Accept' })}>
<Paper style={{ maxHeight: '200px' }}>
<Card variant="outlined">
<List dense={true}>
<ListItem>
<Typography variant="body1" style={{ fontWeight: 'bold' }}>
<FormattedMessage id="info.basic-info" defaultMessage="Basic Info" />
</Typography>
</ListItem>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.name" defaultMessage="Name" />:
</Typography>
<Typography variant="body2">
{map?.title}
</Typography>
</ListItem>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.description" defaultMessage="Description" />:
</Typography>
<Typography variant="body2">
{map?.description}
</Typography>
</ListItem>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.creator" defaultMessage="Creator" />:
</Typography>
<Typography variant="body2">
{map?.createdBy}
</Typography>
</ListItem>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.creation-time" defaultMessage="Creation Date" />:
</Typography>
<Typography variant="body2">
{moment(map?.creationTime).format("lll")}
</Typography>
</ListItem>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.modified-tny" defaultMessage="Last Modified By" />:
</Typography>
<Typography variant="body2">
{map?.lastModificationBy}
</Typography>
</ListItem>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.modified-time" defaultMessage="Last Modified Date" />:
</Typography>
<Typography variant="body2">
{moment(map?.lastModificationTime).format("lll")}
</Typography>
</ListItem>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.starred" defaultMessage="Starred" />:
</Typography>
<Typography variant="body2">
{Boolean(map?.starred).toString()}
</Typography>
</ListItem>
</List>
</Card>
<Card variant="outlined" style={{ marginTop: "10px" }}>
<List dense={true}>
<ListItem>
<Typography variant="body1" style={{ fontWeight: 'bold' }}>
<FormattedMessage id="info.sharing" defaultMessage="Sharing" />
</Typography>
</ListItem>
</List>
<ListItem>
<Typography variant="caption" color="textPrimary" className={classes.textDesc}>
<FormattedMessage id="info.public-visibility" defaultMessage="Publicly Visible" />:
</Typography>
<Typography variant="body2">
{Boolean(map?.isPublic).toString()}
</Typography>
</ListItem>
</Card>
</Paper>
</BaseDialog>
)
}
export default InfoDialog;

View File

@ -0,0 +1,14 @@
import { createStyles, makeStyles, Theme } from "@material-ui/core";
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
textarea: {
width: '100%',
padding: '15px 15px',
marging: '0px 10px'
},
textDesc: {
width: '150px'
}
}),
);

View File

@ -24,7 +24,7 @@ const PublishDialog = (props: PublishProps) => {
const client: Client = useSelector(activeInstance); const client: Client = useSelector(activeInstance);
const [model, setModel] = React.useState<boolean>(map ? map.isPublic : false); const [model, setModel] = React.useState<boolean>(map ? map.isPublic : false);
const [error, setError] = React.useState<ErrorInfo>(); const [error, setError] = React.useState<ErrorInfo>();
const [value, setValue] = React.useState('1'); const [activeTab, setActiveTab] = React.useState('1');
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const intl = useIntl(); const intl = useIntl();
@ -59,7 +59,7 @@ const PublishDialog = (props: PublishProps) => {
} }
const handleTabChange = (event, newValue) => { const handleTabChange = (event, newValue) => {
setValue(newValue); setActiveTab(newValue);
}; };
return ( return (
@ -84,7 +84,7 @@ const PublishDialog = (props: PublishProps) => {
</FormControl> </FormControl>
<div style={!model ? { visibility: 'hidden' } : {}}> <div style={!model ? { visibility: 'hidden' } : {}}>
<TabContext value={value}> <TabContext value={activeTab}>
<AppBar position="static"> <AppBar position="static">
<TabList onChange={handleTabChange}> <TabList onChange={handleTabChange}>
<Tab label={intl.formatMessage({ id: 'publish.embedded', defaultMessage: 'Embedded' })} value="1" /> <Tab label={intl.formatMessage({ id: 'publish.embedded', defaultMessage: 'Embedded' })} value="1" />

View File

@ -94,8 +94,8 @@ function EnhancedTableHead(props: EnhancedTableProps) {
const headCells: HeadCell[] = [ const headCells: HeadCell[] = [
{ id: 'title', numeric: false, label: intl.formatMessage({ id: 'map.name', defaultMessage: 'Name' }) }, { id: 'title', numeric: false, label: intl.formatMessage({ id: 'map.name', defaultMessage: 'Name' }) },
{ id: 'labels', numeric: false }, { id: 'labels', numeric: false },
{ id: 'creator', numeric: false, label: intl.formatMessage({ id: 'map.creator', defaultMessage: 'Creator' }), style: { width: '70px', whiteSpace: 'nowrap' } }, { id: 'createdBy', numeric: false, label: intl.formatMessage({ id: 'map.creator', defaultMessage: 'Creator' }), style: { width: '70px', whiteSpace: 'nowrap' } },
{ id: 'modified', numeric: true, label: intl.formatMessage({ id: 'map.last-update', defaultMessage: 'Last Update' }), style: { width: '70px', whiteSpace: 'nowrap' } } { id: 'lastModificationTime', numeric: true, label: intl.formatMessage({ id: 'map.last-update', defaultMessage: 'Last Update' }), style: { width: '70px', whiteSpace: 'nowrap' } }
]; ];
return ( return (
@ -194,7 +194,7 @@ export const MapsList = (props: MapsListProps) => {
const [order, setOrder] = React.useState<Order>('asc'); const [order, setOrder] = React.useState<Order>('asc');
const [filter, setFilter] = React.useState<Filter>({ type: 'all' }); const [filter, setFilter] = React.useState<Filter>({ type: 'all' });
const [orderBy, setOrderBy] = React.useState<keyof MapInfo>('modified'); const [orderBy, setOrderBy] = React.useState<keyof MapInfo>('lastModificationTime');
const [selected, setSelected] = React.useState<number[]>([]); const [selected, setSelected] = React.useState<number[]>([]);
const [searchCondition, setSearchCondition] = React.useState<string>(''); const [searchCondition, setSearchCondition] = React.useState<string>('');
@ -319,7 +319,7 @@ export const MapsList = (props: MapsListProps) => {
const isSelected = (id: number) => selected.indexOf(id) !== -1; const isSelected = (id: number) => selected.indexOf(id) !== -1;
return ( return (
<div className={classes.root}> <div className={classes.root}>
<ActionChooser anchor={activeRowAction?.el} onClose={handleActionMenuClose} mapId={activeRowAction?.mapId} /> <ActionChooser anchor={activeRowAction?.el} onClose={handleActionMenuClose} mapId={activeRowAction?.mapId} />
<Paper className={classes.paper} elevation={0}> <Paper className={classes.paper} elevation={0}>
<Toolbar className={classes.toolbar} variant="dense"> <Toolbar className={classes.toolbar} variant="dense">
@ -454,12 +454,14 @@ export const MapsList = (props: MapsListProps) => {
</TableCell> </TableCell>
<TableCell className={classes.bodyCell}> <TableCell className={classes.bodyCell}>
{row.creator} {row.createdBy}
</TableCell> </TableCell>
<TableCell className={classes.bodyCell}> <TableCell className={classes.bodyCell}>
<Tooltip title={moment(row.modified).format("lll")} placement="bottom-start"> <Tooltip title={
<span>{moment(row.modified).fromNow()}</span> `Modified by ${row.lastModificationBy} on ${moment(row.lastModificationTime).format("lll")}`
} placement="bottom-start">
<span>{moment(row.lastModificationTime).fromNow()}</span>
</Tooltip> </Tooltip>
</TableCell> </TableCell>