mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
dialog-editor: drop and edit items
This commit is contained in:
parent
a2607b257d
commit
970d0967c8
10 changed files with 279 additions and 150 deletions
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { RouteRow } from '$components/maps/RouteRow';
|
import { RouteRowWrapper } from '$components/maps/RouteRowWrapper';
|
||||||
import { Scroll } from '$components/Scroll';
|
import { Scroll } from '$components/Scroll';
|
||||||
import {
|
import {
|
||||||
searchSetDistance,
|
searchSetDistance,
|
||||||
|
@ -21,6 +21,8 @@ import { IRootState, IRouteListItem } from '$redux/user/reducer';
|
||||||
export interface IMapListDialogProps extends IRootState {
|
export interface IMapListDialogProps extends IRootState {
|
||||||
marks: { [x: number]: string },
|
marks: { [x: number]: string },
|
||||||
routes_sorted: Array<IRouteListItem>,
|
routes_sorted: Array<IRouteListItem>,
|
||||||
|
routes: IRootState['routes'],
|
||||||
|
ready: IRootState['ready'],
|
||||||
|
|
||||||
mapsLoadMore: typeof mapsLoadMore,
|
mapsLoadMore: typeof mapsLoadMore,
|
||||||
searchSetDistance: typeof searchSetDistance,
|
searchSetDistance: typeof searchSetDistance,
|
||||||
|
@ -30,32 +32,44 @@ export interface IMapListDialogProps extends IRootState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMapListDialogState {
|
export interface IMapListDialogState {
|
||||||
selected_item: IRouteListItem['_id'],
|
menu_target: IRouteListItem['_id'],
|
||||||
selected_item_mode: 'menu' | 'edit' | 'drop' | null,
|
editor_target: IRouteListItem['_id'],
|
||||||
|
|
||||||
|
is_editing: boolean,
|
||||||
|
is_dropping: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
class Component extends React.Component<IMapListDialogProps, IMapListDialogState> {
|
class Component extends React.Component<IMapListDialogProps, IMapListDialogState> {
|
||||||
state = {
|
state = {
|
||||||
selected_item: null,
|
menu_target: null,
|
||||||
selected_item_mode: null,
|
editor_target: null,
|
||||||
|
|
||||||
|
is_editing: false,
|
||||||
|
is_dropping: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
startEditing = (selected_item: IRouteListItem['_id']): void => this.setState({
|
startEditing = (editor_target: IRouteListItem['_id']): void => this.setState({
|
||||||
selected_item: ((this.state.selected_item !== selected_item && selected_item) || null),
|
editor_target,
|
||||||
selected_item_mode: 'edit',
|
menu_target: null,
|
||||||
|
is_editing: true,
|
||||||
|
is_dropping: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
showMenu = (selected_item: IRouteListItem['_id']): void => this.setState({
|
showMenu = (menu_target: IRouteListItem['_id']): void => this.setState({
|
||||||
selected_item: ((this.state.selected_item !== selected_item && selected_item) || null),
|
menu_target,
|
||||||
selected_item_mode: 'menu',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
showDropCard = (selected_item: IRouteListItem['_id']): void => this.setState({
|
showDropCard = (editor_target: IRouteListItem['_id']): void => this.setState({
|
||||||
selected_item: ((this.state.selected_item !== selected_item && selected_item) || null),
|
editor_target,
|
||||||
selected_item_mode: 'drop',
|
menu_target: null,
|
||||||
|
is_editing: false,
|
||||||
|
is_dropping: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
stopEditing = (): void => this.setState({ selected_item: null });
|
stopEditing = (): void => {
|
||||||
|
console.log('stop it!');
|
||||||
|
this.setState({ editor_target: null });
|
||||||
|
};
|
||||||
|
|
||||||
setTitle = ({ target: { value } }: { target: { value: string }}): void => {
|
setTitle = ({ target: { value } }: { target: { value: string }}): void => {
|
||||||
this.props.searchSetTitle(value);
|
this.props.searchSetTitle(value);
|
||||||
|
@ -64,6 +78,8 @@ class Component extends React.Component<IMapListDialogProps, IMapListDialogState
|
||||||
openRoute = (_id: string): void => {
|
openRoute = (_id: string): void => {
|
||||||
if (isMobile()) this.props.setDialogActive(false);
|
if (isMobile()) this.props.setDialogActive(false);
|
||||||
|
|
||||||
|
this.stopEditing();
|
||||||
|
|
||||||
pushPath(`/${_id}/${this.props.editing ? 'edit' : ''}`);
|
pushPath(`/${_id}/${this.props.editing ? 'edit' : ''}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,6 +96,8 @@ class Component extends React.Component<IMapListDialogProps, IMapListDialogState
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dropRoute = (): void => null;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
ready,
|
ready,
|
||||||
|
@ -97,7 +115,7 @@ class Component extends React.Component<IMapListDialogProps, IMapListDialogState
|
||||||
marks,
|
marks,
|
||||||
}: IMapListDialogProps = this.props;
|
}: IMapListDialogProps = this.props;
|
||||||
|
|
||||||
const { selected_item, selected_item_mode } = this.state;
|
const { editor_target, menu_target, is_editing, is_dropping } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dialog-content">
|
<div className="dialog-content">
|
||||||
|
@ -166,19 +184,21 @@ class Component extends React.Component<IMapListDialogProps, IMapListDialogState
|
||||||
<div className="dialog-maplist">
|
<div className="dialog-maplist">
|
||||||
{
|
{
|
||||||
list.map(route => (
|
list.map(route => (
|
||||||
<RouteRow
|
<RouteRowWrapper
|
||||||
title={route.title}
|
title={route.title}
|
||||||
distance={route.distance}
|
distance={route.distance}
|
||||||
_id={route._id}
|
_id={route._id}
|
||||||
is_public={route.is_public}
|
is_public={route.is_public}
|
||||||
tab={tab}
|
tab={tab}
|
||||||
selected={(selected_item === route._id)}
|
is_editing_mode={is_dropping ? 'drop' : 'edit'}
|
||||||
mode={selected_item_mode}
|
is_editing_target={editor_target === route._id}
|
||||||
|
is_menu_target={menu_target === route._id}
|
||||||
openRoute={this.openRoute}
|
openRoute={this.openRoute}
|
||||||
startEditing={this.startEditing}
|
startEditing={this.startEditing}
|
||||||
stopEditing={this.stopEditing}
|
stopEditing={this.stopEditing}
|
||||||
showMenu={this.showMenu}
|
showMenu={this.showMenu}
|
||||||
showDropCard={this.showDropCard}
|
showDropCard={this.showDropCard}
|
||||||
|
dropRoute={this.dropRoute}
|
||||||
key={route._id}
|
key={route._id}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
// @flow
|
|
||||||
import * as React from 'react';
|
|
||||||
import { Icon } from '$components/panels/Icon';
|
|
||||||
import classnames from 'classnames';
|
|
||||||
import { IMapListDialogState, MapListDialog } from "$components/dialogs/MapListDialog";
|
|
||||||
import { Tooltip } from "$components/panels/Tooltip";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
_id: string,
|
|
||||||
tab: string,
|
|
||||||
selected: boolean,
|
|
||||||
title: string,
|
|
||||||
distance: number,
|
|
||||||
is_public: boolean,
|
|
||||||
mode: IMapListDialogState['selected_item_mode'],
|
|
||||||
|
|
||||||
openRoute: typeof MapListDialog.openRoute,
|
|
||||||
startEditing: typeof MapListDialog.startEditing,
|
|
||||||
stopEditing: typeof MapListDialog.stopEditing,
|
|
||||||
showMenu: typeof MapListDialog.showMenu,
|
|
||||||
showDropCard: typeof MapListDialog.showDropCard,
|
|
||||||
key: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const RouteRow = ({
|
|
||||||
title, distance, _id, openRoute, tab, selected, startEditing, showMenu, showDropCard, mode
|
|
||||||
}: Props) => (
|
|
||||||
<div
|
|
||||||
className={classnames('route-row-wrapper', {
|
|
||||||
selected,
|
|
||||||
has_menu: selected && mode === 'menu',
|
|
||||||
has_drop: selected && mode === 'drop',
|
|
||||||
has_edit: selected && mode === 'edit',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="route-row"
|
|
||||||
>
|
|
||||||
<div onClick={() => openRoute(_id)}>
|
|
||||||
<div className="route-title">
|
|
||||||
<span>{(title || _id)}</span>
|
|
||||||
</div>
|
|
||||||
<div className="route-description">
|
|
||||||
<span>
|
|
||||||
<Icon icon="icon-link-1" />
|
|
||||||
{_id}
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<Icon icon="icon-cycle-1" />
|
|
||||||
{(distance && `${distance} km`) || '0 km'}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="route-row-edit-button pointer" onClick={() => showMenu(_id)}>
|
|
||||||
<Icon icon="icon-more-vert" />
|
|
||||||
<div className="route-row-edit-menu">
|
|
||||||
<div onClick={() => showDropCard(_id)}>
|
|
||||||
<Tooltip>Удалить</Tooltip>
|
|
||||||
<Icon icon="icon-trash-3" size={32} />
|
|
||||||
</div>
|
|
||||||
<div onClick={() => startEditing(_id)}>
|
|
||||||
<Tooltip>Редактировать</Tooltip>
|
|
||||||
<Icon icon="icon-edit-1" size={32} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
29
src/components/maps/RouteRowDrop.tsx
Normal file
29
src/components/maps/RouteRowDrop.tsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Icon } from '$components/panels/Icon';
|
||||||
|
import { MapListDialog } from "$components/dialogs/MapListDialog";
|
||||||
|
import { Tooltip } from "$components/panels/Tooltip";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
_id: string,
|
||||||
|
stopEditing: typeof MapListDialog.stopEditing,
|
||||||
|
dropRoute: typeof MapListDialog.dropRoute,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RouteRowDrop = ({
|
||||||
|
_id, stopEditing, dropRoute,
|
||||||
|
}: Props): ReactElement<Props, null> => (
|
||||||
|
<div
|
||||||
|
className="route-row-drop"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="route-row"
|
||||||
|
>
|
||||||
|
<div className="button-group">
|
||||||
|
<div className="button" onClick={() => dropRoute(_id)}>Удалить</div>
|
||||||
|
<div className="button primary" onClick={stopEditing}>Отмена</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
|
@ -5,9 +5,8 @@ import { Switch } from '$components/Switch';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
is_editing: boolean;
|
|
||||||
distance: number;
|
|
||||||
_id: string;
|
_id: string;
|
||||||
|
is_public: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -32,46 +31,34 @@ export class RouteRowEditor extends React.Component<Props, State> {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
state: { title, is_public },
|
state: { title, is_public },
|
||||||
props: { distance, _id }
|
props: { _id }
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="route-row-edit">
|
||||||
className="route-row"
|
<div className="route-row">
|
||||||
>
|
<div className="route-title">
|
||||||
<div className="route-title">
|
<input
|
||||||
<input
|
type="text"
|
||||||
type="text"
|
value={title}
|
||||||
value={title}
|
onChange={this.setTitle}
|
||||||
onChange={this.setTitle}
|
placeholder="Введите название"
|
||||||
placeholder="Введите название"
|
autoFocus
|
||||||
autoFocus
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
<div className="route-row-editor">
|
||||||
<div className="route-description">
|
<div className="route-row-buttons">
|
||||||
<span>
|
<div className="flex_1" onClick={this.setPublic}>
|
||||||
<Icon icon="icon-link-1" />
|
<Switch active={is_public} />
|
||||||
{_id}
|
{
|
||||||
</span>
|
is_public
|
||||||
<span>
|
? ' В каталоге карт'
|
||||||
<Icon icon="icon-cycle-1" />
|
: ' Только по ссылке'
|
||||||
{(distance && `${distance} km`) || '0 km'}
|
}
|
||||||
</span>
|
</div>
|
||||||
</div>
|
<div className="button primary" onClick={this.stopEditing}>
|
||||||
<div className="route-row-editor">
|
OK
|
||||||
<div className="route-row-buttons">
|
</div>
|
||||||
<div className="flex_1" onClick={this.setPublic}>
|
|
||||||
<Switch
|
|
||||||
active={is_public}
|
|
||||||
/>
|
|
||||||
{
|
|
||||||
is_public
|
|
||||||
? ' В каталоге карт'
|
|
||||||
: ' Только по ссылке'
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className="button primary" onClick={this.stopEditing}>
|
|
||||||
OK
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
61
src/components/maps/RouteRowView.tsx
Normal file
61
src/components/maps/RouteRowView.tsx
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Icon } from '$components/panels/Icon';
|
||||||
|
import { MapListDialog } from "$components/dialogs/MapListDialog";
|
||||||
|
import { Tooltip } from "$components/panels/Tooltip";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
_id: string,
|
||||||
|
tab: string,
|
||||||
|
title: string,
|
||||||
|
distance: number,
|
||||||
|
is_public: boolean,
|
||||||
|
|
||||||
|
openRoute: typeof MapListDialog.openRoute,
|
||||||
|
startEditing: typeof MapListDialog.startEditing,
|
||||||
|
stopEditing: typeof MapListDialog.stopEditing,
|
||||||
|
showMenu: typeof MapListDialog.showMenu,
|
||||||
|
showDropCard: typeof MapListDialog.showDropCard,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RouteRowView = ({
|
||||||
|
title, distance, _id, openRoute, tab, startEditing, showMenu, showDropCard
|
||||||
|
}: Props): ReactElement<Props, null> => (
|
||||||
|
<div
|
||||||
|
className="route-row-view"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="route-row"
|
||||||
|
onClick={() => openRoute(_id)}
|
||||||
|
>
|
||||||
|
<div className="route-title">
|
||||||
|
<span>{(title || _id)}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="route-description">
|
||||||
|
<span>
|
||||||
|
<Icon icon="icon-link-1" />
|
||||||
|
{_id}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<Icon icon="icon-cycle-1" />
|
||||||
|
{(distance && `${distance} km`) || '0 km'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="route-row-edit-button pointer" onClick={() => showMenu(_id)}>
|
||||||
|
<Icon icon="icon-more-vert" />
|
||||||
|
</div>
|
||||||
|
<div className="route-row-edit-menu pointer">
|
||||||
|
<div onMouseDown={() => showDropCard(_id)}>
|
||||||
|
<Tooltip>Удалить</Tooltip>
|
||||||
|
<Icon icon="icon-trash-3" size={32} />
|
||||||
|
</div>
|
||||||
|
<div onMouseDown={() => startEditing(_id)}>
|
||||||
|
<Tooltip>Редактировать</Tooltip>
|
||||||
|
<Icon icon="icon-edit-1" size={32} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
72
src/components/maps/RouteRowWrapper.tsx
Normal file
72
src/components/maps/RouteRowWrapper.tsx
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { MapListDialog } from "$components/dialogs/MapListDialog";
|
||||||
|
import { RouteRowView } from "$components/maps/RouteRowView";
|
||||||
|
import { RouteRowEditor } from "$components/maps/RouteRowEditor";
|
||||||
|
import { RouteRowDrop } from "$components/maps/RouteRowDrop";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
_id: string,
|
||||||
|
tab: string,
|
||||||
|
title: string,
|
||||||
|
distance: number,
|
||||||
|
is_public: boolean,
|
||||||
|
|
||||||
|
is_editing_target: boolean,
|
||||||
|
is_menu_target: boolean,
|
||||||
|
|
||||||
|
openRoute: typeof MapListDialog.openRoute,
|
||||||
|
startEditing: typeof MapListDialog.startEditing,
|
||||||
|
stopEditing: typeof MapListDialog.stopEditing,
|
||||||
|
showMenu: typeof MapListDialog.showMenu,
|
||||||
|
showDropCard: typeof MapListDialog.showDropCard,
|
||||||
|
dropRoute: typeof MapListDialog.dropRoute,
|
||||||
|
|
||||||
|
is_editing_mode: 'edit' | 'drop',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RouteRowWrapper = ({
|
||||||
|
title, distance, _id, openRoute, tab, startEditing, showMenu,
|
||||||
|
showDropCard, is_public, is_editing_target, is_menu_target, is_editing_mode,
|
||||||
|
dropRoute, stopEditing,
|
||||||
|
}: Props): ReactElement<Props, null> => (
|
||||||
|
<div
|
||||||
|
className={classnames('route-row-wrapper', {
|
||||||
|
is_menu_target,
|
||||||
|
is_editing_target,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
is_editing_target && is_editing_mode === 'edit' &&
|
||||||
|
<RouteRowEditor
|
||||||
|
title={title}
|
||||||
|
_id={_id}
|
||||||
|
is_public={is_public}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
is_editing_target && is_editing_mode === 'drop' &&
|
||||||
|
<RouteRowDrop
|
||||||
|
_id={_id}
|
||||||
|
dropRoute={dropRoute}
|
||||||
|
stopEditing={stopEditing}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!is_editing_target &&
|
||||||
|
<RouteRowView
|
||||||
|
_id={_id}
|
||||||
|
tab={tab}
|
||||||
|
title={title}
|
||||||
|
distance={distance}
|
||||||
|
is_public={is_public}
|
||||||
|
openRoute={openRoute}
|
||||||
|
startEditing={startEditing}
|
||||||
|
stopEditing={stopEditing}
|
||||||
|
showMenu={showMenu}
|
||||||
|
showDropCard={showDropCard}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
|
@ -1,11 +1,10 @@
|
||||||
import { Map, LayerGroup, LatLng, LatLngLiteral, LeafletEventHandlerFn, marker, divIcon, Marker } from 'leaflet';
|
import { Map, LatLng } from 'leaflet';
|
||||||
import { EditablePolyline } from '$utils/EditablePolyline';
|
import { EditablePolyline } from '$utils/EditablePolyline';
|
||||||
import { simplify } from '$utils/simplify';
|
import { simplify } from '$utils/simplify';
|
||||||
import { CLIENT } from '$config/frontend';
|
import { CLIENT } from '$config/frontend';
|
||||||
import { editor, Editor } from "$modules/Editor";
|
import { editor, Editor } from "$modules/Editor";
|
||||||
import { ILatLng } from "$modules/Stickers";
|
import { ILatLng } from "$modules/Stickers";
|
||||||
import { InteractivePoly } from "$modules/InteractivePoly";
|
import { InteractivePoly } from "$modules/InteractivePoly";
|
||||||
import { clusterIcon } from "$utils/clusterIcon";
|
|
||||||
import { MarkerClusterGroup } from 'leaflet.markercluster/dist/leaflet.markercluster-src.js';
|
import { MarkerClusterGroup } from 'leaflet.markercluster/dist/leaflet.markercluster-src.js';
|
||||||
import { angleBetweenPoints, dist2, distToSegment, middleCoord } from "$utils/geom";
|
import { angleBetweenPoints, dist2, distToSegment, middleCoord } from "$utils/geom";
|
||||||
import { arrowClusterIcon, createArrow } from "$utils/arrow";
|
import { arrowClusterIcon, createArrow } from "$utils/arrow";
|
||||||
|
@ -23,17 +22,17 @@ export class Poly {
|
||||||
constructor({
|
constructor({
|
||||||
map, routerMoveStart, lockMapClicks, setDistance, triggerOnChange, editor,
|
map, routerMoveStart, lockMapClicks, setDistance, triggerOnChange, editor,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
this.poly = new InteractivePoly([], {
|
this.poly = new InteractivePoly([ ], {
|
||||||
color: 'url(#activePathGradient)',
|
color: 'url(#activePathGradient)',
|
||||||
weight: 6,
|
weight: 6,
|
||||||
maxMarkers: 100,
|
maxMarkers: 100,
|
||||||
smoothFactor: 3,
|
smoothFactor: 3,
|
||||||
// bubblingMouseEvents: false,
|
|
||||||
})
|
})
|
||||||
.on('distancechange', this.onDistanceUpdate)
|
.on('distancechange', this.onDistanceUpdate)
|
||||||
.on('allvertexhide', this.onVertexHide)
|
.on('allvertexhide', this.onVertexHide)
|
||||||
.on('allvertexshow', this.onVertexShow)
|
.on('allvertexshow', this.onVertexShow)
|
||||||
.on('latlngschange', this.updateArrows);
|
.on('latlngschange', this.updateArrows)
|
||||||
|
.on('latlngschange', triggerOnChange);
|
||||||
|
|
||||||
this.poly.addTo(map);
|
this.poly.addTo(map);
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
@ -162,7 +161,7 @@ export class Poly {
|
||||||
return (!this.latlngs || Object.values(this.latlngs).length <= 0);
|
return (!this.latlngs || Object.values(this.latlngs).length <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
poly: EditablePolyline;
|
poly;
|
||||||
arrowLayer: MarkerClusterGroup = new MarkerClusterGroup({
|
arrowLayer: MarkerClusterGroup = new MarkerClusterGroup({
|
||||||
spiderfyOnMaxZoom: false,
|
spiderfyOnMaxZoom: false,
|
||||||
showCoverageOnHover: false,
|
showCoverageOnHover: false,
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
box-shadow: inset rgba(100,100,100, 0.3) 1px 0, inset rgba(0,0,0, 0.1) -1px 0;
|
box-shadow: inset rgba(100,100,100, 0.3) 1px 0, inset rgba(0,0,0, 0.1) -1px 0;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
border: none;
|
||||||
|
|
||||||
&.primary {
|
&.primary {
|
||||||
background: #3c78db;
|
background: #3c78db;
|
||||||
|
|
|
@ -188,13 +188,14 @@
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
transition: all 500ms;
|
transition: all 500ms;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
&.has_edit {
|
&.has_edit {
|
||||||
//transform: translateY(-2px);
|
//transform: translateY(-2px);
|
||||||
.route-row { background: rgba(255, 100, 100, 0.2); }
|
.route-row { background: fade(@green_secondary, 30%); }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.has_menu {
|
&.is_menu_target {
|
||||||
.route-row {
|
.route-row {
|
||||||
transform: translateX(-100px);
|
transform: translateX(-100px);
|
||||||
}
|
}
|
||||||
|
@ -204,18 +205,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
//.route-row-editor {
|
.route-row-editor {
|
||||||
// color: white;
|
color: white;
|
||||||
// padding: 20px 0 5px;
|
padding: 5px 0 5px;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//.route-row-buttons {
|
.route-row-buttons {
|
||||||
// flex: 1;
|
flex: 1;
|
||||||
// flex-direction: row;
|
flex-direction: row;
|
||||||
// display: flex;
|
display: flex;
|
||||||
// align-items: center;
|
align-items: center;
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
.route-row-view {
|
||||||
|
overflow: hidden;
|
||||||
|
transition: height 500ms;
|
||||||
|
padding-right: 32px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.route-row-edit {
|
||||||
|
background: fade(@green_secondary, 30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.route-row-drop {
|
||||||
|
background: fade(@red_secondary, 20%);
|
||||||
|
|
||||||
|
.route-row {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.route-row {
|
.route-row {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
@ -226,6 +246,12 @@
|
||||||
transition: background 250ms, transform 500ms;
|
transition: background 250ms, transform 500ms;
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 64px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
@ -246,7 +272,10 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
transition: all 250ms;
|
transition: all 250ms;
|
||||||
position: relative;
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
@ -256,13 +285,14 @@
|
||||||
.route-row-edit-menu {
|
.route-row-edit-menu {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
right: 100%;
|
right: 32px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: rgba(0, 0, 0, 0.1);
|
background: rgba(0, 0, 0, 0.1);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all 500ms;
|
transition: all 500ms;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
fill: fade(white, 30%);
|
||||||
|
|
||||||
div {
|
div {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
|
|
|
@ -41,7 +41,6 @@ const resolve = {
|
||||||
$utils: join(__dirname, 'src/utils'),
|
$utils: join(__dirname, 'src/utils'),
|
||||||
$modules: join(__dirname, 'src/modules'),
|
$modules: join(__dirname, 'src/modules'),
|
||||||
},
|
},
|
||||||
|
|
||||||
extensions: ['*', '.ts', '.tsx', '.js', '.jsx', '.json']
|
extensions: ['*', '.ts', '.tsx', '.js', '.jsx', '.json']
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue