Add label calor support

This commit is contained in:
Paulo Gustavo Veiga 2021-02-04 17:40:41 -08:00
parent 858050096f
commit 9596852c90
5 changed files with 86 additions and 58 deletions

View File

@ -6,11 +6,19 @@ export type NewUser = {
recaptcha: string | null;
}
export type Label = {
id: number;
title: string;
color: string;
iconName: string;
}
export type MapInfo = {
id: number;
starred: boolean;
title: string;
labels: string[];
labels: number[];
creator: string;
modified: string;
description: string;
@ -40,17 +48,18 @@ export type ErrorInfo = {
interface Client {
createMap(map: BasicMapInfo): Promise<number>;
deleteLabel(label: string): Promise<void>;
createMap(map: BasicMapInfo): Promise<number>;
registerNewUser(user: NewUser): Promise<void>;
resetPassword(email: string): Promise<void>;
fetchAllMaps(): Promise<MapInfo[]>;
fetchLabels(): Promise<string[]>;
deleteMap(id: number): Promise<void>;
renameMap(id: number, basicInfo: BasicMapInfo): Promise<void>;
duplicateMap(id: number, basicInfo: BasicMapInfo): Promise<number>;
loadMapInfo(id: number): Promise<BasicMapInfo>;
changeStarred(id: number, starred: boolean): Promise<void>;
fetchLabels(): Promise<Label[]>;
deleteLabel(id: number): Promise<void>;
}

View File

@ -1,8 +1,8 @@
import Client, { BasicMapInfo, MapInfo, NewUser } from '..';
import Client, { BasicMapInfo, Label, MapInfo, NewUser } from '..';
class MockClient implements Client {
private maps: MapInfo[] = [];
private labels: string[] = [];
private labels: Label[] = [];
constructor() {
@ -11,7 +11,7 @@ class MockClient implements Client {
id: number,
starred: boolean,
title: string,
labels: string[],
labels: number[],
creator: string,
modified: string,
description: string,
@ -20,21 +20,24 @@ class MockClient implements Client {
return { id, title, labels, creator, modified, starred, description, isPublic };
}
this.maps = [
createMapInfo(1, true, "El Mapa", [""], "Paulo", "2008-06-02T00:00:00Z", "", true),
createMapInfo(2, false, "El Mapa2", [""], "Paulo2", "2008-06-02T00:00:00Z", "", false),
createMapInfo(3, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(4, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(5, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(6, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(7, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(8, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(9, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(10, false, "El Mapa3", [""], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(11, false, "El Mapa3", ["label 3", "label3"], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(12, false, "El Mapa3", ["label 2"], "Paulo3", "2008-06-02T00:00:00Z", "", false)
createMapInfo(1, true, "El Mapa", [], "Paulo", "2008-06-02T00:00:00Z", "", true),
createMapInfo(2, false, "El Mapa2", [], "Paulo2", "2008-06-02T00:00:00Z", "", false),
createMapInfo(3, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(4, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(5, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(6, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(7, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(8, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(9, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(10, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(11, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "", false),
createMapInfo(12, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "", false)
];
this.labels = ["label 1,", "label 2", "label 3"];
this.labels = [
{ id: 1, title: "Red Label", iconName: "", color: 'red' },
{ id: 1, title: "Blue Label", iconName: "", color: 'blue' }
];
}
@ -42,7 +45,7 @@ class MockClient implements Client {
throw new Error("Method not implemented.");
}
fetchLabels(): Promise<string[]> {
fetchLabels(): Promise<Label[]> {
console.log("Fetching labels from server")
return Promise.resolve(this.labels);
}
@ -63,10 +66,6 @@ class MockClient implements Client {
return Promise.resolve({ title: 'My Map', description: 'My Description' });
}
fetchLabes(id: number): Promise<BasicMapInfo> {
return Promise.resolve({ title: 'My Map', description: 'My Description' });
}
renameMap(id: number, basicInfo: BasicMapInfo): Promise<void> {
const exists = this.maps.find(m => m.title == basicInfo.title) != undefined;
@ -121,9 +120,9 @@ class MockClient implements Client {
};
}
deleteLabel(label: string): Promise<void> {
this.labels = this.labels.filter(l => l != label);
console.log("Label delete:" + label);
deleteLabel(id: number): Promise<void> {
this.labels = this.labels.filter(l => l.id != id);
console.log("Label delete:" + this.labels);
return Promise.resolve();
}

View File

@ -1,5 +1,5 @@
import axios from 'axios';
import { ErrorInfo, MapInfo, BasicMapInfo, NewUser } from '..';
import { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label } from '..';
import MockClient from '../mock-client/';
//@Remove inheritance once is it completed.
@ -196,5 +196,10 @@ export default class RestClient extends MockClient {
}
return new Promise(handler);
}
deleteLabel(id: number): Promise<void> {
console.log("Fetching labels from server")
return Promise.resolve();
}
}

View File

@ -8,14 +8,14 @@ import IconButton from '@material-ui/core/IconButton';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import { useStyles } from './style';
import { AccountCircle, AddCircleTwoTone, CloudUploadTwoTone, DeleteOutlineTwoTone, EmailOutlined, EmojiPeopleOutlined, ExitToAppOutlined, FeedbackOutlined, Help, PolicyOutlined, PublicTwoTone, SettingsApplicationsOutlined } from '@material-ui/icons';
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, Link, ListItemSecondaryAction, ListItemText, Menu, MenuItem, Tooltip } from '@material-ui/core';
import { MapsList } from './maps-list';
import { FormattedMessage } from 'react-intl';
import { useQuery, useMutation, useQueryClient } from 'react-query';
import { activeInstance } from '../../reducers/serviceSlice';
import { useSelector } from 'react-redux';
import Client from '../../client';
import Client, { Label } from '../../client';
import ActionDispatcher from './action-dispatcher';
import { ActionType } from './action-chooser';
@ -30,12 +30,13 @@ export interface GenericFilter {
export interface LabelFilter {
type: 'label',
label: string
label: Label
}
interface ToolbarButtonInfo {
filter: GenericFilter | LabelFilter,
label: string
icon: any;
}
const MapsPage = () => {
@ -52,7 +53,7 @@ const MapsPage = () => {
const mutation = useMutation(
(label: string) => client.deleteLabel(label),
(id: number) => client.deleteLabel(id),
{
onSuccess: () => queryClient.invalidateQueries('labels')
}
@ -64,34 +65,44 @@ const MapsPage = () => {
setFilter(filter);
};
const handleLabelDelete = (label: string) => {
mutation.mutate(label);
const handleLabelDelete = (id: number) => {
mutation.mutate(id);
};
const { data } = useQuery<unknown, ErrorInfo, string[]>('labels', async () => {
const { data } = useQuery<unknown, ErrorInfo, Label[]>('labels', async () => {
return await client.fetchLabels();
});
const labels: string[] = data ? data : [];
const labels: Label[] = data ? data : [];
const filterButtons: ToolbarButtonInfo[] = [{
filter: { type: 'all' },
label: 'All'
label: 'All',
icon: <AcUnitTwoTone color="secondary" />
}, {
filter: { type: 'owned' },
label: 'Owned'
label: 'Owned',
icon: <PersonOutlineTwoTone color="secondary" />
}, {
filter: { type: 'starred' },
label: 'Starred'
label: 'Starred',
icon: <StarTwoTone color="secondary" />
}, {
filter: { type: 'shared' },
label: 'Shared with me'
label: 'Shared with me',
icon: <ShareTwoTone color="secondary" />
}, {
filter: { type: 'public' },
label: 'Public'
label: 'Public',
icon: <PublicTwoTone color="secondary" />
}];
labels.forEach(l => filterButtons.push({ filter: { type: 'label', label: l }, label: l }))
labels.forEach(l => filterButtons.push({
filter: { type: 'label', label: l },
label: l.title,
icon: <LabelTwoTone style={{ color: l.color ? l.color : 'inherit' }} />
}))
return (
<div className={classes.root}>
@ -147,15 +158,17 @@ const MapsPage = () => {
</div>
<List component="nav">
{filterButtons.map(buttonInfo => (<StyleListItem
icon={<PublicTwoTone color="secondary" />}
label={buttonInfo.label}
filter={buttonInfo.filter}
active={filter}
onClick={handleMenuClick}
onDelete={handleLabelDelete}
key={`${buttonInfo.filter.type}:${(buttonInfo.filter as LabelFilter).label}`}
/>)
{filterButtons.map(buttonInfo => {
return (<StyleListItem
icon={buttonInfo.icon}
label={buttonInfo.label}
filter={buttonInfo.filter}
active={filter}
onClick={handleMenuClick}
onDelete={handleLabelDelete}
key={`${buttonInfo.filter.type}:${(buttonInfo.filter as LabelFilter).label}`}
/>)
}
)}
</List>
@ -179,7 +192,7 @@ interface ListItemProps {
filter: Filter,
active?: Filter
onClick: (filter: Filter) => void;
onDelete?: (label: string) => void;
onDelete?: (id: number) => void;
}
const StyleListItem = (props: ListItemProps) => {
@ -204,7 +217,7 @@ const StyleListItem = (props: ListItemProps) => {
if (!onDeleteLabel) {
throw "Illegal state exeption";
}
onDeleteLabel((filter as LabelFilter).label);
onDeleteLabel((filter as LabelFilter).label.id);
}
return (

View File

@ -47,7 +47,7 @@ type Order = 'asc' | 'desc';
function getComparator<Key extends keyof any>(
order: Order,
orderBy: Key,
): (a: { [key in Key]: number | string | boolean | string[] | undefined }, b: { [key in Key]: number | string | string[] | boolean }) => number {
): (a: { [key in Key]: number | string | boolean | number[] | undefined }, b: { [key in Key]: number | string | number[] | boolean }) => number {
return order === 'desc'
? (a, b) => descendingComparator(a, b, orderBy)
: (a, b) => -descendingComparator(a, b, orderBy);
@ -162,6 +162,8 @@ const mapsFilter = (filter: Filter, search: string): ((mapInfo: MapInfo) => bool
result = mapInfo.starred;
break;
case 'owned':
//@todo: complete ...
result = mapInfo.starred;
break;
case 'shared':
@ -169,8 +171,7 @@ const mapsFilter = (filter: Filter, search: string): ((mapInfo: MapInfo) => bool
result = mapInfo.starred;
break;
case 'label':
//@todo: complete ...
result = !mapInfo.labels || mapInfo.labels.includes((filter as LabelFilter).label)
result = !mapInfo.labels || mapInfo.labels.includes((filter as LabelFilter).label.id)
break;
default:
result = false;
@ -284,6 +285,7 @@ export const MapsList = (props: MapsListProps) => {
queryClient.invalidateQueries('maps');
},
onError: (error) => {
// @todo ...
// setError(error);
}
}