complete item editing

This commit is contained in:
muerwre 2019-03-07 11:49:40 +07:00
parent 7513f79b93
commit 0cbbc0ce8a
12 changed files with 94 additions and 34 deletions

View file

@ -13,6 +13,7 @@ const RouteSchema = new Schema(
owner: { type: Schema.Types.ObjectId, ref: 'User' },
distance: { type: Number, default: 0 },
is_public: { type: Boolean, default: false },
is_deleted: { type: Boolean, default: false },
created_at: { type: Date, default: Date.now() },
updated_at: { type: Date, default: Date.now() },
logo: { type: String, default: 'DEFAULT' },

View file

@ -12,7 +12,7 @@ module.exports = async (req, res) => {
if (!exists) return res.send({ success: false, mode: 'not_exists' });
if (exists && exists.owner._id !== id) return res.send({ success: false, mode: 'not_yours' });
exists.delete();
await exists.set({ is_deleted: true }).save();
return res.send({ success: true, address });
};

View file

@ -6,7 +6,7 @@ module.exports = async (req, res) => {
if (!name) return res.send({ success: false, mode: 'not_found_1' });
const exists = await Route.findOne({ _id: name }).populate('owner', '_id');
const exists = await Route.findOne({ _id: name, is_deleted: false }).populate('owner', '_id');
if (!exists) return res.send({ success: false, mode: 'not_found_2' });
const data = exists.toObject();

View file

@ -9,7 +9,7 @@ module.exports = async (req, res) => {
const user = await User.findOne({ _id: id, token });
let criteria = {};
let criteria = { is_deleted: false };
if (title) {
criteria = {
@ -32,16 +32,14 @@ module.exports = async (req, res) => {
{
...criteria,
},
'_id title distance owner updated_at is_public',
'_id title distance owner updated_at is_public is_deleted',
{
limit: 9000,
sort: { updated_at: -1 },
}
).populate('owner', '_id');
list = list.filter(item => (
!author || item.owner._id === author
));
list = list.filter(item => !author || (item.owner && item.owner._id === author));
let limits = list.reduce(({ min, max }, { distance: dist }) => ({
min: Math.ceil(Math.min(dist, min) / 25) * 25,

View file

@ -12,7 +12,7 @@ module.exports = async (req, res) => {
const title = parseString(body.title, 32);
const is_public = !!body.is_public;
const exists = await Route.findOne({ _id: address }).populate('owner', '_id');
const exists = await Route.findOne({ _id: address, is_deleted: false }).populate('owner', '_id');
if (!exists) return res.send({ success: false, mode: 'not_exists' });
if (exists && exists.owner._id !== id) return res.send({ success: false, mode: 'not_yours' });

View file

@ -21,7 +21,7 @@ module.exports = async (req, res) => {
return res.send({ success: false, mode: 'empty' });
}
const exists = await Route.findOne({ _id: address }).populate('owner', '_id');
const exists = await Route.findOne({ _id: address, is_deleted: false }).populate('owner', '_id');
if (exists && exists.owner._id !== id) return res.send({ success: false, mode: 'exists' });
if (exists && !force) return res.send({ success: false, mode: 'overwriting' });

View file

@ -64,6 +64,10 @@ class Component extends React.Component<IMapListDialogProps, IMapListDialogState
menu_target,
});
hideMenu = (): void => this.setState({
menu_target: null,
});
showDropCard = (editor_target: IRouteListItem['_id']): void => this.setState({
editor_target,
menu_target: null,
@ -211,6 +215,7 @@ class Component extends React.Component<IMapListDialogProps, IMapListDialogState
startEditing={this.startEditing}
stopEditing={this.stopEditing}
showMenu={this.showMenu}
hideMenu={this.hideMenu}
showDropCard={this.showDropCard}
dropRoute={this.dropRoute}
modifyRoute={this.modifyRoute}

View file

@ -4,6 +4,7 @@ import { Icon } from '$components/panels/Icon';
import { MapListDialog } from "$components/dialogs/MapListDialog";
import { Tooltip } from "$components/panels/Tooltip";
import { ReactElement } from "react";
import classnames from 'classnames';
interface Props {
_id: string,
@ -16,14 +17,15 @@ interface Props {
startEditing: typeof MapListDialog.startEditing,
stopEditing: typeof MapListDialog.stopEditing,
showMenu: typeof MapListDialog.showMenu,
hideMenu: typeof MapListDialog.hideMenu,
showDropCard: typeof MapListDialog.showDropCard,
}
export const RouteRowView = ({
title, distance, _id, openRoute, tab, startEditing, showMenu, showDropCard
title, distance, _id, openRoute, tab, startEditing, showMenu, showDropCard, hideMenu,
}: Props): ReactElement<Props, null> => (
<div
className="route-row-view"
className={classnames('route-row-view', { has_menu: (tab === 'mine') })}
>
<div
className="route-row"
@ -44,18 +46,27 @@ export const RouteRowView = ({
</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>
{
tab === 'mine' &&
<React.Fragment>
<div
className="route-row-edit-button pointer"
onMouseOver={showMenu.bind(null, _id)}
onMouseOut={hideMenu}
>
<Icon icon="icon-more-vert" />
<div className="route-row-edit-menu pointer">
<div onMouseDown={showDropCard.bind(null, _id)}>
<Tooltip>Удалить</Tooltip>
<Icon icon="icon-trash-3" size={32} />
</div>
<div onMouseDown={startEditing.bind(null, _id)} className="modify-button">
<Tooltip>Редактировать</Tooltip>
<Icon icon="icon-edit-1" size={32} />
</div>
</div>
</div>
</React.Fragment>
}
</div>
);

View file

@ -20,6 +20,7 @@ interface Props {
startEditing: typeof MapListDialog.startEditing,
stopEditing: typeof MapListDialog.stopEditing,
showMenu: typeof MapListDialog.showMenu,
hideMenu: typeof MapListDialog.hideMenu,
showDropCard: typeof MapListDialog.showDropCard,
dropRoute: typeof MapListDialog.dropRoute,
modifyRoute: typeof MapListDialog.modifyRoute,
@ -30,7 +31,7 @@ interface Props {
export const RouteRowWrapper = ({
title, distance, _id, openRoute, tab, startEditing, showMenu,
showDropCard, is_public, is_editing_target, is_menu_target, is_editing_mode,
dropRoute, stopEditing, modifyRoute,
dropRoute, stopEditing, modifyRoute, hideMenu,
}: Props): ReactElement<Props, null> => (
<div
className={classnames('route-row-wrapper', {
@ -67,6 +68,7 @@ export const RouteRowWrapper = ({
startEditing={startEditing}
stopEditing={stopEditing}
showMenu={showMenu}
hideMenu={hideMenu}
showDropCard={showDropCard}
/>
}

View file

@ -649,16 +649,46 @@ function* mapsLoadMoreSaga() {
function* dropRouteSaga({ _id }: ReturnType<typeof ActionCreators.dropRoute>): SagaIterator {
const { id, token } = yield select(getUser);
const result = yield call(dropRoute, { address: _id, id, token });
const {
routes: { list, step, shift, limit, filter: { min, max } }
} = yield select(getState);
console.log('result', result);
const index = list.findIndex(el => el._id === _id);
if (index >= 0) {
yield put(searchPutRoutes({
list: list.filter(el => el._id !== _id),
min,
max,
step,
shift: (shift > 0) ? shift - 1 : 0,
limit: (limit > 0) ? limit - 1 : limit,
}));
}
return yield call(dropRoute, { address: _id, id, token });
}
function* modifyRouteSaga({ _id, title, is_public }: ReturnType<typeof ActionCreators.modifyRoute>): SagaIterator {
const { id, token } = yield select(getUser);
const result = yield call(modifyRoute, { address: _id, id, token, title, is_public });
const {
routes: { list, step, shift, limit, filter: { min, max } }
} = yield select(getState);
console.log('result', result);
const index = list.findIndex(el => el._id === _id);
if (index >= 0) {
yield put(searchPutRoutes({
list: list.map(el => (el._id !== _id ? el : { ...el, title, is_public })),
min,
max,
step,
shift: (shift > 0) ? shift - 1 : 0,
limit: (limit > 0) ? limit - 1 : limit,
}));
}
return yield call(modifyRoute, { address: _id, id, token, title, is_public });
}
export function* userSaga() {

View file

@ -197,11 +197,11 @@
&.is_menu_target {
.route-row {
transform: translateX(-100px);
transform: translateX(-120px);
}
.route-row-edit-menu {
width: 100px;
width: 120px;
}
}
}
@ -221,8 +221,11 @@
.route-row-view {
overflow: hidden;
transition: height 500ms;
padding-right: 32px;
position: relative;
&.has_menu {
padding-right: 32px;
}
}
.route-row-edit {
@ -295,15 +298,25 @@
fill: fade(white, 30%);
div {
width: 50px;
width: 60px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
&:first-child {
box-shadow: fade(black, 30%) 1px 0;
}
&:hover {
background: fade(@red_secondary, 30%);
}
&.modify-button {
&:hover {
background: fade(@green_secondary, 30%);
}
}
}
}

View file

@ -103,7 +103,7 @@ export const checkOSRMService = (bounds: LatLngLiteral[]): Promise<boolean> => (
);
export const dropRoute = ({ address, id, token }: { address: string, id: string, token: string }): AxiosPromise<any> => (
axios.delete(API.DROP_ROUTE, { data: { address: '1123123123123', id, token } })
axios.delete(API.DROP_ROUTE, { data: { address, id, token } })
);
export const modifyRoute = (