mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-25 15:47:55 +01:00
Add label calor support
This commit is contained in:
parent
858050096f
commit
9596852c90
@ -6,11 +6,19 @@ export type NewUser = {
|
|||||||
recaptcha: string | null;
|
recaptcha: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Label = {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
color: string;
|
||||||
|
iconName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export type MapInfo = {
|
export type MapInfo = {
|
||||||
id: number;
|
id: number;
|
||||||
starred: boolean;
|
starred: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
labels: string[];
|
labels: number[];
|
||||||
creator: string;
|
creator: string;
|
||||||
modified: string;
|
modified: string;
|
||||||
description: string;
|
description: string;
|
||||||
@ -41,16 +49,17 @@ export type ErrorInfo = {
|
|||||||
|
|
||||||
interface Client {
|
interface Client {
|
||||||
createMap(map: BasicMapInfo): Promise<number>;
|
createMap(map: BasicMapInfo): Promise<number>;
|
||||||
deleteLabel(label: string): Promise<void>;
|
|
||||||
registerNewUser(user: NewUser): Promise<void>;
|
registerNewUser(user: NewUser): Promise<void>;
|
||||||
resetPassword(email: string): Promise<void>;
|
resetPassword(email: string): Promise<void>;
|
||||||
fetchAllMaps(): Promise<MapInfo[]>;
|
fetchAllMaps(): Promise<MapInfo[]>;
|
||||||
fetchLabels(): Promise<string[]>;
|
|
||||||
deleteMap(id: number): Promise<void>;
|
deleteMap(id: number): Promise<void>;
|
||||||
renameMap(id: number, basicInfo: BasicMapInfo): Promise<void>;
|
renameMap(id: number, basicInfo: BasicMapInfo): Promise<void>;
|
||||||
duplicateMap(id: number, basicInfo: BasicMapInfo): Promise<number>;
|
duplicateMap(id: number, basicInfo: BasicMapInfo): Promise<number>;
|
||||||
loadMapInfo(id: number): Promise<BasicMapInfo>;
|
loadMapInfo(id: number): Promise<BasicMapInfo>;
|
||||||
changeStarred(id: number, starred: boolean): Promise<void>;
|
changeStarred(id: number, starred: boolean): Promise<void>;
|
||||||
|
|
||||||
|
fetchLabels(): Promise<Label[]>;
|
||||||
|
deleteLabel(id: number): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import Client, { BasicMapInfo, MapInfo, NewUser } from '..';
|
import Client, { BasicMapInfo, Label, MapInfo, NewUser } from '..';
|
||||||
|
|
||||||
class MockClient implements Client {
|
class MockClient implements Client {
|
||||||
private maps: MapInfo[] = [];
|
private maps: MapInfo[] = [];
|
||||||
private labels: string[] = [];
|
private labels: Label[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ class MockClient implements Client {
|
|||||||
id: number,
|
id: number,
|
||||||
starred: boolean,
|
starred: boolean,
|
||||||
title: string,
|
title: string,
|
||||||
labels: string[],
|
labels: number[],
|
||||||
creator: string,
|
creator: string,
|
||||||
modified: string,
|
modified: string,
|
||||||
description: string,
|
description: string,
|
||||||
@ -20,21 +20,24 @@ class MockClient implements Client {
|
|||||||
return { id, title, labels, creator, modified, starred, description, isPublic };
|
return { id, title, labels, creator, modified, starred, description, isPublic };
|
||||||
}
|
}
|
||||||
this.maps = [
|
this.maps = [
|
||||||
createMapInfo(1, true, "El Mapa", [""], "Paulo", "2008-06-02T00:00:00Z", "", true),
|
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(2, false, "El Mapa2", [], "Paulo2", "2008-06-02T00:00:00Z", "", false),
|
||||||
createMapInfo(3, false, "El Mapa3", [""], "Paulo3", "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(4, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
|
||||||
createMapInfo(5, 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(6, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
|
||||||
createMapInfo(7, 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(8, false, "El Mapa3", [], "Paulo3", "2008-06-02T00:00:00Z", "", false),
|
||||||
createMapInfo(9, 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(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(11, false, "El Mapa3", [1, 2, 3], "Paulo3", "2008-06-02T00:00:00Z", "", false),
|
||||||
createMapInfo(12, false, "El Mapa3", ["label 2"], "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.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchLabels(): Promise<string[]> {
|
fetchLabels(): Promise<Label[]> {
|
||||||
console.log("Fetching labels from server")
|
console.log("Fetching labels from server")
|
||||||
return Promise.resolve(this.labels);
|
return Promise.resolve(this.labels);
|
||||||
}
|
}
|
||||||
@ -63,10 +66,6 @@ class MockClient implements Client {
|
|||||||
return Promise.resolve({ title: 'My Map', description: 'My Description' });
|
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> {
|
renameMap(id: number, basicInfo: BasicMapInfo): Promise<void> {
|
||||||
|
|
||||||
const exists = this.maps.find(m => m.title == basicInfo.title) != undefined;
|
const exists = this.maps.find(m => m.title == basicInfo.title) != undefined;
|
||||||
@ -121,9 +120,9 @@ class MockClient implements Client {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteLabel(label: string): Promise<void> {
|
deleteLabel(id: number): Promise<void> {
|
||||||
this.labels = this.labels.filter(l => l != label);
|
this.labels = this.labels.filter(l => l.id != id);
|
||||||
console.log("Label delete:" + label);
|
console.log("Label delete:" + this.labels);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { ErrorInfo, MapInfo, BasicMapInfo, NewUser } from '..';
|
import { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label } from '..';
|
||||||
import MockClient from '../mock-client/';
|
import MockClient from '../mock-client/';
|
||||||
|
|
||||||
//@Remove inheritance once is it completed.
|
//@Remove inheritance once is it completed.
|
||||||
@ -196,5 +196,10 @@ export default class RestClient extends MockClient {
|
|||||||
}
|
}
|
||||||
return new Promise(handler);
|
return new Promise(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteLabel(id: number): Promise<void> {
|
||||||
|
console.log("Fetching labels from server")
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@ import IconButton from '@material-ui/core/IconButton';
|
|||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||||
import { useStyles } from './style';
|
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 { Button, Link, ListItemSecondaryAction, ListItemText, Menu, MenuItem, Tooltip } from '@material-ui/core';
|
||||||
import { MapsList } from './maps-list';
|
import { MapsList } from './maps-list';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { useQuery, useMutation, useQueryClient } from 'react-query';
|
import { useQuery, useMutation, useQueryClient } from 'react-query';
|
||||||
import { activeInstance } from '../../reducers/serviceSlice';
|
import { activeInstance } from '../../reducers/serviceSlice';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import Client from '../../client';
|
import Client, { Label } from '../../client';
|
||||||
import ActionDispatcher from './action-dispatcher';
|
import ActionDispatcher from './action-dispatcher';
|
||||||
import { ActionType } from './action-chooser';
|
import { ActionType } from './action-chooser';
|
||||||
|
|
||||||
@ -30,12 +30,13 @@ export interface GenericFilter {
|
|||||||
|
|
||||||
export interface LabelFilter {
|
export interface LabelFilter {
|
||||||
type: 'label',
|
type: 'label',
|
||||||
label: string
|
label: Label
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ToolbarButtonInfo {
|
interface ToolbarButtonInfo {
|
||||||
filter: GenericFilter | LabelFilter,
|
filter: GenericFilter | LabelFilter,
|
||||||
label: string
|
label: string
|
||||||
|
icon: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapsPage = () => {
|
const MapsPage = () => {
|
||||||
@ -52,7 +53,7 @@ const MapsPage = () => {
|
|||||||
|
|
||||||
|
|
||||||
const mutation = useMutation(
|
const mutation = useMutation(
|
||||||
(label: string) => client.deleteLabel(label),
|
(id: number) => client.deleteLabel(id),
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.invalidateQueries('labels')
|
onSuccess: () => queryClient.invalidateQueries('labels')
|
||||||
}
|
}
|
||||||
@ -64,34 +65,44 @@ const MapsPage = () => {
|
|||||||
setFilter(filter);
|
setFilter(filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLabelDelete = (label: string) => {
|
const handleLabelDelete = (id: number) => {
|
||||||
mutation.mutate(label);
|
mutation.mutate(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data } = useQuery<unknown, ErrorInfo, string[]>('labels', async () => {
|
const { data } = useQuery<unknown, ErrorInfo, Label[]>('labels', async () => {
|
||||||
return await client.fetchLabels();
|
return await client.fetchLabels();
|
||||||
});
|
});
|
||||||
|
|
||||||
const labels: string[] = data ? data : [];
|
const labels: Label[] = data ? data : [];
|
||||||
const filterButtons: ToolbarButtonInfo[] = [{
|
const filterButtons: ToolbarButtonInfo[] = [{
|
||||||
filter: { type: 'all' },
|
filter: { type: 'all' },
|
||||||
label: 'All'
|
label: 'All',
|
||||||
|
icon: <AcUnitTwoTone color="secondary" />
|
||||||
}, {
|
}, {
|
||||||
filter: { type: 'owned' },
|
filter: { type: 'owned' },
|
||||||
label: 'Owned'
|
label: 'Owned',
|
||||||
|
icon: <PersonOutlineTwoTone color="secondary" />
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
filter: { type: 'starred' },
|
filter: { type: 'starred' },
|
||||||
label: 'Starred'
|
label: 'Starred',
|
||||||
|
icon: <StarTwoTone color="secondary" />
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
filter: { type: 'shared' },
|
filter: { type: 'shared' },
|
||||||
label: 'Shared with me'
|
label: 'Shared with me',
|
||||||
|
icon: <ShareTwoTone color="secondary" />
|
||||||
}, {
|
}, {
|
||||||
filter: { type: 'public' },
|
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 (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
@ -147,8 +158,9 @@ const MapsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<List component="nav">
|
<List component="nav">
|
||||||
{filterButtons.map(buttonInfo => (<StyleListItem
|
{filterButtons.map(buttonInfo => {
|
||||||
icon={<PublicTwoTone color="secondary" />}
|
return (<StyleListItem
|
||||||
|
icon={buttonInfo.icon}
|
||||||
label={buttonInfo.label}
|
label={buttonInfo.label}
|
||||||
filter={buttonInfo.filter}
|
filter={buttonInfo.filter}
|
||||||
active={filter}
|
active={filter}
|
||||||
@ -156,6 +168,7 @@ const MapsPage = () => {
|
|||||||
onDelete={handleLabelDelete}
|
onDelete={handleLabelDelete}
|
||||||
key={`${buttonInfo.filter.type}:${(buttonInfo.filter as LabelFilter).label}`}
|
key={`${buttonInfo.filter.type}:${(buttonInfo.filter as LabelFilter).label}`}
|
||||||
/>)
|
/>)
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
@ -179,7 +192,7 @@ interface ListItemProps {
|
|||||||
filter: Filter,
|
filter: Filter,
|
||||||
active?: Filter
|
active?: Filter
|
||||||
onClick: (filter: Filter) => void;
|
onClick: (filter: Filter) => void;
|
||||||
onDelete?: (label: string) => void;
|
onDelete?: (id: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyleListItem = (props: ListItemProps) => {
|
const StyleListItem = (props: ListItemProps) => {
|
||||||
@ -204,7 +217,7 @@ const StyleListItem = (props: ListItemProps) => {
|
|||||||
if (!onDeleteLabel) {
|
if (!onDeleteLabel) {
|
||||||
throw "Illegal state exeption";
|
throw "Illegal state exeption";
|
||||||
}
|
}
|
||||||
onDeleteLabel((filter as LabelFilter).label);
|
onDeleteLabel((filter as LabelFilter).label.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -47,7 +47,7 @@ type Order = 'asc' | 'desc';
|
|||||||
function getComparator<Key extends keyof any>(
|
function getComparator<Key extends keyof any>(
|
||||||
order: Order,
|
order: Order,
|
||||||
orderBy: Key,
|
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'
|
return order === 'desc'
|
||||||
? (a, b) => descendingComparator(a, b, orderBy)
|
? (a, b) => descendingComparator(a, b, orderBy)
|
||||||
: (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;
|
result = mapInfo.starred;
|
||||||
break;
|
break;
|
||||||
case 'owned':
|
case 'owned':
|
||||||
|
//@todo: complete ...
|
||||||
|
|
||||||
result = mapInfo.starred;
|
result = mapInfo.starred;
|
||||||
break;
|
break;
|
||||||
case 'shared':
|
case 'shared':
|
||||||
@ -169,8 +171,7 @@ const mapsFilter = (filter: Filter, search: string): ((mapInfo: MapInfo) => bool
|
|||||||
result = mapInfo.starred;
|
result = mapInfo.starred;
|
||||||
break;
|
break;
|
||||||
case 'label':
|
case 'label':
|
||||||
//@todo: complete ...
|
result = !mapInfo.labels || mapInfo.labels.includes((filter as LabelFilter).label.id)
|
||||||
result = !mapInfo.labels || mapInfo.labels.includes((filter as LabelFilter).label)
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = false;
|
result = false;
|
||||||
@ -284,6 +285,7 @@ export const MapsList = (props: MapsListProps) => {
|
|||||||
queryClient.invalidateQueries('maps');
|
queryClient.invalidateQueries('maps');
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
// @todo ...
|
||||||
// setError(error);
|
// setError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user