mirror of
https://github.com/haiwen/seahub.git
synced 2025-04-28 03:10:45 +00:00
upgrade react-dnd react-dnd-html5-backend
This commit is contained in:
parent
b43ad4132b
commit
bba5014f6d
132
frontend/package-lock.json
generated
132
frontend/package-lock.json
generated
@ -46,8 +46,8 @@
|
||||
"react-app-polyfill": "^2.0.0",
|
||||
"react-chartjs-2": "5.3.0",
|
||||
"react-cookies": "^0.1.0",
|
||||
"react-dnd": "^2.6.0",
|
||||
"react-dnd-html5-backend": "^2.6.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-i18next": "^10.12.2",
|
||||
"react-mentions": "4.4.10",
|
||||
@ -3106,19 +3106,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/react/node_modules/hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"dependencies": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/react/node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/@emotion/serialize": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
|
||||
@ -5391,6 +5378,21 @@
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
|
||||
"integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
|
||||
},
|
||||
"node_modules/@react-dnd/asap": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
|
||||
"integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
|
||||
},
|
||||
"node_modules/@react-dnd/invariant": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
|
||||
"integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
|
||||
},
|
||||
"node_modules/@react-dnd/shallowequal": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
|
||||
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
|
||||
},
|
||||
"node_modules/@replit/codemirror-lang-csharp": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/@replit/codemirror-lang-csharp/-/codemirror-lang-csharp-6.2.0.tgz",
|
||||
@ -11612,12 +11614,6 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/disposables": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/disposables/-/disposables-1.0.2.tgz",
|
||||
"integrity": "sha512-q1XTvs/XGdfubRSemB2+QRhJjIX4PerKkSom+i8Nkw3hCv6xISNrgaN442n2BunyBI4x77Om4ZAzSlqmhM9pwA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz",
|
||||
@ -11626,15 +11622,13 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dnd-core": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/dnd-core/-/dnd-core-2.6.0.tgz",
|
||||
"integrity": "sha512-5BfQHIp0XVd4ioF0q4GyUeHQQNCbqP+0SnUiP9TssoQ50wrP1NgSzDqZkjD5pFngsVz9txGin6rvTQD7w0qC3w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
|
||||
"integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
|
||||
"dependencies": {
|
||||
"asap": "^2.0.6",
|
||||
"invariant": "^2.0.0",
|
||||
"lodash": "^4.2.0",
|
||||
"redux": "^3.7.1"
|
||||
"@react-dnd/asap": "^5.0.1",
|
||||
"@react-dnd/invariant": "^4.0.1",
|
||||
"redux": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dns-packet": {
|
||||
@ -13510,7 +13504,6 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
@ -15283,10 +15276,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hoist-non-react-statics": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
|
||||
"integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==",
|
||||
"license": "BSD-3-Clause"
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"dependencies": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hoist-non-react-statics/node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/hoopy": {
|
||||
"version": "0.1.4",
|
||||
@ -24069,29 +24069,40 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-dnd": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/react-dnd/-/react-dnd-2.6.0.tgz",
|
||||
"integrity": "sha512-2KHNpeg2SyaxXYq+xO1TM+tOtN9hViI41otJuiYiu6DRYGw+WMvDFDMP4aw7zIKRRm1xd0gizXuKWhb8iJYHBw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
|
||||
"integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
|
||||
"dependencies": {
|
||||
"disposables": "^1.0.1",
|
||||
"dnd-core": "^2.6.0",
|
||||
"hoist-non-react-statics": "^2.1.0",
|
||||
"invariant": "^2.1.0",
|
||||
"lodash": "^4.2.0",
|
||||
"prop-types": "^15.5.10"
|
||||
"@react-dnd/invariant": "^4.0.1",
|
||||
"@react-dnd/shallowequal": "^4.0.1",
|
||||
"dnd-core": "^16.0.1",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"hoist-non-react-statics": "^3.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
"@types/hoist-non-react-statics": ">= 3.3.1",
|
||||
"@types/node": ">= 12",
|
||||
"@types/react": ">= 16",
|
||||
"react": ">= 16.14"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/hoist-non-react-statics": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-dnd-html5-backend": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/react-dnd-html5-backend/-/react-dnd-html5-backend-2.6.0.tgz",
|
||||
"integrity": "sha512-8gOfBfqFikWmXvAGSZz1mgoctwkcsKdUC9POt/WGnMoZwGB4ivB0Ex5D6pwHTNjvAs0ixqqWdJKy57CzjDg5Sg==",
|
||||
"license": "BSD-3-Clause",
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
|
||||
"integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
|
||||
"dependencies": {
|
||||
"lodash": "^4.2.0"
|
||||
"dnd-core": "^16.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
@ -24436,15 +24447,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/redux": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/redux/-/redux-3.7.2.tgz",
|
||||
"integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==",
|
||||
"license": "MIT",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||
"dependencies": {
|
||||
"lodash": "^4.2.1",
|
||||
"lodash-es": "^4.2.1",
|
||||
"loose-envify": "^1.1.0",
|
||||
"symbol-observable": "^1.0.3"
|
||||
"@babel/runtime": "^7.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
@ -28510,15 +28517,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||
|
@ -41,8 +41,8 @@
|
||||
"react-app-polyfill": "^2.0.0",
|
||||
"react-chartjs-2": "5.3.0",
|
||||
"react-cookies": "^0.1.0",
|
||||
"react-dnd": "^2.6.0",
|
||||
"react-dnd-html5-backend": "^2.6.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-i18next": "^10.12.2",
|
||||
"react-mentions": "4.4.10",
|
||||
|
@ -3,6 +3,8 @@ import { createRoot } from 'react-dom/client';
|
||||
import { Router, navigate, LocationProvider, globalHistory } from '@gatsbyjs/reach-router';
|
||||
import MediaQuery from 'react-responsive';
|
||||
import { Modal } from 'reactstrap';
|
||||
import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import { siteRoot, siteTitle, mediaUrl, faviconPath } from './utils/constants';
|
||||
import { Utils, isMobile } from './utils/utils';
|
||||
import SystemNotification from './components/system-notification';
|
||||
@ -315,44 +317,46 @@ class App extends Component {
|
||||
/>
|
||||
}
|
||||
<div className="main-panel" style={mainPanelStyle}>
|
||||
<Router className="reach-router">
|
||||
<Libraries path={siteRoot} />
|
||||
<Libraries path={siteRoot + 'libraries'} />
|
||||
<MyLibraries path={siteRoot + 'my-libs'} />
|
||||
<MyLibDeleted path={siteRoot + 'my-libs/deleted/'} />
|
||||
<ShareAdminShareLinks path={siteRoot + 'share-admin-share-links'} />
|
||||
<ShareAdminUploadLinks path={siteRoot + 'share-admin-upload-links'} />
|
||||
<SharedWithAll path={siteRoot + 'org/'} />
|
||||
<Wikis
|
||||
path={siteRoot + 'published'}
|
||||
sidePanelRate={sidePanelRate}
|
||||
isSidePanelFolded={isSidePanelFolded}
|
||||
/>
|
||||
<Starred path={siteRoot + 'starred'} />
|
||||
<InvitationsView path={siteRoot + 'invitations/'} />
|
||||
<FilesActivities path={siteRoot + 'dashboard'} />
|
||||
<MyFileActivities path={siteRoot + 'my-activities'} />
|
||||
<GroupView path={siteRoot + 'group/:groupID'} />
|
||||
<LinkedDevices path={siteRoot + 'linked-devices'} />
|
||||
<ShareAdminLibraries path={siteRoot + 'share-admin-libs'} />
|
||||
<ShareAdminFolders path={siteRoot + 'share-admin-folders'} />
|
||||
<SharedLibraries path={siteRoot + 'shared-libs'} />
|
||||
<ShareWithOCM path={siteRoot + 'shared-with-ocm'} />
|
||||
<OCMViaWebdav path={siteRoot + 'ocm-via-webdav'} />
|
||||
<OCMRepoDir
|
||||
path={siteRoot + 'remote-library/:providerID/:repoID/*'}
|
||||
pathPrefix={this.state.pathPrefix}
|
||||
onTabNavClick={this.tabItemClick}
|
||||
/>
|
||||
<LibContentView
|
||||
path={siteRoot + 'library/:repoID/*'}
|
||||
pathPrefix={this.state.pathPrefix}
|
||||
isSidePanelFolded={isSidePanelFolded}
|
||||
onTabNavClick={this.tabItemClick}
|
||||
eventBus={this.eventBus}
|
||||
resetTitle={this.resetTitle}
|
||||
/>
|
||||
</Router>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Router className="reach-router">
|
||||
<Libraries path={siteRoot} />
|
||||
<Libraries path={siteRoot + 'libraries'} />
|
||||
<MyLibraries path={siteRoot + 'my-libs'} />
|
||||
<MyLibDeleted path={siteRoot + 'my-libs/deleted/'} />
|
||||
<ShareAdminShareLinks path={siteRoot + 'share-admin-share-links'} />
|
||||
<ShareAdminUploadLinks path={siteRoot + 'share-admin-upload-links'} />
|
||||
<SharedWithAll path={siteRoot + 'org/'} />
|
||||
<Wikis
|
||||
path={siteRoot + 'published'}
|
||||
sidePanelRate={sidePanelRate}
|
||||
isSidePanelFolded={isSidePanelFolded}
|
||||
/>
|
||||
<Starred path={siteRoot + 'starred'} />
|
||||
<InvitationsView path={siteRoot + 'invitations/'} />
|
||||
<FilesActivities path={siteRoot + 'dashboard'} />
|
||||
<MyFileActivities path={siteRoot + 'my-activities'} />
|
||||
<GroupView path={siteRoot + 'group/:groupID'} />
|
||||
<LinkedDevices path={siteRoot + 'linked-devices'} />
|
||||
<ShareAdminLibraries path={siteRoot + 'share-admin-libs'} />
|
||||
<ShareAdminFolders path={siteRoot + 'share-admin-folders'} />
|
||||
<SharedLibraries path={siteRoot + 'shared-libs'} />
|
||||
<ShareWithOCM path={siteRoot + 'shared-with-ocm'} />
|
||||
<OCMViaWebdav path={siteRoot + 'ocm-via-webdav'} />
|
||||
<OCMRepoDir
|
||||
path={siteRoot + 'remote-library/:providerID/:repoID/*'}
|
||||
pathPrefix={this.state.pathPrefix}
|
||||
onTabNavClick={this.tabItemClick}
|
||||
/>
|
||||
<LibContentView
|
||||
path={siteRoot + 'library/:repoID/*'}
|
||||
pathPrefix={this.state.pathPrefix}
|
||||
isSidePanelFolded={isSidePanelFolded}
|
||||
onTabNavClick={this.tabItemClick}
|
||||
eventBus={this.eventBus}
|
||||
resetTitle={this.resetTitle}
|
||||
/>
|
||||
</Router>
|
||||
</DndProvider>
|
||||
</div>
|
||||
<MediaQuery query="(max-width: 767.8px)">
|
||||
<Modal zIndex="1030" isOpen={!isSidePanelClosed} toggle={this.toggleSidePanel} contentClassName="d-none"></Modal>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Fragment, useCallback, useMemo } from 'react';
|
||||
import React, { Fragment, useCallback, useMemo, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { DragSource, DropTarget } from 'react-dnd';
|
||||
import { useDrag, useDrop } from 'react-dnd';
|
||||
import CustomizeSelect from '../../../../../components/customize-select';
|
||||
import Icon from '../../../../../components/icon';
|
||||
import { gettext } from '../../../../../utils/constants';
|
||||
@ -9,49 +9,6 @@ import { getColumnByKey } from '../../../../utils/column';
|
||||
import { COLUMNS_ICON_CONFIG, SORT_TYPE, SORT_COLUMN_OPTIONS } from '../../../../constants';
|
||||
import { getGroupbyGranularityByColumn, isShowGroupCountType, getSelectedCountType, getDefaultCountType } from '../../../../utils/group';
|
||||
|
||||
const dragSource = {
|
||||
beginDrag: props => {
|
||||
return { idx: props.index, data: props.groupby, mode: 'sfMetadataGroupbyItem' };
|
||||
},
|
||||
endDrag(props, monitor) {
|
||||
const groupSource = monitor.getItem();
|
||||
const didDrop = monitor.didDrop();
|
||||
let groupTarget = {};
|
||||
if (!didDrop) {
|
||||
return { groupSource, groupTarget };
|
||||
}
|
||||
},
|
||||
isDragging(props) {
|
||||
const { index, dragged } = props;
|
||||
const { idx } = dragged;
|
||||
return idx > index;
|
||||
}
|
||||
};
|
||||
|
||||
const dropTarget = {
|
||||
drop(props, monitor) {
|
||||
const groupSource = monitor.getItem();
|
||||
const { index: targetIdx } = props;
|
||||
if (targetIdx !== groupSource.idx) {
|
||||
let groupTarget = { idx: targetIdx, data: props.groupby };
|
||||
props.onMove(groupSource, groupTarget);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const dragCollect = (connect, monitor) => ({
|
||||
connectDragSource: connect.dragSource(),
|
||||
connectDragPreview: connect.dragPreview(),
|
||||
isDragging: monitor.isDragging(),
|
||||
});
|
||||
|
||||
const dropCollect = (connect, monitor) => ({
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
isOver: monitor.isOver(),
|
||||
canDrop: monitor.canDrop(),
|
||||
dragged: monitor.getItem(),
|
||||
});
|
||||
|
||||
/*
|
||||
groupby: {
|
||||
column_key: 'xxx',
|
||||
@ -59,10 +16,39 @@ const dropCollect = (connect, monitor) => ({
|
||||
sort_type: 'xxx',
|
||||
}
|
||||
*/
|
||||
const GroupbyItem = ({
|
||||
isOver, isDragging, canDrop, connectDragSource, connectDragPreview, connectDropTarget,
|
||||
showDragBtn, index, readOnly, groupby, columns, onDelete, onUpdate
|
||||
}) => {
|
||||
const GroupbyItem = ({ showDragBtn, index, readOnly, groupby, columns, onDelete, onUpdate, onMove }) => {
|
||||
const ref = useRef(null);
|
||||
|
||||
// drag and drop
|
||||
const [{ isDragging }, drag] = useDrag({
|
||||
type: 'sfMetadataGroupbyItem',
|
||||
item: () => ({
|
||||
idx: index,
|
||||
data: groupby,
|
||||
}),
|
||||
collect: (monitor) => ({
|
||||
isDragging: monitor.isDragging(),
|
||||
}),
|
||||
});
|
||||
|
||||
const [{ isOver, canDrop }, drop] = useDrop({
|
||||
accept: 'sfMetadataGroupbyItem',
|
||||
hover: (item) => {
|
||||
if (item.idx !== index) {
|
||||
onMove(
|
||||
{ idx: item.idx, data: item.data },
|
||||
{ idx: index, data: groupby }
|
||||
);
|
||||
item.idx = index;
|
||||
}
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isOver: monitor.isOver(),
|
||||
canDrop: monitor.canDrop(),
|
||||
})
|
||||
});
|
||||
const dragDropRef = drag(drop(ref));
|
||||
|
||||
const column = useMemo(() => {
|
||||
return getColumnByKey(columns, groupby.column_key);
|
||||
}, [groupby, columns]);
|
||||
@ -165,59 +151,58 @@ const GroupbyItem = ({
|
||||
onUpdate(newGroupby, index);
|
||||
}, [groupby, index, onUpdate]);
|
||||
|
||||
return connectDropTarget(
|
||||
connectDragPreview(
|
||||
<div
|
||||
className={classnames('groupby-item',
|
||||
{ 'group-can-drop-top': isOver && canDrop && isDragging },
|
||||
{ 'group-can-drop': isOver && canDrop && !isDragging }
|
||||
)}
|
||||
>
|
||||
{!readOnly && (
|
||||
<div className="delete-groupby" onClick={deleteGroupby} aria-label={gettext('Delete')}>
|
||||
<Icon className="sf-metadata-icon" symbol="fork-number"/>
|
||||
</div>
|
||||
)}
|
||||
<div className="condition">
|
||||
<div className="groupby-column">
|
||||
return (
|
||||
<div
|
||||
ref={dragDropRef}
|
||||
className={classnames('groupby-item',
|
||||
{ 'group-can-drop-top': isOver && canDrop && isDragging },
|
||||
{ 'group-can-drop': isOver && canDrop && !isDragging }
|
||||
)}
|
||||
>
|
||||
{!readOnly && (
|
||||
<div className="delete-groupby" onClick={deleteGroupby} aria-label={gettext('Delete')}>
|
||||
<Icon className="sf-metadata-icon" symbol="fork-number"/>
|
||||
</div>
|
||||
)}
|
||||
<div className="condition">
|
||||
<div className="groupby-column">
|
||||
<CustomizeSelect
|
||||
readOnly={readOnly}
|
||||
value={selectedColumn}
|
||||
options={columnsOptions}
|
||||
onSelectOption={selectColumn}
|
||||
searchable={true}
|
||||
searchPlaceholder={gettext('Search property')}
|
||||
noOptionsPlaceholder={gettext('No results')}
|
||||
/>
|
||||
</div>
|
||||
{isShowGroupCountType(column) && (
|
||||
<div className="groupby-count-type">
|
||||
<CustomizeSelect
|
||||
readOnly={readOnly}
|
||||
value={selectedColumn}
|
||||
options={columnsOptions}
|
||||
onSelectOption={selectColumn}
|
||||
searchable={true}
|
||||
searchPlaceholder={gettext('Search property')}
|
||||
noOptionsPlaceholder={gettext('No results')}
|
||||
value={selectedCountType}
|
||||
onSelectOption={selectCountType}
|
||||
options={countTypeOptions}
|
||||
/>
|
||||
</div>
|
||||
{isShowGroupCountType(column) && (
|
||||
<div className="groupby-count-type">
|
||||
<CustomizeSelect
|
||||
readOnly={readOnly}
|
||||
value={selectedCountType}
|
||||
onSelectOption={selectCountType}
|
||||
options={countTypeOptions}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="groupby-predicate">
|
||||
{(!column.key || SORT_COLUMN_OPTIONS.includes(column.type)) && (
|
||||
<CustomizeSelect
|
||||
readOnly={readOnly}
|
||||
value={selectedSortType}
|
||||
options={sortOptions}
|
||||
onSelectOption={selectSortType}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{!readOnly && showDragBtn && connectDragSource(
|
||||
<div className="groupby-drag">
|
||||
<Icon symbol="drag" />
|
||||
</div>
|
||||
)}
|
||||
<div className="groupby-predicate">
|
||||
{(!column.key || SORT_COLUMN_OPTIONS.includes(column.type)) && (
|
||||
<CustomizeSelect
|
||||
readOnly={readOnly}
|
||||
value={selectedSortType}
|
||||
options={sortOptions}
|
||||
onSelectOption={selectSortType}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
{!readOnly && showDragBtn && (
|
||||
<div className="groupby-drag">
|
||||
<Icon symbol="drag" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
};
|
||||
@ -229,16 +214,7 @@ GroupbyItem.propTypes = {
|
||||
columns: PropTypes.array,
|
||||
onDelete: PropTypes.func,
|
||||
onUpdate: PropTypes.func,
|
||||
|
||||
// drag
|
||||
isDragging: PropTypes.bool,
|
||||
isOver: PropTypes.bool,
|
||||
canDrop: PropTypes.bool,
|
||||
connectDropTarget: PropTypes.func,
|
||||
connectDragSource: PropTypes.func,
|
||||
connectDragPreview: PropTypes.func,
|
||||
onMove: PropTypes.func,
|
||||
};
|
||||
|
||||
export default DropTarget('sfMetadataGroupbyItem', dropTarget, dropCollect)(
|
||||
DragSource('sfMetadataGroupbyItem', dragSource, dragCollect)(GroupbyItem)
|
||||
);
|
||||
export default GroupbyItem;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { DropTarget } from 'react-dnd';
|
||||
import html5DragDropContext from '../../../../../pages/wiki2/wiki-nav/html5DragDropContext';
|
||||
import { useDrop } from 'react-dnd';
|
||||
import GroupbyItem from './groupby-item';
|
||||
import { gettext } from '../../../../../utils/constants';
|
||||
|
||||
@ -17,8 +16,20 @@ const Groupbys = ({ readOnly, groupbys, columns, onDelete, onUpdate, onMove }) =
|
||||
return groupbys.length > 1;
|
||||
}, [readOnly, groupbys]);
|
||||
|
||||
const [, drop] = useDrop({
|
||||
accept: 'sfMetadataGroupbyItem',
|
||||
drop: (item, monitor) => {
|
||||
if (!monitor.didDrop()) {
|
||||
onMove(item, { idx: groupbys.length });
|
||||
}
|
||||
},
|
||||
collect: monitor => ({
|
||||
isOver: monitor.isOver(),
|
||||
}),
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={classnames('groupbys-list', { 'empty-groupbys-container': isEmpty })}>
|
||||
<div ref={drop} className={classnames('groupbys-list', { 'empty-groupbys-container': isEmpty })}>
|
||||
{isEmpty && <div className="empty-groupbys-list">{gettext('No groupings applied to this view.')}</div>}
|
||||
{!isEmpty && groupbys.map((groupby, index) => {
|
||||
return (
|
||||
@ -47,8 +58,4 @@ Groupbys.propTypes = {
|
||||
onMove: PropTypes.func,
|
||||
};
|
||||
|
||||
const DndGroupbysContainer = DropTarget('sfMetadataGroupbyItem', {}, connect => ({
|
||||
connectDropTarget: connect.dropTarget()
|
||||
}))(Groupbys);
|
||||
|
||||
export default html5DragDropContext(DndGroupbysContainer);
|
||||
export default Groupbys;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DragSource, DropTarget } from 'react-dnd';
|
||||
import { useDrag, useDrop } from 'react-dnd';
|
||||
import classnames from 'classnames';
|
||||
import Icon from '../../../../../components/icon';
|
||||
import IconBtn from '../../../../../components/icon-btn';
|
||||
@ -9,56 +9,73 @@ import Name from './name';
|
||||
|
||||
import './index.css';
|
||||
|
||||
const dragSource = {
|
||||
beginDrag: props => {
|
||||
return { idx: props.index, data: props.option, mode: 'sfMetadataSingleSelectOption' };
|
||||
},
|
||||
endDrag(props, monitor) {
|
||||
const optionSource = monitor.getItem();
|
||||
const didDrop = monitor.didDrop();
|
||||
let optionTarget = {};
|
||||
if (!didDrop) {
|
||||
return { optionSource, optionTarget };
|
||||
}
|
||||
},
|
||||
isDragging(props, monitor) {
|
||||
const { index, dragged } = props;
|
||||
const { idx } = dragged;
|
||||
return idx > index;
|
||||
}
|
||||
};
|
||||
// const dragSource = {
|
||||
// beginDrag: props => {
|
||||
// return { idx: props.index, data: props.option, mode: 'sfMetadataSingleSelectOption' };
|
||||
// },
|
||||
// endDrag(props, monitor) {
|
||||
// const optionSource = monitor.getItem();
|
||||
// const didDrop = monitor.didDrop();
|
||||
// let optionTarget = {};
|
||||
// if (!didDrop) {
|
||||
// return { optionSource, optionTarget };
|
||||
// }
|
||||
// },
|
||||
// isDragging(props, monitor) {
|
||||
// const { index, dragged } = props;
|
||||
// const { idx } = dragged;
|
||||
// return idx > index;
|
||||
// }
|
||||
// };
|
||||
|
||||
const dragCollect = (connect, monitor) => ({
|
||||
connectDragSource: connect.dragSource(),
|
||||
connectDragPreview: connect.dragPreview(),
|
||||
isDragging: monitor.isDragging()
|
||||
});
|
||||
// const dragCollect = (connect, monitor) => ({
|
||||
// connectDragSource: connect.dragSource(),
|
||||
// connectDragPreview: connect.dragPreview(),
|
||||
// isDragging: monitor.isDragging()
|
||||
// });
|
||||
|
||||
const dropTarget = {
|
||||
drop(props, monitor) {
|
||||
const optionSource = monitor.getItem();
|
||||
const { index: targetIdx } = props;
|
||||
if (targetIdx !== optionSource.idx) {
|
||||
const optionTarget = { idx: targetIdx, data: props.option };
|
||||
props.onMove(optionSource, optionTarget);
|
||||
}
|
||||
}
|
||||
};
|
||||
// const dropTarget = {
|
||||
// drop(props, monitor) {
|
||||
// const optionSource = monitor.getItem();
|
||||
// const { index: targetIdx } = props;
|
||||
// if (targetIdx !== optionSource.idx) {
|
||||
// const optionTarget = { idx: targetIdx, data: props.option };
|
||||
// props.onMove(optionSource, optionTarget);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
const dropCollect = (connect, monitor) => ({
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
isOver: monitor.isOver(),
|
||||
canDrop: monitor.canDrop(),
|
||||
dragged: monitor.getItem()
|
||||
});
|
||||
// const dropCollect = (connect, monitor) => ({
|
||||
// connectDropTarget: connect.dropTarget(),
|
||||
// isOver: monitor.isOver(),
|
||||
// canDrop: monitor.canDrop(),
|
||||
// dragged: monitor.getItem()
|
||||
// });
|
||||
|
||||
const Option = ({
|
||||
isOver, isDragging, canDrop, connectDragSource, connectDragPreview, connectDropTarget,
|
||||
isViewing, isDeleting, isEditing, isPredefined,
|
||||
option,
|
||||
onDelete: propsDelete, onUpdate,
|
||||
onMouseLeave, onMouseEnter: propsMouseEnter, onToggleFreeze, onOpenNameEditor, onCloseNameEditor,
|
||||
}) => {
|
||||
const [{ isDragging }, drag] = useDrag({
|
||||
type: 'sfMetadataSingleSelectOption',
|
||||
item: () => ({
|
||||
idx: option.id,
|
||||
data: option,
|
||||
}),
|
||||
collect: (monitor) => ({
|
||||
isDragging: monitor.isDragging(),
|
||||
}),
|
||||
});
|
||||
|
||||
const [{ isOver, canDrop }, drop] = useDrop({
|
||||
accept: 'sfMetadataSingleSelectOption',
|
||||
collect: (monitor) => ({
|
||||
isOver: monitor.isOver(),
|
||||
canDrop: monitor.canDrop(),
|
||||
})
|
||||
});
|
||||
|
||||
const onDelete = useCallback((event) => {
|
||||
event.nativeEvent.stopImmediatePropagation();
|
||||
@ -69,44 +86,41 @@ const Option = ({
|
||||
propsMouseEnter(option.id);
|
||||
}, [option, propsMouseEnter]);
|
||||
|
||||
return connectDropTarget(
|
||||
connectDragPreview(
|
||||
<div
|
||||
className={classnames('sf-metadata-edit-option-container', {
|
||||
'sf-metadata-edit-option-can-drop': isOver && canDrop && !isDragging,
|
||||
'sf-metadata-edit-deleting-option': isDeleting,
|
||||
'sf-metadata-edit-option-can-drop-top': isOver && canDrop && isDragging,
|
||||
'sf-metadata-edit-option-viewing': isViewing,
|
||||
'sf-metadata-edit-option-editing': isEditing,
|
||||
'sf-metadata-edit-option-disabled': isPredefined,
|
||||
})}
|
||||
onMouseEnter={() => onMouseEnter()}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
{connectDragSource(
|
||||
<div className="sf-metadata-edit-option-drag-container">
|
||||
<Icon symbol="drag" />
|
||||
</div>
|
||||
)}
|
||||
<div className="sf-metadata-edit-option-content">
|
||||
<Color option={option} onChange={onUpdate} isViewing={isViewing} isPredefined={isPredefined} />
|
||||
<Name
|
||||
option={option}
|
||||
isPredefined={isPredefined}
|
||||
isEditing={isEditing}
|
||||
onChange={onUpdate}
|
||||
onToggleFreeze={onToggleFreeze}
|
||||
onOpen={onOpenNameEditor}
|
||||
onClose={onCloseNameEditor}
|
||||
/>
|
||||
</div>
|
||||
<div id={`sf-metadata-edit-option-more-operation-${option.id}`} className="sf-metadata-edit-option-more-operations">
|
||||
{(isViewing || isDeleting) && (
|
||||
<IconBtn className="sf-metadata-edit-option-operation-item" onClick={onDelete} symbol="delete" />
|
||||
)}
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
ref={(node) => drag(drop(node))}
|
||||
className={classnames('sf-metadata-edit-option-container', {
|
||||
'sf-metadata-edit-option-can-drop': isOver && canDrop && !isDragging,
|
||||
'sf-metadata-edit-deleting-option': isDeleting,
|
||||
'sf-metadata-edit-option-can-drop-top': isOver && canDrop && isDragging,
|
||||
'sf-metadata-edit-option-viewing': isViewing,
|
||||
'sf-metadata-edit-option-editing': isEditing,
|
||||
'sf-metadata-edit-option-disabled': isPredefined,
|
||||
})}
|
||||
onMouseEnter={() => onMouseEnter()}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
<div className="sf-metadata-edit-option-drag-container">
|
||||
<Icon symbol="drag" />
|
||||
</div>
|
||||
)
|
||||
<div className="sf-metadata-edit-option-content">
|
||||
<Color option={option} onChange={onUpdate} isViewing={isViewing} isPredefined={isPredefined} />
|
||||
<Name
|
||||
option={option}
|
||||
isPredefined={isPredefined}
|
||||
isEditing={isEditing}
|
||||
onChange={onUpdate}
|
||||
onToggleFreeze={onToggleFreeze}
|
||||
onOpen={onOpenNameEditor}
|
||||
onClose={onCloseNameEditor}
|
||||
/>
|
||||
</div>
|
||||
<div id={`sf-metadata-edit-option-more-operation-${option.id}`} className="sf-metadata-edit-option-more-operations">
|
||||
{(isViewing || isDeleting) && (
|
||||
<IconBtn className="sf-metadata-edit-option-operation-item" onClick={onDelete} symbol="delete" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -127,15 +141,13 @@ Option.propTypes = {
|
||||
onOpenNameEditor: PropTypes.func.isRequired,
|
||||
onCloseNameEditor: PropTypes.func.isRequired,
|
||||
|
||||
// drag
|
||||
isOver: PropTypes.bool,
|
||||
canDrop: PropTypes.bool,
|
||||
dragged: PropTypes.object,
|
||||
connectDragSource: PropTypes.func.isRequired,
|
||||
connectDropTarget: PropTypes.func.isRequired,
|
||||
connectDragPreview: PropTypes.func.isRequired,
|
||||
// // drag
|
||||
// isOver: PropTypes.bool,
|
||||
// canDrop: PropTypes.bool,
|
||||
// dragged: PropTypes.object,
|
||||
// connectDragSource: PropTypes.func.isRequired,
|
||||
// connectDropTarget: PropTypes.func.isRequired,
|
||||
// connectDragPreview: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default DropTarget('sfMetadataSingleSelectOption', dropTarget, dropCollect)(
|
||||
DragSource('sfMetadataSingleSelectOption', dragSource, dragCollect)(Option)
|
||||
);
|
||||
export default Option;
|
||||
|
@ -1,7 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DropTarget } from 'react-dnd';
|
||||
import html5DragDropContext from '../../../../pages/wiki2/wiki-nav/html5DragDropContext';
|
||||
|
||||
const OptionsContainer = ({ inputRef, options }) => {
|
||||
if (!Array.isArray(options) || options.length === 0) return null;
|
||||
@ -17,8 +15,4 @@ OptionsContainer.propTypes = {
|
||||
options: PropTypes.array
|
||||
};
|
||||
|
||||
const DndOptionsContainer = DropTarget('sfMetadataSingleSelectOption', {}, connect => ({
|
||||
connectDropTarget: connect.dropTarget()
|
||||
}))(OptionsContainer);
|
||||
|
||||
export default html5DragDropContext(DndOptionsContainer);
|
||||
export default OptionsContainer;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DragDropContext } from 'react-dnd';
|
||||
import HTML5Backend from 'react-dnd-html5-backend';
|
||||
// import { DragDropContext } from 'react-dnd';
|
||||
// import HTML5Backend from 'react-dnd-html5-backend';
|
||||
|
||||
export default DragDropContext(HTML5Backend);
|
||||
// export default DragDropContext(HTML5Backend);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DragSource, DropTarget } from 'react-dnd';
|
||||
import { useDrag, useDrop } from 'react-dnd';
|
||||
import PageItem from './page-item';
|
||||
import wikiAPI from '../../../../utils/wiki-api';
|
||||
import { wikiId, gettext } from '../../../../utils/constants';
|
||||
@ -77,6 +77,4 @@ const dropCollect = (connect, monitor) => ({
|
||||
draggedPage: monitor.getItem()
|
||||
});
|
||||
|
||||
export default DropTarget('WikiNav', dropTarget, dropCollect)(
|
||||
DragSource('WikiNav', dragSource, dragCollect)(PageItem)
|
||||
);
|
||||
export default PageItem;
|
||||
|
@ -2,8 +2,7 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { UncontrolledTooltip } from 'reactstrap';
|
||||
import { DropTarget, DragLayer } from 'react-dnd';
|
||||
import html5DragDropContext from './html5DragDropContext';
|
||||
import { useDragLayer, useDrop } from 'react-dnd';
|
||||
import DraggedPageItem from './pages/dragged-page-item';
|
||||
import { gettext, wikiPermission } from '../../../utils/constants';
|
||||
import { Utils } from '../../../utils/utils';
|
||||
@ -158,14 +157,14 @@ class WikiNav extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const StructureBody = html5DragDropContext(
|
||||
DropTarget('WikiNav', {}, connect => ({
|
||||
connectDropTarget: connect.dropTarget()
|
||||
}))(DragLayer(this.collect)(this.renderStructureBody))
|
||||
);
|
||||
// const StructureBody = html5DragDropContext(
|
||||
// DropTarget('WikiNav', {}, connect => ({
|
||||
// connectDropTarget: connect.dropTarget()
|
||||
// }))(DragLayer(this.collect)(this.renderStructureBody))
|
||||
// );
|
||||
return (
|
||||
<div className='wiki-nav'>
|
||||
<StructureBody />
|
||||
{this.renderStructureBody()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user