mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
complete item editing
This commit is contained in:
parent
7513f79b93
commit
0cbbc0ce8a
12 changed files with 94 additions and 34 deletions
|
@ -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' },
|
||||
|
|
|
@ -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 });
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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' });
|
||||
|
|
|
@ -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' });
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 = (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue