@manuscripts/style-guide 1.3.2-LEAN-2859-1 → 1.3.2-LEAN-2880-1

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.
Files changed (100) hide show
  1. package/dist/cjs/components/FileManager/ConfirmationPopUp.js +90 -0
  2. package/dist/cjs/components/FileManager/DragItemArea.js +28 -0
  3. package/dist/cjs/components/FileManager/FileManager.js +125 -14
  4. package/dist/cjs/components/FileManager/FileManagerProvider.js +7 -2
  5. package/dist/cjs/components/FileManager/{DragLayer.js → FileSectionItem/DragLayer.js} +10 -12
  6. package/dist/cjs/components/FileManager/FileSectionItem/DraggableFileSectionItem.js +76 -0
  7. package/dist/cjs/components/FileManager/FileSectionItem/FileInfo.js +115 -0
  8. package/dist/cjs/components/FileManager/FileSectionItem/FileSectionItem.js +95 -0
  9. package/dist/cjs/components/FileManager/FileSectionItem/FileSectionUploadItem.js +37 -0
  10. package/dist/cjs/components/FileManager/FileSectionItem/FileTypeIcon.js +53 -0
  11. package/dist/cjs/components/FileManager/FileSectionItem/ItemActions.js +92 -0
  12. package/dist/cjs/components/FileManager/FileSectionItem/ProgressBarUploadItem.js +120 -0
  13. package/dist/cjs/components/FileManager/FileSectionState.js +83 -0
  14. package/dist/cjs/components/FileManager/FilesSection.js +61 -0
  15. package/dist/cjs/components/FileManager/InlineFilesSection.js +123 -64
  16. package/dist/cjs/components/FileManager/ItemsAction.js +48 -0
  17. package/dist/cjs/components/FileManager/{Tooltip.js → TooltipDiv.js} +3 -8
  18. package/dist/cjs/components/FileManager/{FileUploader.js → UploadFileArea.js} +12 -19
  19. package/dist/cjs/components/FileManager/util.js +66 -29
  20. package/dist/cjs/components/icons/document-icon-with-dot.js +1 -1
  21. package/dist/cjs/hooks/use-files.js +43 -14
  22. package/dist/cjs/index.js +4 -3
  23. package/dist/cjs/lib/inlineFiles.js +92 -0
  24. package/dist/es/components/FileManager/ConfirmationPopUp.js +62 -0
  25. package/dist/es/components/FileManager/DragItemArea.js +21 -0
  26. package/dist/es/components/FileManager/FileManager.js +124 -16
  27. package/dist/es/components/FileManager/FileManagerProvider.js +8 -3
  28. package/dist/es/components/FileManager/{DragLayer.js → FileSectionItem/DragLayer.js} +10 -12
  29. package/dist/es/components/FileManager/FileSectionItem/DraggableFileSectionItem.js +46 -0
  30. package/dist/es/components/FileManager/FileSectionItem/FileInfo.js +85 -0
  31. package/dist/es/components/FileManager/FileSectionItem/FileSectionItem.js +88 -0
  32. package/dist/es/components/FileManager/FileSectionItem/FileSectionUploadItem.js +30 -0
  33. package/dist/es/components/FileManager/FileSectionItem/FileTypeIcon.js +46 -0
  34. package/dist/es/components/FileManager/FileSectionItem/ItemActions.js +65 -0
  35. package/dist/es/components/FileManager/FileSectionItem/ProgressBarUploadItem.js +113 -0
  36. package/dist/es/components/FileManager/FileSectionState.js +78 -0
  37. package/dist/es/components/FileManager/FilesSection.js +34 -0
  38. package/dist/es/components/FileManager/InlineFilesSection.js +124 -65
  39. package/dist/es/components/FileManager/ItemsAction.js +42 -0
  40. package/dist/es/components/FileManager/{Tooltip.js → TooltipDiv.js} +2 -7
  41. package/dist/es/components/FileManager/{FileUploader.js → UploadFileArea.js} +10 -17
  42. package/dist/es/components/FileManager/util.js +64 -28
  43. package/dist/es/components/icons/document-icon-with-dot.js +1 -1
  44. package/dist/es/hooks/use-files.js +40 -14
  45. package/dist/es/index.js +2 -2
  46. package/dist/es/lib/inlineFiles.js +90 -0
  47. package/dist/types/components/FileManager/ConfirmationPopUp.d.ts +12 -0
  48. package/dist/types/components/FileManager/DragItemArea.d.ts +4 -0
  49. package/dist/types/components/FileManager/FileManager.d.ts +8 -17
  50. package/dist/types/components/FileManager/FileManagerProvider.d.ts +18 -8
  51. package/dist/types/components/FileManager/FileSectionItem/DraggableFileSectionItem.d.ts +3 -0
  52. package/dist/types/components/FileManager/FileSectionItem/FileInfo.d.ts +19 -0
  53. package/dist/types/components/FileManager/FileSectionItem/FileSectionItem.d.ts +38 -0
  54. package/dist/types/components/FileManager/FileSectionItem/FileSectionUploadItem.d.ts +12 -0
  55. package/dist/types/components/FileManager/{FileTypeIcon.d.ts → FileSectionItem/FileTypeIcon.d.ts} +3 -2
  56. package/dist/types/components/FileManager/FileSectionItem/ItemActions.d.ts +21 -0
  57. package/dist/types/components/FileManager/FileSectionItem/ProgressBarUploadItem.d.ts +4 -0
  58. package/dist/types/components/FileManager/FileSectionState.d.ts +38 -0
  59. package/dist/types/components/FileManager/FilesSection.d.ts +12 -0
  60. package/dist/types/components/FileManager/InlineFilesSection.d.ts +19 -3
  61. package/dist/types/components/FileManager/ItemsAction.d.ts +4 -0
  62. package/dist/types/components/FileManager/TooltipDiv.d.ts +1 -0
  63. package/dist/types/components/FileManager/UploadFileArea.d.ts +9 -0
  64. package/dist/types/components/FileManager/util.d.ts +10 -3
  65. package/dist/types/hooks/use-files.d.ts +6 -5
  66. package/dist/types/index.d.ts +2 -2
  67. package/dist/types/lib/inlineFiles.d.ts +11 -0
  68. package/package.json +2 -2
  69. package/dist/cjs/components/FileManager/FileActions.js +0 -135
  70. package/dist/cjs/components/FileManager/FileContainer.js +0 -38
  71. package/dist/cjs/components/FileManager/FileCreatedDate.js +0 -25
  72. package/dist/cjs/components/FileManager/FileName.js +0 -27
  73. package/dist/cjs/components/FileManager/FileSectionAlert.js +0 -170
  74. package/dist/cjs/components/FileManager/FileTypeIcon.js +0 -31
  75. package/dist/cjs/components/FileManager/OtherFilesSection.js +0 -101
  76. package/dist/cjs/components/FileManager/SupplementsSection.js +0 -118
  77. package/dist/cjs/components/icons/corrupted-file-icon.js +0 -27
  78. package/dist/cjs/lib/files.js +0 -85
  79. package/dist/es/components/FileManager/FileActions.js +0 -105
  80. package/dist/es/components/FileManager/FileContainer.js +0 -32
  81. package/dist/es/components/FileManager/FileCreatedDate.js +0 -18
  82. package/dist/es/components/FileManager/FileName.js +0 -20
  83. package/dist/es/components/FileManager/FileSectionAlert.js +0 -163
  84. package/dist/es/components/FileManager/FileTypeIcon.js +0 -24
  85. package/dist/es/components/FileManager/OtherFilesSection.js +0 -74
  86. package/dist/es/components/FileManager/SupplementsSection.js +0 -91
  87. package/dist/es/components/icons/corrupted-file-icon.js +0 -22
  88. package/dist/es/lib/files.js +0 -79
  89. package/dist/types/components/FileManager/FileActions.d.ts +0 -19
  90. package/dist/types/components/FileManager/FileContainer.d.ts +0 -1
  91. package/dist/types/components/FileManager/FileCreatedDate.d.ts +0 -8
  92. package/dist/types/components/FileManager/FileName.d.ts +0 -6
  93. package/dist/types/components/FileManager/FileSectionAlert.d.ts +0 -13
  94. package/dist/types/components/FileManager/FileUploader.d.ts +0 -4
  95. package/dist/types/components/FileManager/OtherFilesSection.d.ts +0 -5
  96. package/dist/types/components/FileManager/SupplementsSection.d.ts +0 -5
  97. package/dist/types/components/FileManager/Tooltip.d.ts +0 -2
  98. package/dist/types/components/icons/corrupted-file-icon.d.ts +0 -19
  99. package/dist/types/lib/files.d.ts +0 -24
  100. /package/dist/types/components/FileManager/{DragLayer.d.ts → FileSectionItem/DragLayer.d.ts} +0 -0
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const json_schema_1 = require("@manuscripts/json-schema");
4
+ const transform_1 = require("@manuscripts/transform");
5
+ const util_1 = require("../components/FileManager/util");
6
+ const getFigureData = (element, modelMap, attachmentsMap) => {
7
+ const attachments = [];
8
+ element.containedObjectIDs.map((id) => {
9
+ const object = modelMap.get(id);
10
+ if (object && object.objectType === json_schema_1.ObjectTypes.Figure) {
11
+ const figure = object;
12
+ if (figure.src) {
13
+ const attachment = attachmentsMap.get(figure.src.replace('attachment:', ''));
14
+ if (attachment) {
15
+ attachment.modelId = id;
16
+ attachments.push(attachment);
17
+ }
18
+ }
19
+ }
20
+ });
21
+ return {
22
+ id: element._id,
23
+ attachments,
24
+ };
25
+ };
26
+ exports.default = (modelMap, attachments) => {
27
+ const files = [];
28
+ const attachmentsMap = new Map(attachments.map((attachment) => [attachment.id, attachment]));
29
+ const { graphicalAbstractFigureId, figureElement } = getAuxiliaryObjects(modelMap);
30
+ if (graphicalAbstractFigureId) {
31
+ const element = modelMap.get(graphicalAbstractFigureId);
32
+ files.unshift(Object.assign(Object.assign({}, getFigureData(element, modelMap, attachmentsMap)), { label: `Graphical Abstract`, type: util_1.FileType.GraphicalAbstract }));
33
+ }
34
+ figureElement.map((id, index) => {
35
+ const element = modelMap.get(id);
36
+ files.push(Object.assign(Object.assign({}, getFigureData(element, modelMap, attachmentsMap)), { label: `Figure ${index + 1}`, type: util_1.FileType.Figure }));
37
+ });
38
+ return files;
39
+ };
40
+ const getAuxiliaryObjects = (modelMap) => {
41
+ var _a, _b;
42
+ let graphicalAbstractFigureId, figureElementIds = [];
43
+ const tableElementIds = [], orderObjects = {};
44
+ for (const model of modelMap.values()) {
45
+ switch (model.objectType) {
46
+ case json_schema_1.ObjectTypes.Section: {
47
+ const section = model;
48
+ if (section.category === 'MPSectionCategory:abstract-graphical') {
49
+ graphicalAbstractFigureId = (_a = section.elementIDs) === null || _a === void 0 ? void 0 : _a.find((id) => {
50
+ const obj = modelMap.get(id);
51
+ return obj && (0, transform_1.hasObjectType)(json_schema_1.ObjectTypes.FigureElement)(obj);
52
+ });
53
+ }
54
+ else {
55
+ (_b = section.elementIDs) === null || _b === void 0 ? void 0 : _b.map((elementId) => {
56
+ const element = modelMap.get(elementId);
57
+ if (!element) {
58
+ return;
59
+ }
60
+ switch (element.objectType) {
61
+ case json_schema_1.ObjectTypes.FigureElement:
62
+ figureElementIds.push(element._id);
63
+ break;
64
+ case json_schema_1.ObjectTypes.TableElement:
65
+ tableElementIds.push(element._id);
66
+ break;
67
+ }
68
+ });
69
+ }
70
+ break;
71
+ }
72
+ case json_schema_1.ObjectTypes.ElementsOrder: {
73
+ const elementsOrder = model;
74
+ orderObjects[elementsOrder.elementType] = elementsOrder;
75
+ }
76
+ }
77
+ }
78
+ if (graphicalAbstractFigureId) {
79
+ figureElementIds = figureElementIds.filter((id) => id != graphicalAbstractFigureId);
80
+ }
81
+ return {
82
+ graphicalAbstractFigureId,
83
+ figureElement: sortAuxiliaryObject(figureElementIds, orderObjects[json_schema_1.ObjectTypes.FigureElement]),
84
+ tableElement: sortAuxiliaryObject(tableElementIds, orderObjects[json_schema_1.ObjectTypes.TableElement]),
85
+ };
86
+ };
87
+ const sortAuxiliaryObject = (auxiliaryObjectIds, orderObject) => {
88
+ if (!orderObject) {
89
+ return auxiliaryObjectIds;
90
+ }
91
+ return auxiliaryObjectIds.sort((a, b) => orderObject.elements.indexOf(a) - orderObject.elements.indexOf(b));
92
+ };
@@ -0,0 +1,62 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { ObjectTypes } from '@manuscripts/json-schema';
11
+ import { buildSupplementaryMaterial, getModelsByType, } from '@manuscripts/transform';
12
+ import React, { useCallback, useContext } from 'react';
13
+ import { Category, Dialog } from '../Dialog';
14
+ import { FileManagerContext } from './FileManagerProvider';
15
+ import { actions } from './FileSectionState';
16
+ import { FileSectionType } from './util';
17
+ export const ConfirmationPopUp = ({ popupHeader, popUpMessage, isOpen, handleClose, handleMove }) => {
18
+ return (React.createElement(Dialog, { isOpen: isOpen, category: Category.confirmation, header: popupHeader, message: popUpMessage, actions: {
19
+ primary: {
20
+ action: handleMove,
21
+ title: 'Move',
22
+ },
23
+ secondary: {
24
+ action: handleClose,
25
+ title: 'Cancel',
26
+ },
27
+ } }));
28
+ };
29
+ export const MoveFilePopup = ({ dispatch, }) => {
30
+ const { moveFilePopup: { isOpen, fileSection, attachmentId }, saveModel, deleteModel, modelMap, getAttachments, setMoveFilePopupData, } = useContext(FileManagerContext);
31
+ const isSupplement = fileSection === FileSectionType.Supplements;
32
+ const message = {
33
+ popupHeader: `Are you sure you want to move this file to “${(!isSupplement && 'Supplements') || 'Other files'}”?`,
34
+ popUpMessage: `The file will be removed from the “${(isSupplement && 'Supplements') || 'Other files'}” and added to “${(!isSupplement && 'Supplements') || 'Other files'}”.`,
35
+ };
36
+ const closePopup = useCallback(() => setMoveFilePopupData({
37
+ isOpen: false,
38
+ fileSection: fileSection,
39
+ }), [fileSection, setMoveFilePopupData]);
40
+ const showSuccessMessage = useCallback(() => dispatch(actions.HANDLE_SUCCESS_MESSAGE(`File moved to ${(isSupplement && 'Other files') || 'Supplements'}.`, fileSection)), [dispatch, fileSection, isSupplement]);
41
+ const moveToSupplement = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
42
+ closePopup();
43
+ const attachment = getAttachments().find(({ id }) => id === attachmentId);
44
+ if (!attachment) {
45
+ return;
46
+ }
47
+ const model = buildSupplementaryMaterial(attachment.name, `attachment:${attachment.id}`);
48
+ yield saveModel(Object.assign(Object.assign({}, model), { title: attachment.name, href: `attachment:${attachment.id}` }));
49
+ showSuccessMessage();
50
+ }), [getAttachments, saveModel, showSuccessMessage, closePopup, attachmentId]);
51
+ const moveSupplementToOtherFiles = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
52
+ closePopup();
53
+ const model = getModelsByType(modelMap, ObjectTypes.Supplement).find(({ href }) => (href === null || href === void 0 ? void 0 : href.replace('attachment:', '')) === attachmentId);
54
+ if (!model) {
55
+ return;
56
+ }
57
+ yield deleteModel(model._id);
58
+ showSuccessMessage();
59
+ }), [attachmentId, closePopup, deleteModel, modelMap, showSuccessMessage]);
60
+ return (React.createElement(React.Fragment, null,
61
+ React.createElement(ConfirmationPopUp, Object.assign({ isOpen: isOpen }, message, { handleMove: () => (!isSupplement && moveToSupplement()) || moveSupplementToOtherFiles(), handleClose: closePopup }))));
62
+ };
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import DragAndDropFileIcon from '../icons/drag-drop-file-icon';
4
+ export const DragItemArea = ({ text }) => {
5
+ return (React.createElement(Container, null,
6
+ React.createElement("div", null,
7
+ React.createElement(DragAndDropFileIcon, null)),
8
+ text));
9
+ };
10
+ const Container = styled.div `
11
+ display: flex;
12
+ flex-direction: column;
13
+ align-items: center;
14
+ justify-content: center;
15
+ font-size: 14px;
16
+ line-height: 24px;
17
+ font-family: ${(props) => props.theme.font.family.Lato};
18
+ color: ${(props) => props.theme.colors.text.onLight};
19
+ padding: 32px 0;
20
+ text-align: center;
21
+ `;
@@ -1,33 +1,141 @@
1
- import React, { createContext } from 'react';
2
- import { useFiles } from '../../index';
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { ObjectTypes, } from '@manuscripts/json-schema';
11
+ import { buildSupplementaryMaterial, getModelsByType, } from '@manuscripts/transform';
12
+ import React, { createContext, useCallback, useReducer } from 'react';
13
+ import ReactTooltip from 'react-tooltip';
14
+ import { FileSectionType, useFiles } from '../../index';
3
15
  import { InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabPanels, InspectorTabs, } from '../Inspector';
4
16
  import { InspectorSection } from '../InspectorSection';
5
- import { DragLayer } from './DragLayer';
17
+ import { MoveFilePopup } from './ConfirmationPopUp';
6
18
  import { FileManagerProvider } from './FileManagerProvider';
19
+ import { DraggableFileSectionItem } from './FileSectionItem/DraggableFileSectionItem';
20
+ import { DragLayer } from './FileSectionItem/DragLayer';
21
+ import { FileSectionItem, } from './FileSectionItem/FileSectionItem';
22
+ import { actions, getInitialState, reducer } from './FileSectionState';
23
+ import { FilesSection } from './FilesSection';
7
24
  import { InlineFilesSection } from './InlineFilesSection';
8
- import { OtherFilesSection } from './OtherFilesSection';
9
- import { SupplementsSection } from './SupplementsSection';
10
- import { Tooltip } from './Tooltip';
25
+ import { TooltipDiv } from './TooltipDiv';
26
+ import { generateAttachmentsTitles } from './util';
11
27
  export const PermissionsContext = createContext(null);
12
- export const FileManager = ({ files, fileManagement, modelMap, saveModel, deleteModel, enableDragAndDrop, can, }) => {
13
- const { inlineFiles, supplements, otherFiles } = useFiles(modelMap, files);
14
- return (React.createElement(FileManagerProvider, { saveModel: saveModel, deleteModel: deleteModel, modelMap: modelMap, fileManagement: fileManagement },
28
+ export const FileManager = ({ modelMap, saveModel, deleteModel, enableDragAndDrop, can, fileManagement: { getAttachments, replace, upload }, addAttachmentToState, }) => {
29
+ const [state, dispatch] = useReducer(reducer, getInitialState());
30
+ const handleReplaceFile = useCallback((attachmentId, name, file) => __awaiter(void 0, void 0, void 0, function* () {
31
+ dispatch(actions.HANDLE_UPLOAD_ACTION());
32
+ const res = yield replace(attachmentId, name, file);
33
+ dispatch(actions.HANDLE_FINISH_UPLOAD());
34
+ if (res) {
35
+ dispatch(actions.HANDLE_SUCCESS_MESSAGE('File uploaded successfully.'));
36
+ }
37
+ return res;
38
+ }), [replace]);
39
+ const handleUploadFile = useCallback((file) => __awaiter(void 0, void 0, void 0, function* () {
40
+ dispatch(actions.HANDLE_UPLOAD_ACTION());
41
+ const res = yield upload(file);
42
+ dispatch(actions.HANDLE_FINISH_UPLOAD());
43
+ if (res) {
44
+ dispatch(actions.HANDLE_SUCCESS_MESSAGE('File uploaded successfully.', FileSectionType.OtherFile));
45
+ }
46
+ return res;
47
+ }), [upload]);
48
+ const handleUploadFileWithSupplement = useCallback((file) => __awaiter(void 0, void 0, void 0, function* () {
49
+ dispatch(actions.HANDLE_UPLOAD_ACTION());
50
+ const response = yield upload(file);
51
+ if (typeof response === 'object') {
52
+ const { id, name } = response;
53
+ yield saveModel(buildSupplementaryMaterial(name, `attachment:${id}`));
54
+ }
55
+ dispatch(actions.HANDLE_FINISH_UPLOAD());
56
+ if (response) {
57
+ dispatch(actions.HANDLE_SUCCESS_MESSAGE('File uploaded successfully.', FileSectionType.Supplements));
58
+ }
59
+ return response;
60
+ }), [upload, saveModel]);
61
+ const handleSupplementReplace = useCallback((attachment, oldAttachmentId) => __awaiter(void 0, void 0, void 0, function* () {
62
+ const model = getModelsByType(modelMap, ObjectTypes.Supplement).find(({ href }) => (href === null || href === void 0 ? void 0 : href.replace('attachment:', '')) === oldAttachmentId);
63
+ yield saveModel(Object.assign(Object.assign({}, model), { title: attachment.name, href: `attachment:${attachment.id}` }));
64
+ }), [modelMap, saveModel]);
65
+ const handleDownload = useCallback((url) => {
66
+ window.location.assign(url);
67
+ }, []);
68
+ const handleUpdateInline = useCallback((modelId, attachment) => __awaiter(void 0, void 0, void 0, function* () {
69
+ const figureModel = modelMap.get(modelId);
70
+ figureModel.src = `attachment:${attachment.id}`;
71
+ if (addAttachmentToState) {
72
+ addAttachmentToState(Object.assign({}, attachment));
73
+ }
74
+ yield saveModel(figureModel);
75
+ }), [modelMap, saveModel, addAttachmentToState]);
76
+ const attachments = getAttachments();
77
+ const { otherFiles, supplementFiles, inlineFiles } = useFiles(modelMap, attachments);
78
+ const handleDetachFile = (attachmentId, modelId) => {
79
+ const model = modelMap.get(modelId);
80
+ if (model) {
81
+ saveModel(Object.assign(Object.assign({}, model), { src: '' }));
82
+ }
83
+ };
84
+ const getFileSectionExternalFile = (fileSection) => {
85
+ const isSupplementOrOtherFilesTab = fileSection === FileSectionType.Supplements ||
86
+ fileSection === FileSectionType.OtherFile;
87
+ const isOtherFilesTab = fileSection === FileSectionType.OtherFile;
88
+ const itemsData = (fileSection === FileSectionType.Supplements && supplementFiles) ||
89
+ otherFiles;
90
+ const itemsDataWithTitle = generateAttachmentsTitles(itemsData, fileSection);
91
+ const filesItems = itemsDataWithTitle.map((element) => {
92
+ const itemProps = {
93
+ fileSection,
94
+ externalFile: element.externalFile,
95
+ title: element.title,
96
+ showAttachmentName: isSupplementOrOtherFilesTab,
97
+ showReplaceAction: !isOtherFilesTab,
98
+ handleDownload,
99
+ handleReplace: handleReplaceFile,
100
+ handleSupplementReplace,
101
+ dispatch: dispatch,
102
+ };
103
+ if (enableDragAndDrop && isSupplementOrOtherFilesTab) {
104
+ return (React.createElement(DraggableFileSectionItem, Object.assign({}, itemProps, { key: element.externalFile.id })));
105
+ }
106
+ else {
107
+ return (React.createElement(FileSectionItem, Object.assign({}, itemProps, { key: element.externalFile.id, isEditor: enableDragAndDrop })));
108
+ }
109
+ });
110
+ return filesItems;
111
+ };
112
+ return (React.createElement(FileManagerProvider, { saveModel: saveModel, modelMap: modelMap, deleteModel: deleteModel, getAttachments: getAttachments },
15
113
  React.createElement(DragLayer, null),
16
114
  React.createElement(PermissionsContext.Provider, { value: can },
17
- React.createElement(InspectorSection, { title: 'Files', contentStyles: { margin: '24px 16px' } },
115
+ React.createElement(InspectorSection, { title: 'Files', contentStyles: { margin: '24px' } },
18
116
  React.createElement(InspectorTabs, { defaultIndex: 0, style: { overflow: 'visible' } },
19
117
  React.createElement(InspectorTabList, null,
20
118
  React.createElement(InspectorTab, { "data-for": "inline", "data-tip": true }, "Inline files"),
21
- React.createElement(Tooltip, { id: "inline", place: "bottom", offset: { bottom: -11 }, effect: "solid", className: "tooltip" }, "Files that can be found inline in the manuscript."),
119
+ React.createElement(TooltipDiv, null,
120
+ React.createElement(ReactTooltip, { id: "inline", place: "bottom", offset: { bottom: -11 }, effect: "solid", className: "tooltip" },
121
+ React.createElement("div", null,
122
+ "Files that can be found inline ",
123
+ React.createElement("br", null),
124
+ " in the manuscript."))),
22
125
  React.createElement(InspectorTab, { "data-for": "supplements", "data-tip": true }, "Supplements"),
23
- React.createElement(Tooltip, { id: "supplements", place: "bottom", offset: { bottom: -11 }, effect: "solid", className: "tooltip" }, "Files that were marked as supplements."),
126
+ React.createElement(TooltipDiv, null,
127
+ React.createElement(ReactTooltip, { id: "supplements", place: "bottom", offset: { bottom: -11 }, effect: "solid", className: "tooltip" },
128
+ React.createElement("div", null, "Files that were marked as supplementaries."))),
24
129
  React.createElement(InspectorTab, { "data-for": "other", "data-tip": true }, "Other files"),
25
- React.createElement(Tooltip, { id: "other", place: "bottom", offset: { bottom: -11 }, effect: "solid", className: "tooltip" }, "Files excluded from the final submission.")),
130
+ React.createElement(TooltipDiv, null,
131
+ React.createElement(ReactTooltip, { id: "other", place: "bottom", offset: { bottom: -11 }, effect: "solid", className: "tooltip" },
132
+ React.createElement("div", null, "Files excluded from the final submission.")))),
26
133
  React.createElement(InspectorTabPanels, { style: { overflowY: 'visible', position: 'relative' } },
27
134
  React.createElement(InspectorTabPanel, null,
28
- React.createElement(InlineFilesSection, { elements: inlineFiles, isEditor: enableDragAndDrop })),
135
+ React.createElement(InlineFilesSection, { inlineFiles: inlineFiles, handleReplace: replace, handleDownload: handleDownload, handleUpdateInline: handleUpdateInline, handleDetachFile: handleDetachFile, isEditor: enableDragAndDrop, dispatch: dispatch })),
29
136
  React.createElement(InspectorTabPanel, null,
30
- React.createElement(SupplementsSection, { supplements: supplements })),
137
+ React.createElement(FilesSection, { enableDragAndDrop: enableDragAndDrop, handleUpload: handleUploadFileWithSupplement, fileSection: FileSectionType.Supplements, filesItem: getFileSectionExternalFile(FileSectionType.Supplements), state: state, dispatch: dispatch })),
31
138
  React.createElement(InspectorTabPanel, null,
32
- React.createElement(OtherFilesSection, { files: otherFiles }))))))));
139
+ React.createElement(FilesSection, { enableDragAndDrop: enableDragAndDrop, handleUpload: handleUploadFile, fileSection: FileSectionType.OtherFile, filesItem: getFileSectionExternalFile(FileSectionType.OtherFile), state: state, dispatch: dispatch }))))),
140
+ React.createElement(MoveFilePopup, { dispatch: dispatch }))));
33
141
  };
@@ -1,12 +1,17 @@
1
- import React, { createContext } from 'react';
1
+ import React, { createContext, useState } from 'react';
2
2
  export const FileManagerContext = createContext({
3
3
  saveModel: () => '',
4
+ moveFilePopup: { isOpen: false },
5
+ setMoveFilePopupData: () => '',
4
6
  });
5
- export const FileManagerProvider = ({ children, saveModel, deleteModel, modelMap, fileManagement }) => {
7
+ export const FileManagerProvider = ({ children, saveModel, deleteModel, modelMap, getAttachments }) => {
8
+ const [moveFilePopup, setMoveFilePopupData] = useState({ isOpen: false });
6
9
  return (React.createElement(FileManagerContext.Provider, { value: {
7
10
  saveModel,
8
11
  deleteModel,
9
12
  modelMap,
10
- fileManagement,
13
+ getAttachments,
14
+ moveFilePopup,
15
+ setMoveFilePopupData,
11
16
  } }, children));
12
17
  };
@@ -1,9 +1,7 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { useDragLayer } from 'react-dnd';
3
3
  import styled from 'styled-components';
4
- import { FileContainer } from './FileContainer';
5
- import { FileCreatedDate } from './FileCreatedDate';
6
- import { FileName } from './FileName';
4
+ import { FileSectionItem } from './FileSectionItem';
7
5
  function getItemStyles(initialOffset, currentOffset) {
8
6
  if (!initialOffset || !currentOffset) {
9
7
  return {
@@ -27,10 +25,8 @@ export const DragLayer = () => {
27
25
  }));
28
26
  const renderItem = useCallback(() => {
29
27
  switch (itemType) {
30
- case 'file':
31
- return (React.createElement(DraggableFileContainer, null,
32
- React.createElement(FileName, { file: item.file }),
33
- item.file.createdDate && React.createElement(FileCreatedDate, { file: item.file })));
28
+ case 'FileSectionItem':
29
+ return (React.createElement(CustomFileSectionItem, { title: item.title, externalFile: item.externalFile, showAttachmentName: item.showAttachmentName, withDot: item.withDot, showSecondaryActions: false, style: { width: item.width } }));
34
30
  default:
35
31
  return null;
36
32
  }
@@ -38,7 +34,8 @@ export const DragLayer = () => {
38
34
  if (!isDragging) {
39
35
  return null;
40
36
  }
41
- return (React.createElement(Container, { style: getItemStyles(initialOffset, currentOffset) }, renderItem()));
37
+ return (React.createElement(Container, null,
38
+ React.createElement("div", { style: getItemStyles(initialOffset, currentOffset) }, renderItem())));
42
39
  };
43
40
  const Container = styled.div `
44
41
  position: fixed;
@@ -46,12 +43,13 @@ const Container = styled.div `
46
43
  z-index: 999;
47
44
  left: 0;
48
45
  top: 0;
49
- max-width: 400px;
46
+ width: 100%;
47
+ height: 100%;
50
48
  `;
51
- const DraggableFileContainer = styled(FileContainer) `
49
+ const CustomFileSectionItem = React.memo(styled(FileSectionItem) `
52
50
  padding: 16px 32px;
53
51
  background: #f2fbfc;
54
52
  border: 1px solid #bce7f6;
55
- box-shadow: 0 4px 9px rgba(0, 0, 0, 0.3);
53
+ box-shadow: 0px 4px 9px rgba(0, 0, 0, 0.3);
56
54
  border-radius: 6px;
57
- `;
55
+ `);
@@ -0,0 +1,46 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { useDrag } from 'react-dnd';
3
+ import { getEmptyImage } from 'react-dnd-html5-backend';
4
+ import styled from 'styled-components';
5
+ import { FileSectionItem } from './FileSectionItem';
6
+ const itemPlaceHolderDraggingStyle = {
7
+ background: '#FAFAFA',
8
+ borderRadius: '6px',
9
+ height: '104px',
10
+ };
11
+ const draggingItemStyle = {
12
+ opacity: 0,
13
+ height: 0,
14
+ };
15
+ export const DraggableFileSectionItem = (props) => {
16
+ const [draggingItemWidth, setDraggingItemWidth] = useState('100%');
17
+ const itemPlaceholderRef = useRef();
18
+ const [{ isDragging }, dragRef, preview] = useDrag({
19
+ item: {
20
+ id: props.title,
21
+ title: props.title,
22
+ externalFile: props.externalFile,
23
+ showAttachmentName: props.showAttachmentName,
24
+ width: draggingItemWidth,
25
+ type: 'FileSectionItem',
26
+ },
27
+ collect: (monitor) => ({
28
+ isDragging: monitor.isDragging(),
29
+ }),
30
+ });
31
+ useEffect(() => {
32
+ if (itemPlaceholderRef && itemPlaceholderRef.current) {
33
+ setDraggingItemWidth(itemPlaceholderRef.current.offsetWidth + 'px');
34
+ }
35
+ }, []);
36
+ useEffect(() => {
37
+ preview(getEmptyImage());
38
+ }, [preview]);
39
+ return (React.createElement(ItemDraggingPlaceholderContainer, { style: isDragging ? itemPlaceHolderDraggingStyle : {}, ref: itemPlaceholderRef },
40
+ React.createElement(FileSectionItem, Object.assign({ style: isDragging ? draggingItemStyle : {}, dragRef: dragRef }, props))));
41
+ };
42
+ const ItemDraggingPlaceholderContainer = styled.div `
43
+ background: ${(props) => props.theme.colors.background.primary};
44
+ width: 100%;
45
+ position: relative;
46
+ `;
@@ -0,0 +1,85 @@
1
+ import { format } from 'date-fns';
2
+ import React, { useContext } from 'react';
3
+ import ReactTooltip from 'react-tooltip';
4
+ import styled from 'styled-components';
5
+ import { PermissionsContext } from '../FileManager';
6
+ import { TooltipDiv } from '../TooltipDiv';
7
+ export const FileInfo = ({ showAttachmentName, title, fileAttachmentName, fileExtension, attachmentId, dispatch, fileCreatedDate, }) => {
8
+ const fileName = fileAttachmentName.substring(0, fileAttachmentName.lastIndexOf('.'));
9
+ const can = useContext(PermissionsContext);
10
+ return (React.createElement(FileInfoContainer, null,
11
+ React.createElement(FileNameTitleContainer, null,
12
+ React.createElement(FileTitle, null,
13
+ !showAttachmentName ? fileName : title,
14
+ showAttachmentName && ':'),
15
+ showAttachmentName && (React.createElement(FileNameContainer, null,
16
+ React.createElement(FileName, null, fileName),
17
+ React.createElement("div", null,
18
+ ".",
19
+ fileExtension))),
20
+ fileCreatedDate && (React.createElement(FileDateContainer, { "data-tip": "tooltip-content" },
21
+ React.createElement(FileDate, null, format(new Date(fileCreatedDate), 'M/d/yy, HH:mm')),
22
+ React.createElement(TooltipDiv, null,
23
+ React.createElement(ReactTooltip, { place: "bottom", offset: { top: 0 }, effect: "solid", className: "tooltip" },
24
+ React.createElement("div", null, "File uploaded"))))))));
25
+ };
26
+ export const FileDateContainer = styled.div `
27
+ line-height: 20px;
28
+ overflow: hidden;
29
+ width: 100%;
30
+ display: none;
31
+ justify-content: flex-end;
32
+ `;
33
+ export const FileInfoContainer = styled.div `
34
+ margin-left: 8px;
35
+ overflow: hidden;
36
+ display: flex;
37
+ flex-direction: column;
38
+ justify-content: center;
39
+ align-items: start;
40
+ width: 100%;
41
+
42
+ &:hover ${FileDateContainer} {
43
+ display: flex;
44
+ }
45
+ `;
46
+ export const FileNameTitleContainer = styled.div `
47
+ display: flex;
48
+ width: 100%;
49
+ align-items: baseline;
50
+ `;
51
+ export const FileTitle = styled.div `
52
+ color: ${(props) => props.theme.colors.text.primary};
53
+ font-weight: bold;
54
+ font-size: 16px;
55
+ line-height: 20px;
56
+ margin-right: 4px;
57
+ white-space: nowrap;
58
+ `;
59
+ export const FileNameContainer = styled.div `
60
+ display: flex;
61
+ color: ${(props) => props.theme.colors.text.primary};
62
+ font-weight: normal;
63
+ font-size: 16px;
64
+ line-height: 20px;
65
+ overflow: hidden;
66
+ width: 100%;
67
+ `;
68
+ export const FileName = styled.div `
69
+ text-overflow: ellipsis;
70
+ white-space: nowrap;
71
+ overflow: hidden;
72
+ width: 50px;
73
+ `;
74
+ export const FileDate = styled.div `
75
+ font-size: font-size: ${(props) => props.theme.font.size.small};
76
+ `;
77
+ export const FileDescription = styled.div `
78
+ color: ${(props) => props.theme.colors.text.secondary};
79
+ font-size: 14px;
80
+ line-height: 20px;
81
+ text-overflow: ellipsis;
82
+ white-space: nowrap;
83
+ overflow: hidden;
84
+ width: 100%;
85
+ `;
@@ -0,0 +1,88 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { useDropdown } from '../../../hooks/use-dropdown';
4
+ import { DropdownContainer } from '../../Dropdown';
5
+ import { CloseOIcon } from '../../icons/';
6
+ import DotsIcon from '../../icons/dots-icon';
7
+ import { FileInfo } from './FileInfo';
8
+ import { FileTypeIcon } from './FileTypeIcon';
9
+ import { ItemActions } from './ItemActions';
10
+ export const FileSectionItem = ({ fileSection, externalFile, title, showAttachmentName = false, showReplaceAction = true, handleDownload, handleReplace, handleSupplementReplace, dispatch, dragRef, className, style, onClose, isEditor, }) => {
11
+ const { isOpen, toggleOpen, wrapperRef } = useDropdown();
12
+ const fileExtension = externalFile.name.substring(externalFile.name.lastIndexOf('.') + 1);
13
+ const isMainManuscript = externalFile.type.label === 'main-manuscript';
14
+ const isSelected = externalFile.id == window.location.hash.substr(1);
15
+ return (React.createElement(Item, { ref: dragRef, className: className, style: style },
16
+ React.createElement(ItemContainer, { onClick: () => {
17
+ window.location.hash =
18
+ isEditor && !isSelected ? `#${externalFile.id}` : '#';
19
+ if (isSelected) {
20
+ window.location.hash = `#${externalFile.id}`;
21
+ }
22
+ } },
23
+ React.createElement(FileTypeIcon, { withDot: isMainManuscript, fileExtension: fileExtension, alt: externalFile.name }),
24
+ React.createElement(FileInfo, { fileExtension: fileExtension, fileCreatedDate: externalFile.createdDate, showAttachmentName: showAttachmentName, fileAttachmentName: externalFile.name, title: title, attachmentId: externalFile.id, dispatch: dispatch })),
25
+ onClose && (React.createElement(IconCloseButton, { onClick: (e) => {
26
+ e.preventDefault();
27
+ onClose();
28
+ } },
29
+ React.createElement(CloseOIcon, { color: '#6E6E6E' }))),
30
+ handleDownload && handleReplace && (React.createElement(DropdownContainer, { ref: wrapperRef },
31
+ React.createElement(ActionsIcon, { onClick: toggleOpen, type: "button", "aria-label": "Download or Replace", "aria-pressed": isOpen },
32
+ React.createElement(DotsIcon, null)),
33
+ isOpen && (React.createElement(ItemActions, { fileSection: fileSection, isMainManuscript: isMainManuscript, replaceAttachmentHandler: handleReplace, showReplaceAction: showReplaceAction, downloadAttachmentHandler: handleDownload, handleSupplementReplace: handleSupplementReplace, attachmentId: externalFile.id, fileName: externalFile.name, publicUrl: externalFile.link, hideActionList: toggleOpen, dispatch: dispatch }))))));
34
+ };
35
+ const IconCloseButton = styled.button `
36
+ border: none;
37
+ background: transparent;
38
+ cursor: pointer;
39
+ padding: 0 8px;
40
+ align-self: flex-start;
41
+ &:hover {
42
+ opacity: 0.5;
43
+ }
44
+ `;
45
+ export const ActionsIcon = styled.button `
46
+ visibility: hidden;
47
+ border: none;
48
+ background: transparent;
49
+ cursor: pointer;
50
+ padding: 0 8px;
51
+ &:focus {
52
+ outline: none;
53
+ }
54
+ &:hover svg circle {
55
+ fill: #1a9bc7;
56
+ }
57
+ `;
58
+ export const Item = styled.div `
59
+ display: flex;
60
+ font-family: ${(props) => props.theme.font.family.Lato};
61
+ padding: 20px 15px;
62
+ cursor: pointer;
63
+ box-sizing: border-box;
64
+ width: 100%;
65
+ position: relative;
66
+
67
+ &:hover,
68
+ &:focus {
69
+ background: #f2fbfc;
70
+ }
71
+
72
+ &:hover ${ActionsIcon} {
73
+ visibility: visible;
74
+ }
75
+
76
+ ${DropdownContainer} {
77
+ position: absolute;
78
+ top: 24px;
79
+ right: 0;
80
+ margin-right: 8px;
81
+ }
82
+ `;
83
+ export const ItemContainer = styled.div `
84
+ display: flex;
85
+ min-width: calc(100% - 8px);
86
+ padding-right: 4px;
87
+ box-sizing: border-box;
88
+ `;