@sanity/orderable-document-list 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/lib/Document.js +2 -42
- package/lib/Document.js.map +1 -1
- package/lib/DocumentListQuery.js +6 -5
- package/lib/DocumentListQuery.js.map +1 -1
- package/lib/DraggableList.js +53 -34
- package/lib/DraggableList.js.map +1 -1
- package/lib/helpers/reorderDocuments.js +2 -24
- package/lib/helpers/reorderDocuments.js.map +1 -1
- package/package.json +1 -1
- package/src/Document.js +2 -48
- package/src/DocumentListQuery.js +8 -3
- package/src/DraggableList.js +40 -38
- package/src/helpers/reorderDocuments.js +0 -12
package/README.md
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Drag-and-drop Document Ordering without leaving the Editing surface.
|
|
4
4
|
|
|
5
|
-
 (including a bug that is now fixed 😅)
|
|
5
|
+

|
|
8
6
|
|
|
9
7
|
This plugin aims to be OS-like in that you can select and move multiple documents by holding `shift` and clicking a second item, and toggling on/off selections by holding `command/control`.
|
|
10
8
|
|
package/lib/Document.js
CHANGED
|
@@ -13,8 +13,6 @@ var _icons = require("@sanity/icons");
|
|
|
13
13
|
|
|
14
14
|
var _ui = require("@sanity/ui");
|
|
15
15
|
|
|
16
|
-
var _deskTool = require("@sanity/desk-tool");
|
|
17
|
-
|
|
18
16
|
var _preview = _interopRequireDefault(require("part:@sanity/base/preview"));
|
|
19
17
|
|
|
20
18
|
var _schema = _interopRequireDefault(require("part:@sanity/base/schema"));
|
|
@@ -27,8 +25,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
27
25
|
|
|
28
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
// eslint-disable-next-line no-unused-vars
|
|
32
29
|
function Document(_ref) {
|
|
33
30
|
var doc = _ref.doc,
|
|
34
31
|
increment = _ref.increment,
|
|
@@ -84,16 +81,7 @@ function Document(_ref) {
|
|
|
84
81
|
}, /*#__PURE__*/_react.default.createElement(_preview.default, {
|
|
85
82
|
value: doc,
|
|
86
83
|
type: _schema.default.get(doc._type)
|
|
87
|
-
}))))
|
|
88
|
-
paddingX: 3,
|
|
89
|
-
style: {
|
|
90
|
-
flexShrink: 0
|
|
91
|
-
}
|
|
92
|
-
}, /*#__PURE__*/_react.default.createElement(ChildEditLink, {
|
|
93
|
-
id: doc._id
|
|
94
|
-
}, /*#__PURE__*/_react.default.createElement(_ui.Text, {
|
|
95
|
-
fontSize: 4
|
|
96
|
-
}, doc._id.startsWith("drafts.") ? /*#__PURE__*/_react.default.createElement(_icons.EditIcon, null) : /*#__PURE__*/_react.default.createElement(_icons.ChevronRightIcon, null)))));
|
|
84
|
+
})))));
|
|
97
85
|
}
|
|
98
86
|
|
|
99
87
|
Document.propTypes = {
|
|
@@ -110,32 +98,4 @@ Document.propTypes = {
|
|
|
110
98
|
isFirst: _propTypes.default.bool.isRequired,
|
|
111
99
|
isLast: _propTypes.default.bool.isRequired
|
|
112
100
|
};
|
|
113
|
-
|
|
114
|
-
var ChildEditLink = _ref2 => {
|
|
115
|
-
var id = _ref2.id,
|
|
116
|
-
children = _ref2.children;
|
|
117
|
-
var router = (0, _deskTool.usePaneRouter)();
|
|
118
|
-
var ChildLink = router.ChildLink,
|
|
119
|
-
routerPanesState = router.routerPanesState; // Is this document currently being edited
|
|
120
|
-
|
|
121
|
-
var isOpen = (0, _react.useMemo)(() => routerPanesState.some(pane => {
|
|
122
|
-
var _pane$;
|
|
123
|
-
|
|
124
|
-
return ((_pane$ = pane[0]) === null || _pane$ === void 0 ? void 0 : _pane$.id) === id.replace("drafts.", "");
|
|
125
|
-
}), [id, routerPanesState]);
|
|
126
|
-
var Link = (0, _react.useCallback)(linkProps => /*#__PURE__*/_react.default.createElement(ChildLink, _extends({}, linkProps, {
|
|
127
|
-
childId: id.replace("drafts.", "")
|
|
128
|
-
})), [ChildLink, id]);
|
|
129
|
-
return /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
130
|
-
as: Link,
|
|
131
|
-
mode: isOpen ? "default" : "ghost",
|
|
132
|
-
tone: isOpen ? "primary" : "transparent",
|
|
133
|
-
padding: 2
|
|
134
|
-
}, children);
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
ChildEditLink.propTypes = {
|
|
138
|
-
id: _propTypes.default.string.isRequired,
|
|
139
|
-
children: _propTypes.default.node.isRequired
|
|
140
|
-
};
|
|
141
101
|
//# sourceMappingURL=Document.js.map
|
package/lib/Document.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Document.js"],"names":["Document","doc","increment","entities","handleSelect","index","isFirst","isLast","OrderableContext","showIncrements","flexShrink","_id","ChevronUpIcon","ChevronDownIcon","width","e","nativeEvent","schema","get","_type","
|
|
1
|
+
{"version":3,"sources":["../src/Document.js"],"names":["Document","doc","increment","entities","handleSelect","index","isFirst","isLast","OrderableContext","showIncrements","flexShrink","_id","ChevronUpIcon","ChevronDownIcon","width","e","nativeEvent","schema","get","_type","propTypes","PropTypes","shape","string","isRequired","arrayOf","func","number","bool"],"mappings":"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","sourcesContent":["import PropTypes from 'prop-types'\n// eslint-disable-next-line no-unused-vars\nimport React, {useContext} from 'react'\nimport {DragHandleIcon, ChevronUpIcon, ChevronDownIcon} from '@sanity/icons'\nimport {Text, Flex, Box, Button} from '@sanity/ui'\nimport Preview from 'part:@sanity/base/preview'\nimport schema from 'part:@sanity/base/schema'\n\nimport {OrderableContext} from './OrderableContext'\n\nexport default function Document({doc, increment, entities, handleSelect, index, isFirst, isLast}) {\n const {showIncrements} = useContext(OrderableContext)\n\n return (\n <Flex align=\"center\">\n <Box paddingX={3} style={{flexShrink: 0}}>\n <Text fontSize={4}>\n <DragHandleIcon />\n </Text>\n </Box>\n {showIncrements && (\n <Flex style={{flexShrink: 0}} align=\"center\" gap={1} paddingRight={1}>\n <Button\n padding={2}\n mode=\"ghost\"\n onClick={() => increment(index, index + -1, doc._id, entities)}\n disabled={isFirst}\n icon={ChevronUpIcon}\n />\n <Button\n padding={2}\n mode=\"ghost\"\n disabled={isLast}\n onClick={() => increment(index, index + 1, doc._id, entities)}\n icon={ChevronDownIcon}\n />\n </Flex>\n )}\n <Button\n style={{width: `100%`}}\n padding={2}\n mode=\"bleed\"\n onClick={(e) => handleSelect(doc._id, index, e.nativeEvent)}\n >\n <Flex flex={1} align=\"center\">\n <Box flex={1}>\n <Preview value={doc} type={schema.get(doc._type)} />\n </Box>\n </Flex>\n </Button>\n </Flex>\n )\n}\n\nDocument.propTypes = {\n doc: PropTypes.shape({\n _id: PropTypes.string,\n _type: PropTypes.string,\n }).isRequired,\n entities: PropTypes.arrayOf(\n PropTypes.shape({\n _id: PropTypes.string,\n }).isRequired\n ).isRequired,\n handleSelect: PropTypes.func.isRequired,\n increment: PropTypes.func.isRequired,\n index: PropTypes.number.isRequired,\n isFirst: PropTypes.bool.isRequired,\n isLast: PropTypes.bool.isRequired,\n}\n"],"file":"Document.js"}
|
package/lib/DocumentListQuery.js
CHANGED
|
@@ -55,8 +55,8 @@ function DocumentListQuery(_ref) {
|
|
|
55
55
|
|
|
56
56
|
var _useState3 = (0, _react.useState)(false),
|
|
57
57
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
listIsUpdating = _useState4[0],
|
|
59
|
+
setListIsUpdating = _useState4[1];
|
|
60
60
|
|
|
61
61
|
var _useState5 = (0, _react.useState)([]),
|
|
62
62
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
@@ -113,7 +113,7 @@ function DocumentListQuery(_ref) {
|
|
|
113
113
|
}(); // Get data but only if a document isn't being patched or we don't yet have data
|
|
114
114
|
|
|
115
115
|
|
|
116
|
-
if (!
|
|
116
|
+
if (!listIsUpdating && !data.length) {
|
|
117
117
|
prepareData();
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -143,8 +143,9 @@ function DocumentListQuery(_ref) {
|
|
|
143
143
|
padding: 1
|
|
144
144
|
}, /*#__PURE__*/_react.default.createElement(_DraggableList.default, {
|
|
145
145
|
data: data,
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
type: type,
|
|
147
|
+
listIsUpdating: listIsUpdating,
|
|
148
|
+
setListIsUpdating: setListIsUpdating
|
|
148
149
|
})));
|
|
149
150
|
}
|
|
150
151
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/DocumentListQuery.js"],"names":["client","sanityClient","withConfig","apiVersion","DocumentListQuery","type","isLoading","setIsLoading","
|
|
1
|
+
{"version":3,"sources":["../src/DocumentListQuery.js"],"names":["client","sanityClient","withConfig","apiVersion","DocumentListQuery","type","isLoading","setIsLoading","listIsUpdating","setListIsUpdating","data","setData","query","ORDER_FIELD_NAME","queryParams","order","subscription","fetchData","fetch","then","documents","filteredDocuments","reduce","acc","cur","_id","startsWith","alsoHasDraft","some","doc","prepareData","listen","subscribe","length","unsubscribe","unorderedDataCount","filter","width","height","overflow","propTypes","PropTypes","string","isRequired"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AAEA;;AACA;;AACA;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAMA,MAAM,GAAGC,gBAAaC,UAAb,CAAwB;AACrCC,EAAAA,UAAU,EAAE;AADyB,CAAxB,CAAf;;AAIe,SAASC,iBAAT,OAAmC;AAAA,MAAPC,IAAO,QAAPA,IAAO;;AAChD,kBAAkC,qBAAS,IAAT,CAAlC;AAAA;AAAA,MAAOC,SAAP;AAAA,MAAkBC,YAAlB;;AACA,mBAA4C,qBAAS,KAAT,CAA5C;AAAA;AAAA,MAAOC,cAAP;AAAA,MAAuBC,iBAAvB;;AACA,mBAAwB,qBAAS,EAAT,CAAxB;AAAA;AAAA,MAAOC,IAAP;AAAA,MAAaC,OAAb;;AAEA,wBAAU,MAAM;AACd,QAAMC,KAAK,wEACKC,2BADL,YAAX;AAGA,QAAMC,WAAW,GAAG;AAACT,MAAAA,IAAD;AAAOU,MAAAA,KAAK,EAAEF;AAAd,KAApB;AACA,QAAIG,YAAY,GAAG,IAAnB,CALc,CAOd;;AACA,QAAMC,SAAS;AAAA,oCAAG,aAAY;AAC5BjB,QAAAA,MAAM,CAACkB,KAAP,CAAaN,KAAb,EAAoBE,WAApB,EAAiCK,IAAjC,CAAuCC,SAAD,IAAe;AACnD;AACA,cAAMC,iBAAiB,GAAGD,SAAS,CAACE,MAAV,CAAiB,CAACC,GAAD,EAAMC,GAAN,KAAc;AACvD,gBAAI,CAACA,GAAG,CAACC,GAAJ,CAAQC,UAAR,WAAL,EAAoC;AAClC;AACA,kBAAMC,YAAY,GAAGP,SAAS,CAACQ,IAAV,CAAgBC,GAAD,IAASA,GAAG,CAACJ,GAAJ,sBAAsBD,GAAG,CAACC,GAA1B,CAAxB,CAArB;AAEA,qBAAOE,YAAY,GAAGJ,GAAH,GAAS,CAAC,GAAGA,GAAJ,EAASC,GAAT,CAA5B;AACD;;AAED,mBAAO,CAAC,GAAGD,GAAJ,EAASC,GAAT,CAAP;AACD,WATyB,EASvB,EATuB,CAA1B;AAWAb,UAAAA,OAAO,CAACU,iBAAD,CAAP;;AAEA,cAAIf,SAAJ,EAAe;AACbC,YAAAA,YAAY,CAAC,KAAD,CAAZ;AACD;AACF,SAlBD;AAmBD,OApBc;;AAAA,sBAATU,SAAS;AAAA;AAAA;AAAA,OAAf;;AAsBA,QAAMa,WAAW;AAAA,oCAAG,aAAY;AAC9BvB,QAAAA,YAAY,CAAC,IAAD,CAAZ;AAEA,cAAMU,SAAS,EAAf;;AAEA,YAAI,CAACD,YAAL,EAAmB;AACjBA,UAAAA,YAAY,GAAGhB,MAAM,CAAC+B,MAAP,CAAcnB,KAAd,EAAqBE,WAArB,EAAkCkB,SAAlC,CAA4C,MAAMf,SAAS,EAA3D,CAAf;AACD;AACF,OARgB;;AAAA,sBAAXa,WAAW;AAAA;AAAA;AAAA,OAAjB,CA9Bc,CAwCd;;;AACA,QAAI,CAACtB,cAAD,IAAmB,CAACE,IAAI,CAACuB,MAA7B,EAAqC;AACnCH,MAAAA,WAAW;AACZ;;AAED,WAAO;AAAA;;AAAA,8BAAMd,YAAN,kDAAM,cAAckB,WAAd,EAAN;AAAA,KAAP;AACA;AACD,GA/CD,EA+CG,CAAC7B,IAAD,CA/CH;AAiDA,MAAM8B,kBAAkB,GAAG,oBACzB,MAAOzB,IAAI,CAACuB,MAAL,GAAcvB,IAAI,CAAC0B,MAAL,CAAaP,GAAD,IAAS,CAACA,GAAG,CAAChB,2BAAD,CAAzB,EAA6CoB,MAA3D,GAAoE,CADlD,EAEzB,CAACvB,IAAD,CAFyB,CAA3B;AAKA,MAAIJ,SAAJ,EACE,oBACE,6BAAC,QAAD;AAAM,IAAA,KAAK,EAAE;AAAC+B,MAAAA,KAAK,QAAN;AAAgBC,MAAAA,MAAM;AAAtB,KAAb;AAA8C,IAAA,KAAK,EAAC,QAApD;AAA6D,IAAA,OAAO,EAAC;AAArE,kBACE,6BAAC,WAAD,OADF,CADF;AAMF,sBACE,6BAAC,SAAD;AAAO,IAAA,KAAK,EAAE,CAAd;AAAiB,IAAA,KAAK,EAAE;AAACC,MAAAA,QAAQ,UAAT;AAAqBD,MAAAA,MAAM;AAA3B;AAAxB,KACGH,kBAAkB,GAAG,CAArB,iBACC,6BAAC,iBAAD,QACGA,kBADH,OACwBzB,IAAI,CAACuB,MAD7B,sCACqE,GADrE,eAEE,2DAFF,iCAFJ,eAOE,6BAAC,OAAD;AAAK,IAAA,OAAO,EAAE;AAAd,kBACE,6BAAC,sBAAD;AACE,IAAA,IAAI,EAAEvB,IADR;AAEE,IAAA,IAAI,EAAEL,IAFR;AAGE,IAAA,cAAc,EAAEG,cAHlB;AAIE,IAAA,iBAAiB,EAAEC;AAJrB,IADF,CAPF,CADF;AAkBD;;AAEDL,iBAAiB,CAACoC,SAAlB,GAA8B;AAC5BnC,EAAAA,IAAI,EAAEoC,mBAAUC,MAAV,CAAiBC;AADK,CAA9B","sourcesContent":["import PropTypes from 'prop-types'\nimport React, {useEffect, useState, useMemo} from 'react'\nimport sanityClient from 'part:@sanity/base/client'\nimport {Stack, Box, Flex, Spinner} from '@sanity/ui'\n\nimport DraggableList from './DraggableList'\nimport {ORDER_FIELD_NAME} from './helpers/constants'\nimport Feedback from './Feedback'\n\nconst client = sanityClient.withConfig({\n apiVersion: '2021-09-01',\n})\n\nexport default function DocumentListQuery({type}) {\n const [isLoading, setIsLoading] = useState(true)\n const [listIsUpdating, setListIsUpdating] = useState(false)\n const [data, setData] = useState([])\n\n useEffect(() => {\n const query = `*[_type == $type]|order(@[$order] asc){\n _id, _type, ${ORDER_FIELD_NAME}\n }`\n const queryParams = {type, order: ORDER_FIELD_NAME}\n let subscription = null\n\n // eslint-disable-next-line require-await\n const fetchData = async () => {\n client.fetch(query, queryParams).then((documents) => {\n // Remove published document from list if draft also exists\n const filteredDocuments = documents.reduce((acc, cur) => {\n if (!cur._id.startsWith(`drafts.`)) {\n // eslint-disable-next-line max-nested-callbacks\n const alsoHasDraft = documents.some((doc) => doc._id === `drafts.${cur._id}`)\n\n return alsoHasDraft ? acc : [...acc, cur]\n }\n\n return [...acc, cur]\n }, [])\n\n setData(filteredDocuments)\n\n if (isLoading) {\n setIsLoading(false)\n }\n })\n }\n\n const prepareData = async () => {\n setIsLoading(true)\n\n await fetchData()\n\n if (!subscription) {\n subscription = client.listen(query, queryParams).subscribe(() => fetchData())\n }\n }\n\n // Get data but only if a document isn't being patched or we don't yet have data\n if (!listIsUpdating && !data.length) {\n prepareData()\n }\n\n return () => subscription?.unsubscribe()\n /* eslint-disable-next-line react-hooks/exhaustive-deps */\n }, [type])\n\n const unorderedDataCount = useMemo(\n () => (data.length ? data.filter((doc) => !doc[ORDER_FIELD_NAME]).length : 0),\n [data]\n )\n\n if (isLoading)\n return (\n <Flex style={{width: `100%`, height: `100%`}} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )\n\n return (\n <Stack space={1} style={{overflow: `scroll`, height: `100%`}}>\n {unorderedDataCount > 0 && (\n <Feedback>\n {unorderedDataCount}/{data.length} Documents have no Order. Select{' '}\n <strong>Reset Order</strong> from the Menu above to fix.\n </Feedback>\n )}\n <Box padding={1}>\n <DraggableList\n data={data}\n type={type}\n listIsUpdating={listIsUpdating}\n setListIsUpdating={setListIsUpdating}\n />\n </Box>\n </Stack>\n )\n}\n\nDocumentListQuery.propTypes = {\n type: PropTypes.string.isRequired,\n}\n"],"file":"DocumentListQuery.js"}
|
package/lib/DraggableList.js
CHANGED
|
@@ -11,10 +11,12 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
11
11
|
|
|
12
12
|
var _reactBeautifulDnd = require("react-beautiful-dnd");
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _deskTool = require("@sanity/desk-tool");
|
|
15
15
|
|
|
16
16
|
var _ui = require("@sanity/ui");
|
|
17
17
|
|
|
18
|
+
var _client = _interopRequireDefault(require("part:@sanity/base/client"));
|
|
19
|
+
|
|
18
20
|
var _Document = _interopRequireDefault(require("./Document"));
|
|
19
21
|
|
|
20
22
|
var _reorderDocuments2 = require("./helpers/reorderDocuments");
|
|
@@ -62,21 +64,25 @@ var getItemStyle = (draggableStyle, itemIsUpdating) => _objectSpread({
|
|
|
62
64
|
pointerEvents: itemIsUpdating ? "none" : undefined
|
|
63
65
|
}, draggableStyle);
|
|
64
66
|
|
|
65
|
-
var cardTone =
|
|
67
|
+
var cardTone = settings => {
|
|
68
|
+
var isDuplicate = settings.isDuplicate,
|
|
69
|
+
isGhosting = settings.isGhosting,
|
|
70
|
+
isDragging = settings.isDragging,
|
|
71
|
+
isSelected = settings.isSelected;
|
|
66
72
|
if (isGhosting) return "transparent";
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
return "primary";
|
|
70
|
-
}
|
|
71
|
-
|
|
73
|
+
if (isDragging || isSelected) return "primary";
|
|
74
|
+
if (isDuplicate) return "caution";
|
|
72
75
|
return undefined;
|
|
73
76
|
};
|
|
74
77
|
|
|
75
78
|
function DraggableList(_ref) {
|
|
76
79
|
var data = _ref.data,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
type = _ref.type,
|
|
81
|
+
listIsUpdating = _ref.listIsUpdating,
|
|
82
|
+
setListIsUpdating = _ref.setListIsUpdating;
|
|
83
|
+
var toast = (0, _ui.useToast)();
|
|
84
|
+
var router = (0, _deskTool.usePaneRouter)();
|
|
85
|
+
var navigateIntent = router.navigateIntent; // Maintains local state order before transaction completes
|
|
80
86
|
|
|
81
87
|
var _useState = (0, _react.useState)(data),
|
|
82
88
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -85,7 +91,7 @@ function DraggableList(_ref) {
|
|
|
85
91
|
|
|
86
92
|
|
|
87
93
|
(0, _react.useEffect)(() => {
|
|
88
|
-
if (!
|
|
94
|
+
if (!listIsUpdating) setOrderedData(data);
|
|
89
95
|
/* eslint-disable-next-line react-hooks/exhaustive-deps */
|
|
90
96
|
}, [data]);
|
|
91
97
|
|
|
@@ -106,9 +112,15 @@ function DraggableList(_ref) {
|
|
|
106
112
|
var selectMultiple = nativeEvent.shiftKey;
|
|
107
113
|
var isUsingWindows = navigator.appVersion.indexOf('Win') !== -1;
|
|
108
114
|
var selectAdditional = isUsingWindows ? nativeEvent.ctrlKey : nativeEvent.metaKey;
|
|
109
|
-
var updatedIds = []; // No
|
|
115
|
+
var updatedIds = []; // No modifier keys pressed during click:
|
|
116
|
+
// - update selected to just this one
|
|
117
|
+
// - open document
|
|
110
118
|
|
|
111
119
|
if (!selectMultiple && !selectAdditional) {
|
|
120
|
+
navigateIntent('edit', {
|
|
121
|
+
id: clickedId,
|
|
122
|
+
type
|
|
123
|
+
});
|
|
112
124
|
return setSelectedIds([clickedId]);
|
|
113
125
|
} // Shift key was held, add id's between last selected and this one
|
|
114
126
|
// ...before adding this one
|
|
@@ -139,22 +151,15 @@ function DraggableList(_ref) {
|
|
|
139
151
|
yield transaction.commit().then(updated => {
|
|
140
152
|
clearSelected();
|
|
141
153
|
setDraggingId("");
|
|
142
|
-
|
|
154
|
+
setListIsUpdating(false);
|
|
143
155
|
toast.push({
|
|
144
156
|
title: "".concat(updated.results.length === 1 ? "1 Document" : "".concat(updated.results.length, " Documents"), " Reordered"),
|
|
145
157
|
status: "success",
|
|
146
158
|
description: message
|
|
147
|
-
});
|
|
148
|
-
// fetch(
|
|
149
|
-
// `https://i2v7h052.api.sanity.io/v2021-03-25/data/query/production?query=*%5B_type%20%3D%3D%20%22category%22%5D%7Corder(orderRank)%7B%0A%20%20title%2C%20orderRank%0A%7D`
|
|
150
|
-
// )
|
|
151
|
-
// .then((res) => res.json())
|
|
152
|
-
// .then((res) => {
|
|
153
|
-
// console.table(res.result.map((item) => item?.title).join(', '))
|
|
154
|
-
// })
|
|
159
|
+
});
|
|
155
160
|
}).catch(() => {
|
|
156
161
|
setDraggingId("");
|
|
157
|
-
|
|
162
|
+
setListIsUpdating(false);
|
|
158
163
|
toast.push({
|
|
159
164
|
title: "Reordering failed",
|
|
160
165
|
status: "critical"
|
|
@@ -184,7 +189,7 @@ function DraggableList(_ref) {
|
|
|
184
189
|
|
|
185
190
|
if (!(effectedIds !== null && effectedIds !== void 0 && effectedIds.length)) return; // Update state to update styles + prevent data refetching
|
|
186
191
|
|
|
187
|
-
|
|
192
|
+
setListIsUpdating(true);
|
|
188
193
|
setSelectedIds(effectedIds);
|
|
189
194
|
|
|
190
195
|
var _reorderDocuments = (0, _reorderDocuments2.reorderDocuments)({
|
|
@@ -241,7 +246,13 @@ function DraggableList(_ref) {
|
|
|
241
246
|
return () => {
|
|
242
247
|
window.removeEventListener('keydown', onWindowKeyDown);
|
|
243
248
|
};
|
|
244
|
-
}, []);
|
|
249
|
+
}, []); // Find all items with duplicate order field
|
|
250
|
+
|
|
251
|
+
var duplicateOrders = (0, _react.useMemo)(() => {
|
|
252
|
+
if (!orderedData.length) return [];
|
|
253
|
+
var orderField = orderedData.map(item => item[_constants.ORDER_FIELD_NAME]);
|
|
254
|
+
return orderField.filter((item, index) => orderField.indexOf(item) !== index);
|
|
255
|
+
}, [orderedData]);
|
|
245
256
|
return /*#__PURE__*/_react.default.createElement(_reactBeautifulDnd.DragDropContext, {
|
|
246
257
|
onDragStart: handleDragStart,
|
|
247
258
|
onDragEnd: result => handleDragEnd(result, orderedData)
|
|
@@ -255,23 +266,30 @@ function DraggableList(_ref) {
|
|
|
255
266
|
index: index // onClick={(event) => handleDraggableClick(event, provided, snapshot)}
|
|
256
267
|
|
|
257
268
|
}, (innerProvided, innerSnapshot) => {
|
|
258
|
-
var
|
|
259
|
-
var
|
|
260
|
-
var isGhosting = !
|
|
261
|
-
var
|
|
262
|
-
var isDisabled = Boolean(!
|
|
269
|
+
var isSelected = selectedIds.includes(item._id);
|
|
270
|
+
var isDragging = innerSnapshot.isDragging;
|
|
271
|
+
var isGhosting = Boolean(!isDragging && draggingId && isSelected);
|
|
272
|
+
var isUpdating = isUpdating && isSelected;
|
|
273
|
+
var isDisabled = Boolean(!item[_constants.ORDER_FIELD_NAME]);
|
|
274
|
+
var isDuplicate = duplicateOrders.includes(item[_constants.ORDER_FIELD_NAME]);
|
|
275
|
+
var tone = cardTone({
|
|
276
|
+
isDuplicate,
|
|
277
|
+
isGhosting,
|
|
278
|
+
isDragging,
|
|
279
|
+
isSelected
|
|
280
|
+
});
|
|
263
281
|
return /*#__PURE__*/_react.default.createElement("div", _extends({
|
|
264
282
|
ref: innerProvided.innerRef
|
|
265
283
|
}, innerProvided.draggableProps, innerProvided.dragHandleProps, {
|
|
266
284
|
style: isDisabled ? {
|
|
267
285
|
opacity: 0.2,
|
|
268
286
|
pointerEvents: "none"
|
|
269
|
-
} : getItemStyle(innerProvided.draggableProps.style,
|
|
287
|
+
} : getItemStyle(innerProvided.draggableProps.style, isUpdating, isGhosting)
|
|
270
288
|
}), /*#__PURE__*/_react.default.createElement(_ui.Box, {
|
|
271
289
|
paddingBottom: 1
|
|
272
290
|
}, /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
273
|
-
tone:
|
|
274
|
-
shadow:
|
|
291
|
+
tone: tone,
|
|
292
|
+
shadow: isDragging ? "2" : undefined,
|
|
275
293
|
radius: 2
|
|
276
294
|
}, /*#__PURE__*/_react.default.createElement(_Document.default, {
|
|
277
295
|
doc: item,
|
|
@@ -289,7 +307,8 @@ DraggableList.propTypes = {
|
|
|
289
307
|
data: _propTypes.default.arrayOf(_propTypes.default.shape({
|
|
290
308
|
_id: _propTypes.default.string
|
|
291
309
|
}).isRequired).isRequired,
|
|
292
|
-
|
|
293
|
-
|
|
310
|
+
type: _propTypes.default.string.isRequired,
|
|
311
|
+
listIsUpdating: _propTypes.default.bool.isRequired,
|
|
312
|
+
setListIsUpdating: _propTypes.default.func.isRequired
|
|
294
313
|
};
|
|
295
314
|
//# sourceMappingURL=DraggableList.js.map
|
package/lib/DraggableList.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/DraggableList.js"],"names":["client","sanityClient","withConfig","apiVersion","getItemStyle","draggableStyle","itemIsUpdating","userSelect","transition","opacity","pointerEvents","undefined","cardTone","isGhosting","isDragging","isSelected","DraggableList","data","isUpdating","setIsUpdating","toast","orderedData","setOrderedData","draggingId","setDraggingId","selectedIds","setSelectedIds","clearSelected","handleSelect","clickedId","index","nativeEvent","includes","selectMultiple","shiftKey","isUsingWindows","navigator","appVersion","indexOf","selectAdditional","ctrlKey","metaKey","updatedIds","lastSelectedId","at","lastSelectedIndex","findIndex","item","_id","firstSelected","lastSelected","betweenIds","filter","itemIndex","map","id","transactPatches","patches","message","transaction","forEach","patchArgs","patch","commit","then","updated","push","title","results","length","status","description","catch","handleDragEnd","result","entities","source","destination","draggableId","effectedIds","newOrder","handleDragStart","start","selected","incrementIndex","shiftFrom","shiftTo","onWindowKeyDown","event","key","window","addEventListener","removeEventListener","provided","snapshot","droppableProps","innerRef","ORDER_FIELD_NAME","innerProvided","innerSnapshot","itemIsSelected","itemIsDragging","isDisabled","Boolean","draggableProps","dragHandleProps","style","placeholder","propTypes","PropTypes","arrayOf","shape","string","isRequired","bool","func"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AAEA;;AACA;;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAMA,MAAM,GAAGC,gBAAaC,UAAb,CAAwB;AACrCC,EAAAA,UAAU,EAAE;AADyB,CAAxB,CAAf;;AAIA,IAAMC,YAAY,GAAG,CAACC,cAAD,EAAiBC,cAAjB;AACnBC,EAAAA,UAAU,EAAE,MADO;AAEnBC,EAAAA,UAAU,6BAFS;AAGnBC,EAAAA,OAAO,EAAEH,cAAc,GAAG,GAAH,GAAS,CAHb;AAInBI,EAAAA,aAAa,EAAEJ,cAAc,YAAYK;AAJtB,GAKhBN,cALgB,CAArB;;AAQA,IAAMO,QAAQ,GAAG,CAACC,UAAD,EAAaC,UAAb,EAAyBC,UAAzB,KAAwC;AACvD,MAAIF,UAAJ,EAAgB;;AAChB,MAAIC,UAAU,IAAIC,UAAlB,EAA8B;AAC5B;AACD;;AAED,SAAOJ,SAAP;AACD,CAPD;;AASe,SAASK,aAAT,OAA0D;AAAA,MAAlCC,IAAkC,QAAlCA,IAAkC;AAAA,MAA5BC,UAA4B,QAA5BA,UAA4B;AAAA,MAAhBC,aAAgB,QAAhBA,aAAgB;AACvE,MAAMC,KAAK,GAAG,mBAAd,CADuE,CAGvE;;AACA,kBAAsC,qBAASH,IAAT,CAAtC;AAAA;AAAA,MAAOI,WAAP;AAAA,MAAoBC,cAApB,iBAJuE,CAMvE;;;AACA,wBAAU,MAAM;AACd,QAAI,CAACJ,UAAL,EAAiBI,cAAc,CAACL,IAAD,CAAd;AACjB;AACD,GAHD,EAGG,CAACA,IAAD,CAHH;;AAKA,mBAAoC,wBAApC;AAAA;AAAA,MAAOM,UAAP;AAAA,MAAmBC,aAAnB;;AACA,mBAAsC,qBAAS,EAAT,CAAtC;AAAA;AAAA,MAAOC,WAAP;AAAA,MAAoBC,cAApB;;AAEA,MAAMC,aAAa,GAAG,MAAMD,cAAc,CAAC,EAAD,CAA1C;;AAEA,MAAME,YAAY,GAAG,CAACC,SAAD,EAAYC,KAAZ,EAAmBC,WAAnB,KAAmC;AACtD,QAAMhB,UAAU,GAAGU,WAAW,CAACO,QAAZ,CAAqBH,SAArB,CAAnB;AACA,QAAMI,cAAc,GAAGF,WAAW,CAACG,QAAnC;AACA,QAAMC,cAAc,GAAGC,SAAS,CAACC,UAAV,CAAqBC,OAArB,CAA6B,KAA7B,MAAwC,CAAC,CAAhE;AACA,QAAMC,gBAAgB,GAAGJ,cAAc,GAAGJ,WAAW,CAACS,OAAf,GAAyBT,WAAW,CAACU,OAA5E;AAEA,QAAIC,UAAU,GAAG,EAAjB,CANsD,CAQtD;;AACA,QAAI,CAACT,cAAD,IAAmB,CAACM,gBAAxB,EAA0C;AACxC,aAAOb,cAAc,CAAC,CAACG,SAAD,CAAD,CAArB;AACD,KAXqD,CAatD;AACA;;;AACA,QAAII,cAAc,IAAI,CAAClB,UAAvB,EAAmC;AACjC,UAAM4B,cAAc,GAAGlB,WAAW,CAACmB,EAAZ,CAAe,CAAC,CAAhB,CAAvB;AACA,UAAMC,iBAAiB,GAAGxB,WAAW,CAACyB,SAAZ,CAAuBC,IAAD,IAAUA,IAAI,CAACC,GAAL,KAAaL,cAA7C,CAA1B;AAEA,UAAMM,aAAa,GAAGnB,KAAK,GAAGe,iBAAR,GAA4Bf,KAA5B,GAAoCe,iBAA1D;AACA,UAAMK,YAAY,GAAGpB,KAAK,GAAGe,iBAAR,GAA4Bf,KAA5B,GAAoCe,iBAAzD;AAEA,UAAMM,UAAU,GAAG9B,WAAW,CAC3B+B,MADgB,CACT,CAACL,IAAD,EAAOM,SAAP,KAAqBA,SAAS,GAAGJ,aAAZ,IAA6BI,SAAS,GAAGH,YADrD,EAEhBI,GAFgB,CAEXP,IAAD,IAAUA,IAAI,CAACC,GAFH,CAAnB;AAIAN,MAAAA,UAAU,GAAG,CAAC,GAAGjB,WAAJ,EAAiB,GAAG0B,UAApB,EAAgCtB,SAAhC,CAAb;AACD,KAZD,MAYO,IAAId,UAAJ,EAAgB;AACrB;AACA2B,MAAAA,UAAU,GAAGjB,WAAW,CAAC2B,MAAZ,CAAoBG,EAAD,IAAQA,EAAE,KAAK1B,SAAlC,CAAb;AACD,KAHM,MAGA;AACL;AACAa,MAAAA,UAAU,GAAG,CAAC,GAAGjB,WAAJ,EAAiBI,SAAjB,CAAb;AACD;;AAED,WAAOH,cAAc,CAACgB,UAAD,CAArB;AACD,GApCD;;AAsCA,MAAMc,eAAe;AAAA,kCAAG,WAAOC,OAAP,EAAgBC,OAAhB,EAA4B;AAClD,UAAMC,WAAW,GAAG3D,MAAM,CAAC2D,WAAP,EAApB;AAEAF,MAAAA,OAAO,CAACG,OAAR,CAAiBC,SAAD,IAAeF,WAAW,CAACG,KAAZ,CAAkB,GAAGD,SAArB,CAA/B;AAEA,YAAMF,WAAW,CACdI,MADG,GAEHC,IAFG,CAEGC,OAAD,IAAa;AACjBtC,QAAAA,aAAa;AACbH,QAAAA,aAAa,IAAb;AACAL,QAAAA,aAAa,CAAC,KAAD,CAAb;AACAC,QAAAA,KAAK,CAAC8C,IAAN,CAAW;AACTC,UAAAA,KAAK,YACHF,OAAO,CAACG,OAAR,CAAgBC,MAAhB,KAA2B,CAA3B,4BAAiDJ,OAAO,CAACG,OAAR,CAAgBC,MAAjE,eADG,eADI;AAITC,UAAAA,MAAM,WAJG;AAKTC,UAAAA,WAAW,EAAEb;AALJ,SAAX,EAJiB,CAYjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACD,OAtBG,EAuBHc,KAvBG,CAuBG,MAAM;AACXhD,QAAAA,aAAa,IAAb;AACAL,QAAAA,aAAa,CAAC,KAAD,CAAb;AACAC,QAAAA,KAAK,CAAC8C,IAAN,CAAW;AACTC,UAAAA,KAAK,qBADI;AAETG,UAAAA,MAAM;AAFG,SAAX;AAID,OA9BG,CAAN;AA+BD,KApCoB;;AAAA,oBAAfd,eAAe;AAAA;AAAA;AAAA,KAArB;;AAsCA,MAAMiB,aAAa,GAAG,CAACC,MAAD,EAASC,QAAT,KAAsB;AAC1CnD,IAAAA,aAAa,IAAb;;AAEA,gBAA2CkD,MAA3C,aAA2CA,MAA3C,cAA2CA,MAA3C,GAAqD,EAArD;AAAA,QAAOE,MAAP,SAAOA,MAAP;AAAA,QAAeC,WAAf,SAAeA,WAAf;AAAA,QAA4BC,WAA5B,SAA4BA,WAA5B,CAH0C,CAK1C;;;AACA,QAAIF,MAAM,CAAC9C,KAAP,KAAiB+C,WAAW,CAAC/C,KAAjC,EAAwC,OANE,CAQ1C;;AACA,QAAI,EAAC6C,QAAD,aAACA,QAAD,eAACA,QAAQ,CAAEN,MAAX,CAAJ,EAAuB,OATmB,CAW1C;;AACA,QAAMU,WAAW,GAAGtD,WAAW,SAAX,IAAAA,WAAW,WAAX,IAAAA,WAAW,CAAE4C,MAAb,GAAsB5C,WAAtB,GAAoC,CAACqD,WAAD,CAAxD,CAZ0C,CAc1C;;AACA,QAAI,EAACC,WAAD,aAACA,WAAD,eAACA,WAAW,CAAEV,MAAd,CAAJ,EAA0B,OAfgB,CAiB1C;;AACAlD,IAAAA,aAAa,CAAC,IAAD,CAAb;AACAO,IAAAA,cAAc,CAACqD,WAAD,CAAd;;AAEA,4BAAqC,yCAAiB;AACpDJ,MAAAA,QADoD;AAEpDlD,MAAAA,WAAW,EAAEsD,WAFuC;AAGpDH,MAAAA,MAHoD;AAIpDC,MAAAA;AAJoD,KAAjB,CAArC;AAAA,QAAOG,QAAP,qBAAOA,QAAP;AAAA,QAAiBvB,OAAjB,qBAAiBA,OAAjB;AAAA,QAA0BC,OAA1B,qBAA0BA,OAA1B,CArB0C,CA4B1C;;;AACA,QAAIsB,QAAJ,aAAIA,QAAJ,eAAIA,QAAQ,CAAEX,MAAd,EAAsB;AACpB/C,MAAAA,cAAc,CAAC0D,QAAD,CAAd;AACD,KA/ByC,CAiC1C;;;AACA,QAAIvB,OAAJ,aAAIA,OAAJ,eAAIA,OAAO,CAAEY,MAAb,EAAqB;AACnBb,MAAAA,eAAe,CAACC,OAAD,EAAUC,OAAV,CAAf;AACD;AACF,GArCD;;AAuCA,MAAMuB,eAAe,GAAIC,KAAD,IAAW;AACjC,QAAM3B,EAAE,GAAG2B,KAAK,CAACJ,WAAjB;AACA,QAAMK,QAAQ,GAAG1D,WAAW,CAACO,QAAZ,CAAqBuB,EAArB,CAAjB,CAFiC,CAIjC;;AACA,QAAI,CAAC4B,QAAL,EAAexD,aAAa;AAE5BH,IAAAA,aAAa,CAAC+B,EAAD,CAAb;AACD,GARD,CApIuE,CA8IvE;;;AACA,MAAM6B,cAAc,GAAG,CAACC,SAAD,EAAYC,OAAZ,EAAqB/B,EAArB,EAAyBoB,QAAzB,KAAsC;AAC3D,QAAMD,MAAM,GAAG;AACbI,MAAAA,WAAW,EAAEvB,EADA;AAEbqB,MAAAA,MAAM,EAAE;AAAC9C,QAAAA,KAAK,EAAEuD;AAAR,OAFK;AAGbR,MAAAA,WAAW,EAAE;AAAC/C,QAAAA,KAAK,EAAEwD;AAAR;AAHA,KAAf;AAMA,WAAOb,aAAa,CAACC,MAAD,EAASC,QAAT,CAApB;AACD,GARD;;AAUA,MAAMY,eAAe,GAAIC,KAAD,IAAW;AACjC,QAAIA,KAAK,CAACC,GAAN,KAAc,QAAlB,EAA4B;AAC1B9D,MAAAA,aAAa;AACd;AACF,GAJD;;AAMA,wBAAU,MAAM;AACd+D,IAAAA,MAAM,CAACC,gBAAP,CAAwB,SAAxB,EAAmCJ,eAAnC;AAEA,WAAO,MAAM;AACXG,MAAAA,MAAM,CAACE,mBAAP,CAA2B,SAA3B,EAAsCL,eAAtC;AACD,KAFD;AAGD,GAND,EAMG,EANH;AAQA,sBACE,6BAAC,kCAAD;AACE,IAAA,WAAW,EAAEN,eADf;AAEE,IAAA,SAAS,EAAGP,MAAD,IAAYD,aAAa,CAACC,MAAD,EAASrD,WAAT;AAFtC,kBAIE,6BAAC,4BAAD;AAAW,IAAA,WAAW,EAAC;AAAvB,KACG,CAACwE,QAAD,EAAWC,QAAX,kBACC,iDAASD,QAAQ,CAACE,cAAlB;AAAkC,IAAA,GAAG,EAAEF,QAAQ,CAACG;AAAhD,MACG3E,WAAW,CAACiC,GAAZ,CAAgB,CAACP,IAAD,EAAOjB,KAAP,kBACf,6BAAC,4BAAD;AACE,IAAA,GAAG,YAAKiB,IAAI,CAACC,GAAV,cAAiBD,IAAI,CAACkD,2BAAD,CAArB,CADL;AAEE,IAAA,WAAW,EAAElD,IAAI,CAACC,GAFpB;AAGE,IAAA,KAAK,EAAElB,KAHT,CAIE;;AAJF,KAMG,CAACoE,aAAD,EAAgBC,aAAhB,KAAkC;AACjC,QAAMC,cAAc,GAAG3E,WAAW,CAACO,QAAZ,CAAqBe,IAAI,CAACC,GAA1B,CAAvB;AACA,QAAMqD,cAAc,GAAGF,aAAa,CAACrF,UAArC;AACA,QAAMD,UAAU,GAAG,CAACwF,cAAD,IAAmB9E,UAAnB,IAAiC6E,cAApD;AACA,QAAM9F,cAAc,GAAGY,UAAU,IAAIkF,cAArC;AACA,QAAME,UAAU,GAAGC,OAAO,CAAC,EAACxD,IAAD,aAACA,IAAD,eAACA,IAAI,CAAGkD,2BAAH,CAAL,CAAD,CAA1B;AAEA,wBACE;AACE,MAAA,GAAG,EAAEC,aAAa,CAACF;AADrB,OAEME,aAAa,CAACM,cAFpB,EAGMN,aAAa,CAACO,eAHpB;AAIE,MAAA,KAAK,EACHH,UAAU,GACN;AAAC7F,QAAAA,OAAO,EAAE,GAAV;AAAeC,QAAAA,aAAa;AAA5B,OADM,GAENN,YAAY,CACV8F,aAAa,CAACM,cAAd,CAA6BE,KADnB,EAEVpG,cAFU,EAGVO,UAHU;AAPpB,qBAcE,6BAAC,OAAD;AAAK,MAAA,aAAa,EAAE;AAApB,oBACE,6BAAC,QAAD;AACE,MAAA,IAAI,EAAED,QAAQ,CAACC,UAAD,EAAawF,cAAb,EAA6BD,cAA7B,CADhB;AAEE,MAAA,MAAM,EAAEC,cAAc,SAAS1F,SAFjC;AAGE,MAAA,MAAM,EAAE;AAHV,oBAKE,6BAAC,iBAAD;AACE,MAAA,GAAG,EAAEoC,IADP;AAEE,MAAA,QAAQ,EAAE1B,WAFZ;AAGE,MAAA,YAAY,EAAEO,YAHhB;AAIE,MAAA,SAAS,EAAEwD,cAJb;AAKE,MAAA,KAAK,EAAEtD,KALT;AAME,MAAA,OAAO,EAAEA,KAAK,KAAK,CANrB;AAOE,MAAA,MAAM,EAAEA,KAAK,KAAKT,WAAW,CAACgD,MAAZ,GAAqB;AAPzC,MALF,CADF,CAdF,CADF;AAkCD,GA/CH,CADD,CADH,EAoDGwB,QAAQ,CAACc,WApDZ,CAFJ,CAJF,CADF;AAiED;;AAED3F,aAAa,CAAC4F,SAAd,GAA0B;AACxB3F,EAAAA,IAAI,EAAE4F,mBAAUC,OAAV,CACJD,mBAAUE,KAAV,CAAgB;AACd/D,IAAAA,GAAG,EAAE6D,mBAAUG;AADD,GAAhB,EAEGC,UAHC,EAIJA,UALsB;AAMxB/F,EAAAA,UAAU,EAAE2F,mBAAUK,IAAV,CAAeD,UANH;AAOxB9F,EAAAA,aAAa,EAAE0F,mBAAUM,IAAV,CAAeF;AAPN,CAA1B","sourcesContent":["import PropTypes from 'prop-types'\nimport React, {useState, useEffect} from 'react'\nimport {DragDropContext, Droppable, Draggable} from 'react-beautiful-dnd'\nimport sanityClient from 'part:@sanity/base/client'\nimport {Box, Card, useToast} from '@sanity/ui'\n\nimport Document from './Document'\nimport {reorderDocuments} from './helpers/reorderDocuments'\nimport {ORDER_FIELD_NAME} from './helpers/constants'\n\nconst client = sanityClient.withConfig({\n apiVersion: '2021-09-01',\n})\n\nconst getItemStyle = (draggableStyle, itemIsUpdating) => ({\n userSelect: 'none',\n transition: `opacity 500ms ease-in-out`,\n opacity: itemIsUpdating ? 0.2 : 1,\n pointerEvents: itemIsUpdating ? `none` : undefined,\n ...draggableStyle,\n})\n\nconst cardTone = (isGhosting, isDragging, isSelected) => {\n if (isGhosting) return `transparent`\n if (isDragging || isSelected) {\n return `primary`\n }\n\n return undefined\n}\n\nexport default function DraggableList({data, isUpdating, setIsUpdating}) {\n const toast = useToast()\n\n // Maintains local state order before transaction completes\n const [orderedData, setOrderedData] = useState(data)\n\n // Update local state when documents change from an outside source\n useEffect(() => {\n if (!isUpdating) setOrderedData(data)\n /* eslint-disable-next-line react-hooks/exhaustive-deps */\n }, [data])\n\n const [draggingId, setDraggingId] = useState(``)\n const [selectedIds, setSelectedIds] = useState([])\n\n const clearSelected = () => setSelectedIds([])\n\n const handleSelect = (clickedId, index, nativeEvent) => {\n const isSelected = selectedIds.includes(clickedId)\n const selectMultiple = nativeEvent.shiftKey\n const isUsingWindows = navigator.appVersion.indexOf('Win') !== -1\n const selectAdditional = isUsingWindows ? nativeEvent.ctrlKey : nativeEvent.metaKey\n\n let updatedIds = []\n\n // No modifiers, update selected to just this one\n if (!selectMultiple && !selectAdditional) {\n return setSelectedIds([clickedId])\n }\n\n // Shift key was held, add id's between last selected and this one\n // ...before adding this one\n if (selectMultiple && !isSelected) {\n const lastSelectedId = selectedIds.at(-1)\n const lastSelectedIndex = orderedData.findIndex((item) => item._id === lastSelectedId)\n\n const firstSelected = index < lastSelectedIndex ? index : lastSelectedIndex\n const lastSelected = index > lastSelectedIndex ? index : lastSelectedIndex\n\n const betweenIds = orderedData\n .filter((item, itemIndex) => itemIndex > firstSelected && itemIndex < lastSelected)\n .map((item) => item._id)\n\n updatedIds = [...selectedIds, ...betweenIds, clickedId]\n } else if (isSelected) {\n // Toggle off a single id\n updatedIds = selectedIds.filter((id) => id !== clickedId)\n } else {\n // Toggle on a single id\n updatedIds = [...selectedIds, clickedId]\n }\n\n return setSelectedIds(updatedIds)\n }\n\n const transactPatches = async (patches, message) => {\n const transaction = client.transaction()\n\n patches.forEach((patchArgs) => transaction.patch(...patchArgs))\n\n await transaction\n .commit()\n .then((updated) => {\n clearSelected()\n setDraggingId(``)\n setIsUpdating(false)\n toast.push({\n title: `${\n updated.results.length === 1 ? `1 Document` : `${updated.results.length} Documents`\n } Reordered`,\n status: `success`,\n description: message,\n })\n\n // Another \"I didn't write tests but I'm going to console.log my way to victory\" piece of programming\n // fetch(\n // `https://i2v7h052.api.sanity.io/v2021-03-25/data/query/production?query=*%5B_type%20%3D%3D%20%22category%22%5D%7Corder(orderRank)%7B%0A%20%20title%2C%20orderRank%0A%7D`\n // )\n // .then((res) => res.json())\n // .then((res) => {\n // console.table(res.result.map((item) => item?.title).join(', '))\n // })\n })\n .catch(() => {\n setDraggingId(``)\n setIsUpdating(false)\n toast.push({\n title: `Reordering failed`,\n status: `critical`,\n })\n })\n }\n\n const handleDragEnd = (result, entities) => {\n setDraggingId(``)\n\n const {source, destination, draggableId} = result ?? {}\n\n // Don't do anything if nothing changed\n if (source.index === destination.index) return\n\n // Don't do anything if we don't have the entitites\n if (!entities?.length) return\n\n // A document can be dragged without being one-of-many-selected\n const effectedIds = selectedIds?.length ? selectedIds : [draggableId]\n\n // Don't do anything if we don't have ids to effect\n if (!effectedIds?.length) return\n\n // Update state to update styles + prevent data refetching\n setIsUpdating(true)\n setSelectedIds(effectedIds)\n\n const {newOrder, patches, message} = reorderDocuments({\n entities,\n selectedIds: effectedIds,\n source,\n destination,\n })\n\n // Update local state\n if (newOrder?.length) {\n setOrderedData(newOrder)\n }\n\n // Transact new order patches\n if (patches?.length) {\n transactPatches(patches, message)\n }\n }\n\n const handleDragStart = (start) => {\n const id = start.draggableId\n const selected = selectedIds.includes(id)\n\n // if dragging an item that is not selected - unselect all items\n if (!selected) clearSelected()\n\n setDraggingId(id)\n }\n\n // Move one document up or down one place, by fake invoking the drag function\n const incrementIndex = (shiftFrom, shiftTo, id, entities) => {\n const result = {\n draggableId: id,\n source: {index: shiftFrom},\n destination: {index: shiftTo},\n }\n\n return handleDragEnd(result, entities)\n }\n\n const onWindowKeyDown = (event) => {\n if (event.key === 'Escape') {\n clearSelected()\n }\n }\n\n useEffect(() => {\n window.addEventListener('keydown', onWindowKeyDown)\n\n return () => {\n window.removeEventListener('keydown', onWindowKeyDown)\n }\n }, [])\n\n return (\n <DragDropContext\n onDragStart={handleDragStart}\n onDragEnd={(result) => handleDragEnd(result, orderedData)}\n >\n <Droppable droppableId=\"documentSortZone\">\n {(provided, snapshot) => (\n <div {...provided.droppableProps} ref={provided.innerRef}>\n {orderedData.map((item, index) => (\n <Draggable\n key={`${item._id}-${item[ORDER_FIELD_NAME]}`}\n draggableId={item._id}\n index={index}\n // onClick={(event) => handleDraggableClick(event, provided, snapshot)}\n >\n {(innerProvided, innerSnapshot) => {\n const itemIsSelected = selectedIds.includes(item._id)\n const itemIsDragging = innerSnapshot.isDragging\n const isGhosting = !itemIsDragging && draggingId && itemIsSelected\n const itemIsUpdating = isUpdating && itemIsSelected\n const isDisabled = Boolean(!item?.[ORDER_FIELD_NAME])\n\n return (\n <div\n ref={innerProvided.innerRef}\n {...innerProvided.draggableProps}\n {...innerProvided.dragHandleProps}\n style={\n isDisabled\n ? {opacity: 0.2, pointerEvents: `none`}\n : getItemStyle(\n innerProvided.draggableProps.style,\n itemIsUpdating,\n isGhosting\n )\n }\n >\n <Box paddingBottom={1}>\n <Card\n tone={cardTone(isGhosting, itemIsDragging, itemIsSelected)}\n shadow={itemIsDragging ? `2` : undefined}\n radius={2}\n >\n <Document\n doc={item}\n entities={orderedData}\n handleSelect={handleSelect}\n increment={incrementIndex}\n index={index}\n isFirst={index === 0}\n isLast={index === orderedData.length - 1}\n />\n </Card>\n </Box>\n </div>\n )\n }}\n </Draggable>\n ))}\n {provided.placeholder}\n </div>\n )}\n </Droppable>\n </DragDropContext>\n )\n}\n\nDraggableList.propTypes = {\n data: PropTypes.arrayOf(\n PropTypes.shape({\n _id: PropTypes.string,\n }).isRequired\n ).isRequired,\n isUpdating: PropTypes.bool.isRequired,\n setIsUpdating: PropTypes.func.isRequired,\n}\n"],"file":"DraggableList.js"}
|
|
1
|
+
{"version":3,"sources":["../src/DraggableList.js"],"names":["client","sanityClient","withConfig","apiVersion","getItemStyle","draggableStyle","itemIsUpdating","userSelect","transition","opacity","pointerEvents","undefined","cardTone","settings","isDuplicate","isGhosting","isDragging","isSelected","DraggableList","data","type","listIsUpdating","setListIsUpdating","toast","router","navigateIntent","orderedData","setOrderedData","draggingId","setDraggingId","selectedIds","setSelectedIds","clearSelected","handleSelect","clickedId","index","nativeEvent","includes","selectMultiple","shiftKey","isUsingWindows","navigator","appVersion","indexOf","selectAdditional","ctrlKey","metaKey","updatedIds","id","lastSelectedId","at","lastSelectedIndex","findIndex","item","_id","firstSelected","lastSelected","betweenIds","filter","itemIndex","map","transactPatches","patches","message","transaction","forEach","patchArgs","patch","commit","then","updated","push","title","results","length","status","description","catch","handleDragEnd","result","entities","source","destination","draggableId","effectedIds","newOrder","handleDragStart","start","selected","incrementIndex","shiftFrom","shiftTo","onWindowKeyDown","event","key","window","addEventListener","removeEventListener","duplicateOrders","orderField","ORDER_FIELD_NAME","provided","snapshot","droppableProps","innerRef","innerProvided","innerSnapshot","Boolean","isUpdating","isDisabled","tone","draggableProps","dragHandleProps","style","placeholder","propTypes","PropTypes","arrayOf","shape","string","isRequired","bool","func"],"mappings":"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","sourcesContent":["import PropTypes from 'prop-types'\nimport React, {useMemo, useState, useEffect} from 'react'\nimport {DragDropContext, Droppable, Draggable} from 'react-beautiful-dnd'\nimport {usePaneRouter} from '@sanity/desk-tool'\nimport {Box, Card, useToast} from '@sanity/ui'\nimport sanityClient from 'part:@sanity/base/client'\n\nimport Document from './Document'\nimport {reorderDocuments} from './helpers/reorderDocuments'\nimport {ORDER_FIELD_NAME} from './helpers/constants'\n\nconst client = sanityClient.withConfig({\n apiVersion: '2021-09-01',\n})\n\nconst getItemStyle = (draggableStyle, itemIsUpdating) => ({\n userSelect: 'none',\n transition: `opacity 500ms ease-in-out`,\n opacity: itemIsUpdating ? 0.2 : 1,\n pointerEvents: itemIsUpdating ? `none` : undefined,\n ...draggableStyle,\n})\n\nconst cardTone = (settings) => {\n const {isDuplicate, isGhosting, isDragging, isSelected} = settings\n\n if (isGhosting) return `transparent`\n if (isDragging || isSelected) return `primary`\n if (isDuplicate) return `caution`\n\n return undefined\n}\n\nexport default function DraggableList({data, type, listIsUpdating, setListIsUpdating}) {\n const toast = useToast()\n const router = usePaneRouter()\n const {navigateIntent} = router\n\n // Maintains local state order before transaction completes\n const [orderedData, setOrderedData] = useState(data)\n\n // Update local state when documents change from an outside source\n useEffect(() => {\n if (!listIsUpdating) setOrderedData(data)\n /* eslint-disable-next-line react-hooks/exhaustive-deps */\n }, [data])\n\n const [draggingId, setDraggingId] = useState(``)\n const [selectedIds, setSelectedIds] = useState([])\n\n const clearSelected = () => setSelectedIds([])\n\n const handleSelect = (clickedId, index, nativeEvent) => {\n const isSelected = selectedIds.includes(clickedId)\n const selectMultiple = nativeEvent.shiftKey\n const isUsingWindows = navigator.appVersion.indexOf('Win') !== -1\n const selectAdditional = isUsingWindows ? nativeEvent.ctrlKey : nativeEvent.metaKey\n\n let updatedIds = []\n\n // No modifier keys pressed during click:\n // - update selected to just this one\n // - open document\n if (!selectMultiple && !selectAdditional) {\n navigateIntent('edit', {id: clickedId, type})\n return setSelectedIds([clickedId])\n }\n\n // Shift key was held, add id's between last selected and this one\n // ...before adding this one\n if (selectMultiple && !isSelected) {\n const lastSelectedId = selectedIds.at(-1)\n const lastSelectedIndex = orderedData.findIndex((item) => item._id === lastSelectedId)\n\n const firstSelected = index < lastSelectedIndex ? index : lastSelectedIndex\n const lastSelected = index > lastSelectedIndex ? index : lastSelectedIndex\n\n const betweenIds = orderedData\n .filter((item, itemIndex) => itemIndex > firstSelected && itemIndex < lastSelected)\n .map((item) => item._id)\n\n updatedIds = [...selectedIds, ...betweenIds, clickedId]\n } else if (isSelected) {\n // Toggle off a single id\n updatedIds = selectedIds.filter((id) => id !== clickedId)\n } else {\n // Toggle on a single id\n updatedIds = [...selectedIds, clickedId]\n }\n\n return setSelectedIds(updatedIds)\n }\n\n const transactPatches = async (patches, message) => {\n const transaction = client.transaction()\n\n patches.forEach((patchArgs) => transaction.patch(...patchArgs))\n\n await transaction\n .commit()\n .then((updated) => {\n clearSelected()\n setDraggingId(``)\n setListIsUpdating(false)\n toast.push({\n title: `${\n updated.results.length === 1 ? `1 Document` : `${updated.results.length} Documents`\n } Reordered`,\n status: `success`,\n description: message,\n })\n })\n .catch(() => {\n setDraggingId(``)\n setListIsUpdating(false)\n toast.push({\n title: `Reordering failed`,\n status: `critical`,\n })\n })\n }\n\n const handleDragEnd = (result, entities) => {\n setDraggingId(``)\n\n const {source, destination, draggableId} = result ?? {}\n\n // Don't do anything if nothing changed\n if (source.index === destination.index) return\n\n // Don't do anything if we don't have the entitites\n if (!entities?.length) return\n\n // A document can be dragged without being one-of-many-selected\n const effectedIds = selectedIds?.length ? selectedIds : [draggableId]\n\n // Don't do anything if we don't have ids to effect\n if (!effectedIds?.length) return\n\n // Update state to update styles + prevent data refetching\n setListIsUpdating(true)\n setSelectedIds(effectedIds)\n\n const {newOrder, patches, message} = reorderDocuments({\n entities,\n selectedIds: effectedIds,\n source,\n destination,\n })\n\n // Update local state\n if (newOrder?.length) {\n setOrderedData(newOrder)\n }\n\n // Transact new order patches\n if (patches?.length) {\n transactPatches(patches, message)\n }\n }\n\n const handleDragStart = (start) => {\n const id = start.draggableId\n const selected = selectedIds.includes(id)\n\n // if dragging an item that is not selected - unselect all items\n if (!selected) clearSelected()\n\n setDraggingId(id)\n }\n\n // Move one document up or down one place, by fake invoking the drag function\n const incrementIndex = (shiftFrom, shiftTo, id, entities) => {\n const result = {\n draggableId: id,\n source: {index: shiftFrom},\n destination: {index: shiftTo},\n }\n\n return handleDragEnd(result, entities)\n }\n\n const onWindowKeyDown = (event) => {\n if (event.key === 'Escape') {\n clearSelected()\n }\n }\n\n useEffect(() => {\n window.addEventListener('keydown', onWindowKeyDown)\n\n return () => {\n window.removeEventListener('keydown', onWindowKeyDown)\n }\n }, [])\n\n // Find all items with duplicate order field\n const duplicateOrders = useMemo(() => {\n if (!orderedData.length) return []\n\n const orderField = orderedData.map((item) => item[ORDER_FIELD_NAME])\n\n return orderField.filter((item, index) => orderField.indexOf(item) !== index)\n }, [orderedData])\n\n return (\n <DragDropContext\n onDragStart={handleDragStart}\n onDragEnd={(result) => handleDragEnd(result, orderedData)}\n >\n <Droppable droppableId=\"documentSortZone\">\n {(provided, snapshot) => (\n <div {...provided.droppableProps} ref={provided.innerRef}>\n {orderedData.map((item, index) => (\n <Draggable\n key={`${item._id}-${item[ORDER_FIELD_NAME]}`}\n draggableId={item._id}\n index={index}\n // onClick={(event) => handleDraggableClick(event, provided, snapshot)}\n >\n {(innerProvided, innerSnapshot) => {\n const isSelected = selectedIds.includes(item._id)\n const isDragging = innerSnapshot.isDragging\n const isGhosting = Boolean(!isDragging && draggingId && isSelected)\n const isUpdating = isUpdating && isSelected\n const isDisabled = Boolean(!item[ORDER_FIELD_NAME])\n const isDuplicate = duplicateOrders.includes(item[ORDER_FIELD_NAME])\n const tone = cardTone({isDuplicate, isGhosting, isDragging, isSelected})\n\n return (\n <div\n ref={innerProvided.innerRef}\n {...innerProvided.draggableProps}\n {...innerProvided.dragHandleProps}\n style={\n isDisabled\n ? {opacity: 0.2, pointerEvents: `none`}\n : getItemStyle(innerProvided.draggableProps.style, isUpdating, isGhosting)\n }\n >\n <Box paddingBottom={1}>\n <Card tone={tone} shadow={isDragging ? `2` : undefined} radius={2}>\n <Document\n doc={item}\n entities={orderedData}\n handleSelect={handleSelect}\n increment={incrementIndex}\n index={index}\n isFirst={index === 0}\n isLast={index === orderedData.length - 1}\n />\n </Card>\n </Box>\n </div>\n )\n }}\n </Draggable>\n ))}\n {provided.placeholder}\n </div>\n )}\n </Droppable>\n </DragDropContext>\n )\n}\n\nDraggableList.propTypes = {\n data: PropTypes.arrayOf(\n PropTypes.shape({\n _id: PropTypes.string,\n }).isRequired\n ).isRequired,\n type: PropTypes.string.isRequired,\n listIsUpdating: PropTypes.bool.isRequired,\n setListIsUpdating: PropTypes.func.isRequired,\n}\n"],"file":"DraggableList.js"}
|
|
@@ -92,30 +92,8 @@ var reorderDocuments = _ref2 => {
|
|
|
92
92
|
for (var selectedIndex = 0; selectedIndex < selectedItems.length; selectedIndex += 1) {
|
|
93
93
|
selectedItems[selectedIndex][_constants.ORDER_FIELD_NAME] = betweenRank.value;
|
|
94
94
|
betweenRank = isMovingUp ? betweenRank.between(curRank) : betweenRank.between(nextRank);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// createManifest({
|
|
98
|
-
// entities,
|
|
99
|
-
// selectedItems,
|
|
100
|
-
// isMovingUp,
|
|
101
|
-
// curIndex,
|
|
102
|
-
// nextIndex,
|
|
103
|
-
// prevIndex,
|
|
104
|
-
// })
|
|
105
|
-
// )
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// This data is not actually used by the plugin
|
|
109
|
-
// console.table(
|
|
110
|
-
// createManifest({
|
|
111
|
-
// entities,
|
|
112
|
-
// selectedItems,
|
|
113
|
-
// isMovingUp,
|
|
114
|
-
// curIndex,
|
|
115
|
-
// nextIndex,
|
|
116
|
-
// prevIndex,
|
|
117
|
-
// })
|
|
118
|
-
// )
|
|
95
|
+
}
|
|
96
|
+
|
|
119
97
|
return {
|
|
120
98
|
// The `all` array gets sorted by order field later anyway
|
|
121
99
|
// so that this probably isn't necessary ¯\_(ツ)_/¯
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/helpers/reorderDocuments.js"],"names":["lexicographicalSort","a","b","ORDER_FIELD_NAME","createManifest","entities","selectedItems","isMovingUp","curIndex","nextIndex","prevIndex","table","name","title","order","map","item","itemIndex","length","sort","reorderDocuments","selectedIds","source","destination","debug","startIndex","index","endIndex","filter","includes","_id","message","join","reduce","acc","cur","all","selected","prevRank","LexoRank","parse","min","curRank","nextRank","max","betweenRank","between","selectedIndex","value","patches","doc","set","allSorted","newOrder"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/reorderDocuments.js"],"names":["lexicographicalSort","a","b","ORDER_FIELD_NAME","createManifest","entities","selectedItems","isMovingUp","curIndex","nextIndex","prevIndex","table","name","title","order","map","item","itemIndex","length","sort","reorderDocuments","selectedIds","source","destination","debug","startIndex","index","endIndex","filter","includes","_id","message","join","reduce","acc","cur","all","selected","prevRank","LexoRank","parse","min","curRank","nextRank","max","betweenRank","between","selectedIndex","value","patches","doc","set","allSorted","newOrder"],"mappings":"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","sourcesContent":["import {LexoRank} from 'lexorank'\nimport {ORDER_FIELD_NAME} from './constants'\n\nfunction lexicographicalSort(a, b) {\n if (a[ORDER_FIELD_NAME] < b[ORDER_FIELD_NAME]) {\n return -1\n }\n if (a[ORDER_FIELD_NAME] > b[ORDER_FIELD_NAME]) {\n return 1\n }\n return 0\n}\n\n// In lieu of actual *tests*, this is a table\n// to visualise the new order which if correct, shows:\n// 1. The `before` field (or start of the list)\n// 2. The inserted fields, in order\n// 3. The `after` document (or end of the list)\n// eslint-disable-next-line no-unused-vars\nfunction createManifest({entities, selectedItems, isMovingUp, curIndex, nextIndex, prevIndex}) {\n const table = [\n {\n name: `Before`,\n title:\n curIndex === 0 ? `<<Start of List>>` : entities[isMovingUp ? prevIndex : curIndex]?.title,\n order: curIndex === 0 ? `000` : entities[isMovingUp ? prevIndex : curIndex][ORDER_FIELD_NAME],\n },\n ...selectedItems.map((item, itemIndex) => ({\n name: itemIndex,\n title: item?.title,\n order: item[ORDER_FIELD_NAME],\n })),\n {\n name: `After`,\n title:\n curIndex === entities.length - 1\n ? `<<End of List>>`\n : entities[isMovingUp ? curIndex : nextIndex]?.title,\n order:\n curIndex === entities.length - 1\n ? `zzz`\n : entities[isMovingUp ? curIndex : nextIndex][ORDER_FIELD_NAME],\n },\n ]\n\n return table.sort(lexicographicalSort)\n}\n\nexport const reorderDocuments = ({entities, selectedIds, source, destination, debug = false}) => {\n const startIndex = source.index\n const endIndex = destination.index\n const isMovingUp = startIndex > endIndex\n const selectedItems = entities.filter((item) => selectedIds.includes(item._id))\n const message = [\n `Moved`,\n selectedItems.length === 1 ? `1 Document` : `${selectedItems.length} Documents`,\n isMovingUp ? `up` : `down`,\n `from position`,\n `${startIndex + 1} to ${endIndex + 1}`,\n ].join(' ')\n\n const {all, selected} = entities.reduce(\n (acc, cur, curIndex) => {\n // Selected items get spread in below, so skip them here\n if (selectedIds.includes(cur._id)) {\n return {all: acc.all, selected: acc.selected}\n }\n\n // Drop seleced items in\n if (curIndex === endIndex) {\n const prevIndex = curIndex - 1\n const prevRank = entities[prevIndex]?.[ORDER_FIELD_NAME]\n ? LexoRank.parse(entities[prevIndex]?.[ORDER_FIELD_NAME])\n : LexoRank.min()\n\n const curRank = LexoRank.parse(entities[curIndex][ORDER_FIELD_NAME])\n\n const nextIndex = curIndex + 1\n const nextRank = entities[nextIndex]?.[ORDER_FIELD_NAME]\n ? LexoRank.parse(entities[nextIndex]?.[ORDER_FIELD_NAME])\n : LexoRank.max()\n\n let betweenRank = isMovingUp ? prevRank.between(curRank) : curRank.between(nextRank)\n\n // For each selected item, assign a new orderRank between now and next\n for (let selectedIndex = 0; selectedIndex < selectedItems.length; selectedIndex += 1) {\n selectedItems[selectedIndex][ORDER_FIELD_NAME] = betweenRank.value\n betweenRank = isMovingUp ? betweenRank.between(curRank) : betweenRank.between(nextRank)\n }\n\n return {\n // The `all` array gets sorted by order field later anyway\n // so that this probably isn't necessary ¯\\_(ツ)_/¯\n all: isMovingUp\n ? [...acc.all, ...selectedItems, cur]\n : [...acc.all, cur, ...selectedItems],\n selected: selectedItems,\n }\n }\n\n return {all: [...acc.all, cur], selected: acc.selected}\n },\n {all: [], selected: []}\n )\n\n const patches = selected.map((doc) => {\n return [\n doc._id,\n {\n set: {\n [ORDER_FIELD_NAME]: doc[ORDER_FIELD_NAME],\n },\n },\n ]\n })\n\n // Safety-check to make sure everything is in order\n const allSorted = all.sort(lexicographicalSort)\n\n return {newOrder: allSorted, patches, message}\n}\n"],"file":"reorderDocuments.js"}
|
package/package.json
CHANGED
package/src/Document.js
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
2
|
// eslint-disable-next-line no-unused-vars
|
|
3
|
-
import React, {
|
|
4
|
-
import {
|
|
5
|
-
DragHandleIcon,
|
|
6
|
-
ChevronUpIcon,
|
|
7
|
-
ChevronDownIcon,
|
|
8
|
-
ChevronRightIcon,
|
|
9
|
-
EditIcon,
|
|
10
|
-
} from '@sanity/icons'
|
|
3
|
+
import React, {useContext} from 'react'
|
|
4
|
+
import {DragHandleIcon, ChevronUpIcon, ChevronDownIcon} from '@sanity/icons'
|
|
11
5
|
import {Text, Flex, Box, Button} from '@sanity/ui'
|
|
12
|
-
import {usePaneRouter} from '@sanity/desk-tool'
|
|
13
6
|
import Preview from 'part:@sanity/base/preview'
|
|
14
7
|
import schema from 'part:@sanity/base/schema'
|
|
15
8
|
|
|
@@ -55,13 +48,6 @@ export default function Document({doc, increment, entities, handleSelect, index,
|
|
|
55
48
|
</Box>
|
|
56
49
|
</Flex>
|
|
57
50
|
</Button>
|
|
58
|
-
<Box paddingX={3} style={{flexShrink: 0}}>
|
|
59
|
-
<ChildEditLink id={doc._id}>
|
|
60
|
-
<Text fontSize={4}>
|
|
61
|
-
{doc._id.startsWith(`drafts.`) ? <EditIcon /> : <ChevronRightIcon />}
|
|
62
|
-
</Text>
|
|
63
|
-
</ChildEditLink>
|
|
64
|
-
</Box>
|
|
65
51
|
</Flex>
|
|
66
52
|
)
|
|
67
53
|
}
|
|
@@ -82,35 +68,3 @@ Document.propTypes = {
|
|
|
82
68
|
isFirst: PropTypes.bool.isRequired,
|
|
83
69
|
isLast: PropTypes.bool.isRequired,
|
|
84
70
|
}
|
|
85
|
-
|
|
86
|
-
const ChildEditLink = ({id, children}) => {
|
|
87
|
-
const router = usePaneRouter()
|
|
88
|
-
const {ChildLink, routerPanesState} = router
|
|
89
|
-
|
|
90
|
-
// Is this document currently being edited
|
|
91
|
-
const isOpen = useMemo(
|
|
92
|
-
() => routerPanesState.some((pane) => pane[0]?.id === id.replace(`drafts.`, ``)),
|
|
93
|
-
[id, routerPanesState]
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
const Link = useCallback(
|
|
97
|
-
(linkProps) => <ChildLink {...linkProps} childId={id.replace(`drafts.`, ``)} />,
|
|
98
|
-
[ChildLink, id]
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
return (
|
|
102
|
-
<Button
|
|
103
|
-
as={Link}
|
|
104
|
-
mode={isOpen ? `default` : `ghost`}
|
|
105
|
-
tone={isOpen ? `primary` : `transparent`}
|
|
106
|
-
padding={2}
|
|
107
|
-
>
|
|
108
|
-
{children}
|
|
109
|
-
</Button>
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
ChildEditLink.propTypes = {
|
|
114
|
-
id: PropTypes.string.isRequired,
|
|
115
|
-
children: PropTypes.node.isRequired,
|
|
116
|
-
}
|
package/src/DocumentListQuery.js
CHANGED
|
@@ -13,7 +13,7 @@ const client = sanityClient.withConfig({
|
|
|
13
13
|
|
|
14
14
|
export default function DocumentListQuery({type}) {
|
|
15
15
|
const [isLoading, setIsLoading] = useState(true)
|
|
16
|
-
const [
|
|
16
|
+
const [listIsUpdating, setListIsUpdating] = useState(false)
|
|
17
17
|
const [data, setData] = useState([])
|
|
18
18
|
|
|
19
19
|
useEffect(() => {
|
|
@@ -57,7 +57,7 @@ export default function DocumentListQuery({type}) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// Get data but only if a document isn't being patched or we don't yet have data
|
|
60
|
-
if (!
|
|
60
|
+
if (!listIsUpdating && !data.length) {
|
|
61
61
|
prepareData()
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -86,7 +86,12 @@ export default function DocumentListQuery({type}) {
|
|
|
86
86
|
</Feedback>
|
|
87
87
|
)}
|
|
88
88
|
<Box padding={1}>
|
|
89
|
-
<DraggableList
|
|
89
|
+
<DraggableList
|
|
90
|
+
data={data}
|
|
91
|
+
type={type}
|
|
92
|
+
listIsUpdating={listIsUpdating}
|
|
93
|
+
setListIsUpdating={setListIsUpdating}
|
|
94
|
+
/>
|
|
90
95
|
</Box>
|
|
91
96
|
</Stack>
|
|
92
97
|
)
|
package/src/DraggableList.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
|
-
import React, {useState, useEffect} from 'react'
|
|
2
|
+
import React, {useMemo, useState, useEffect} from 'react'
|
|
3
3
|
import {DragDropContext, Droppable, Draggable} from 'react-beautiful-dnd'
|
|
4
|
-
import
|
|
4
|
+
import {usePaneRouter} from '@sanity/desk-tool'
|
|
5
5
|
import {Box, Card, useToast} from '@sanity/ui'
|
|
6
|
+
import sanityClient from 'part:@sanity/base/client'
|
|
6
7
|
|
|
7
8
|
import Document from './Document'
|
|
8
9
|
import {reorderDocuments} from './helpers/reorderDocuments'
|
|
@@ -20,24 +21,27 @@ const getItemStyle = (draggableStyle, itemIsUpdating) => ({
|
|
|
20
21
|
...draggableStyle,
|
|
21
22
|
})
|
|
22
23
|
|
|
23
|
-
const cardTone = (
|
|
24
|
+
const cardTone = (settings) => {
|
|
25
|
+
const {isDuplicate, isGhosting, isDragging, isSelected} = settings
|
|
26
|
+
|
|
24
27
|
if (isGhosting) return `transparent`
|
|
25
|
-
if (isDragging || isSelected)
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
+
if (isDragging || isSelected) return `primary`
|
|
29
|
+
if (isDuplicate) return `caution`
|
|
28
30
|
|
|
29
31
|
return undefined
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
export default function DraggableList({data,
|
|
34
|
+
export default function DraggableList({data, type, listIsUpdating, setListIsUpdating}) {
|
|
33
35
|
const toast = useToast()
|
|
36
|
+
const router = usePaneRouter()
|
|
37
|
+
const {navigateIntent} = router
|
|
34
38
|
|
|
35
39
|
// Maintains local state order before transaction completes
|
|
36
40
|
const [orderedData, setOrderedData] = useState(data)
|
|
37
41
|
|
|
38
42
|
// Update local state when documents change from an outside source
|
|
39
43
|
useEffect(() => {
|
|
40
|
-
if (!
|
|
44
|
+
if (!listIsUpdating) setOrderedData(data)
|
|
41
45
|
/* eslint-disable-next-line react-hooks/exhaustive-deps */
|
|
42
46
|
}, [data])
|
|
43
47
|
|
|
@@ -54,8 +58,11 @@ export default function DraggableList({data, isUpdating, setIsUpdating}) {
|
|
|
54
58
|
|
|
55
59
|
let updatedIds = []
|
|
56
60
|
|
|
57
|
-
// No
|
|
61
|
+
// No modifier keys pressed during click:
|
|
62
|
+
// - update selected to just this one
|
|
63
|
+
// - open document
|
|
58
64
|
if (!selectMultiple && !selectAdditional) {
|
|
65
|
+
navigateIntent('edit', {id: clickedId, type})
|
|
59
66
|
return setSelectedIds([clickedId])
|
|
60
67
|
}
|
|
61
68
|
|
|
@@ -94,7 +101,7 @@ export default function DraggableList({data, isUpdating, setIsUpdating}) {
|
|
|
94
101
|
.then((updated) => {
|
|
95
102
|
clearSelected()
|
|
96
103
|
setDraggingId(``)
|
|
97
|
-
|
|
104
|
+
setListIsUpdating(false)
|
|
98
105
|
toast.push({
|
|
99
106
|
title: `${
|
|
100
107
|
updated.results.length === 1 ? `1 Document` : `${updated.results.length} Documents`
|
|
@@ -102,19 +109,10 @@ export default function DraggableList({data, isUpdating, setIsUpdating}) {
|
|
|
102
109
|
status: `success`,
|
|
103
110
|
description: message,
|
|
104
111
|
})
|
|
105
|
-
|
|
106
|
-
// Another "I didn't write tests but I'm going to console.log my way to victory" piece of programming
|
|
107
|
-
// fetch(
|
|
108
|
-
// `https://i2v7h052.api.sanity.io/v2021-03-25/data/query/production?query=*%5B_type%20%3D%3D%20%22category%22%5D%7Corder(orderRank)%7B%0A%20%20title%2C%20orderRank%0A%7D`
|
|
109
|
-
// )
|
|
110
|
-
// .then((res) => res.json())
|
|
111
|
-
// .then((res) => {
|
|
112
|
-
// console.table(res.result.map((item) => item?.title).join(', '))
|
|
113
|
-
// })
|
|
114
112
|
})
|
|
115
113
|
.catch(() => {
|
|
116
114
|
setDraggingId(``)
|
|
117
|
-
|
|
115
|
+
setListIsUpdating(false)
|
|
118
116
|
toast.push({
|
|
119
117
|
title: `Reordering failed`,
|
|
120
118
|
status: `critical`,
|
|
@@ -140,7 +138,7 @@ export default function DraggableList({data, isUpdating, setIsUpdating}) {
|
|
|
140
138
|
if (!effectedIds?.length) return
|
|
141
139
|
|
|
142
140
|
// Update state to update styles + prevent data refetching
|
|
143
|
-
|
|
141
|
+
setListIsUpdating(true)
|
|
144
142
|
setSelectedIds(effectedIds)
|
|
145
143
|
|
|
146
144
|
const {newOrder, patches, message} = reorderDocuments({
|
|
@@ -196,6 +194,15 @@ export default function DraggableList({data, isUpdating, setIsUpdating}) {
|
|
|
196
194
|
}
|
|
197
195
|
}, [])
|
|
198
196
|
|
|
197
|
+
// Find all items with duplicate order field
|
|
198
|
+
const duplicateOrders = useMemo(() => {
|
|
199
|
+
if (!orderedData.length) return []
|
|
200
|
+
|
|
201
|
+
const orderField = orderedData.map((item) => item[ORDER_FIELD_NAME])
|
|
202
|
+
|
|
203
|
+
return orderField.filter((item, index) => orderField.indexOf(item) !== index)
|
|
204
|
+
}, [orderedData])
|
|
205
|
+
|
|
199
206
|
return (
|
|
200
207
|
<DragDropContext
|
|
201
208
|
onDragStart={handleDragStart}
|
|
@@ -212,11 +219,13 @@ export default function DraggableList({data, isUpdating, setIsUpdating}) {
|
|
|
212
219
|
// onClick={(event) => handleDraggableClick(event, provided, snapshot)}
|
|
213
220
|
>
|
|
214
221
|
{(innerProvided, innerSnapshot) => {
|
|
215
|
-
const
|
|
216
|
-
const
|
|
217
|
-
const isGhosting = !
|
|
218
|
-
const
|
|
219
|
-
const isDisabled = Boolean(!item
|
|
222
|
+
const isSelected = selectedIds.includes(item._id)
|
|
223
|
+
const isDragging = innerSnapshot.isDragging
|
|
224
|
+
const isGhosting = Boolean(!isDragging && draggingId && isSelected)
|
|
225
|
+
const isUpdating = isUpdating && isSelected
|
|
226
|
+
const isDisabled = Boolean(!item[ORDER_FIELD_NAME])
|
|
227
|
+
const isDuplicate = duplicateOrders.includes(item[ORDER_FIELD_NAME])
|
|
228
|
+
const tone = cardTone({isDuplicate, isGhosting, isDragging, isSelected})
|
|
220
229
|
|
|
221
230
|
return (
|
|
222
231
|
<div
|
|
@@ -226,19 +235,11 @@ export default function DraggableList({data, isUpdating, setIsUpdating}) {
|
|
|
226
235
|
style={
|
|
227
236
|
isDisabled
|
|
228
237
|
? {opacity: 0.2, pointerEvents: `none`}
|
|
229
|
-
: getItemStyle(
|
|
230
|
-
innerProvided.draggableProps.style,
|
|
231
|
-
itemIsUpdating,
|
|
232
|
-
isGhosting
|
|
233
|
-
)
|
|
238
|
+
: getItemStyle(innerProvided.draggableProps.style, isUpdating, isGhosting)
|
|
234
239
|
}
|
|
235
240
|
>
|
|
236
241
|
<Box paddingBottom={1}>
|
|
237
|
-
<Card
|
|
238
|
-
tone={cardTone(isGhosting, itemIsDragging, itemIsSelected)}
|
|
239
|
-
shadow={itemIsDragging ? `2` : undefined}
|
|
240
|
-
radius={2}
|
|
241
|
-
>
|
|
242
|
+
<Card tone={tone} shadow={isDragging ? `2` : undefined} radius={2}>
|
|
242
243
|
<Document
|
|
243
244
|
doc={item}
|
|
244
245
|
entities={orderedData}
|
|
@@ -269,6 +270,7 @@ DraggableList.propTypes = {
|
|
|
269
270
|
_id: PropTypes.string,
|
|
270
271
|
}).isRequired
|
|
271
272
|
).isRequired,
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
type: PropTypes.string.isRequired,
|
|
274
|
+
listIsUpdating: PropTypes.bool.isRequired,
|
|
275
|
+
setListIsUpdating: PropTypes.func.isRequired,
|
|
274
276
|
}
|
|
@@ -88,18 +88,6 @@ export const reorderDocuments = ({entities, selectedIds, source, destination, de
|
|
|
88
88
|
betweenRank = isMovingUp ? betweenRank.between(curRank) : betweenRank.between(nextRank)
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
// This data is not actually used by the plugin
|
|
92
|
-
// console.table(
|
|
93
|
-
// createManifest({
|
|
94
|
-
// entities,
|
|
95
|
-
// selectedItems,
|
|
96
|
-
// isMovingUp,
|
|
97
|
-
// curIndex,
|
|
98
|
-
// nextIndex,
|
|
99
|
-
// prevIndex,
|
|
100
|
-
// })
|
|
101
|
-
// )
|
|
102
|
-
|
|
103
91
|
return {
|
|
104
92
|
// The `all` array gets sorted by order field later anyway
|
|
105
93
|
// so that this probably isn't necessary ¯\_(ツ)_/¯
|