@manuscripts/body-editor 2.7.7 → 2.7.8-LEAN-4213.0
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/dist/cjs/components/affiliations/AffiliationForm.js +106 -0
- package/dist/cjs/components/affiliations/AffiliationItem.js +112 -0
- package/dist/cjs/components/affiliations/AffiliationList.js +47 -0
- package/dist/cjs/components/affiliations/AffiliationsModal.js +418 -0
- package/dist/cjs/components/authors/AuthorDetailsForm.js +10 -2
- package/dist/cjs/components/authors/AuthorList.js +1 -1
- package/dist/cjs/components/authors/AuthorsModal.js +184 -80
- package/dist/cjs/components/authors/DraggableAuthor.js +0 -3
- package/dist/cjs/components/dialog/ConfirmationDialog.js +86 -0
- package/dist/cjs/components/form/FormFooter.js +32 -0
- package/dist/cjs/components/form/FormPlaceholder.js +43 -0
- package/dist/cjs/components/{authors/AuthorActions.js → form/ModalFormActions.js} +12 -11
- package/dist/cjs/plugins/affiliations.js +5 -38
- package/dist/cjs/useEditor.js +0 -1
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/affiliations.js +82 -14
- package/dist/cjs/views/contributors.js +1 -9
- package/dist/es/components/affiliations/AffiliationForm.js +76 -0
- package/dist/es/components/affiliations/AffiliationItem.js +82 -0
- package/dist/es/components/affiliations/AffiliationList.js +40 -0
- package/dist/es/components/affiliations/AffiliationsModal.js +388 -0
- package/dist/es/components/authors/AuthorDetailsForm.js +11 -3
- package/dist/es/components/authors/AuthorList.js +1 -1
- package/dist/es/components/authors/AuthorsModal.js +183 -79
- package/dist/es/components/authors/DraggableAuthor.js +0 -3
- package/dist/es/components/dialog/ConfirmationDialog.js +79 -0
- package/dist/es/components/form/FormFooter.js +27 -0
- package/dist/es/components/form/FormPlaceholder.js +36 -0
- package/dist/es/components/{authors/AuthorActions.js → form/ModalFormActions.js} +10 -9
- package/dist/es/plugins/affiliations.js +6 -39
- package/dist/es/useEditor.js +0 -1
- package/dist/es/versions.js +1 -1
- package/dist/es/views/affiliations.js +85 -17
- package/dist/es/views/contributors.js +1 -9
- package/dist/types/components/{authors → affiliations}/AffiliationForm.d.ts +5 -0
- package/dist/types/components/affiliations/AffiliationItem.d.ts +10 -0
- package/dist/types/components/affiliations/AffiliationList.d.ts +26 -0
- package/dist/types/components/affiliations/AffiliationsModal.d.ts +11 -0
- package/dist/types/components/authors/AuthorDetailsForm.d.ts +1 -0
- package/dist/types/components/authors/AuthorsModal.d.ts +2 -1
- package/dist/types/components/dialog/ConfirmationDialog.d.ts +15 -0
- package/dist/types/components/form/FormFooter.d.ts +5 -0
- package/dist/types/components/form/FormPlaceholder.d.ts +9 -0
- package/dist/types/components/{authors/AuthorActions.d.ts → form/ModalFormActions.d.ts} +4 -3
- package/dist/types/lib/dnd.d.ts +1 -1
- package/dist/types/selection.d.ts +7 -1
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/affiliations.d.ts +11 -0
- package/dist/types/views/contributors.d.ts +0 -1
- package/package.json +2 -2
- package/styles/AdvancedEditor.css +8 -4
- package/styles/Editor.css +7 -0
- package/dist/cjs/components/authors/AffiliationButton.js +0 -104
- package/dist/cjs/components/authors/AffiliationForm.js +0 -50
- package/dist/cjs/components/authors/AuthorAffiliations.js +0 -120
- package/dist/cjs/components/authors/AuthorFormPlaceholder.js +0 -71
- package/dist/cjs/components/authors/DeleteAuthorConfirmationDialog.js +0 -36
- package/dist/cjs/components/authors/RequiredFieldConfirmationDialog.js +0 -39
- package/dist/cjs/components/authors/SaveAuthorConfirmationDialog.js +0 -39
- package/dist/es/components/authors/AffiliationButton.js +0 -74
- package/dist/es/components/authors/AffiliationForm.js +0 -43
- package/dist/es/components/authors/AuthorAffiliations.js +0 -89
- package/dist/es/components/authors/AuthorFormPlaceholder.js +0 -64
- package/dist/es/components/authors/DeleteAuthorConfirmationDialog.js +0 -29
- package/dist/es/components/authors/RequiredFieldConfirmationDialog.js +0 -32
- package/dist/es/components/authors/SaveAuthorConfirmationDialog.js +0 -32
- package/dist/types/components/authors/AffiliationButton.d.ts +0 -8
- package/dist/types/components/authors/AuthorAffiliations.d.ts +0 -11
- package/dist/types/components/authors/AuthorFormPlaceholder.d.ts +0 -2
- package/dist/types/components/authors/DeleteAuthorConfirmationDialog.d.ts +0 -7
- package/dist/types/components/authors/RequiredFieldConfirmationDialog.d.ts +0 -7
- package/dist/types/components/authors/SaveAuthorConfirmationDialog.d.ts +0 -7
|
@@ -41,7 +41,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
41
41
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
42
|
};
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.AuthorsModal = void 0;
|
|
44
|
+
exports.AuthorsModal = exports.affiliationsReducer = exports.authorsReducer = void 0;
|
|
45
45
|
const json_schema_1 = require("@manuscripts/json-schema");
|
|
46
46
|
const style_guide_1 = require("@manuscripts/style-guide");
|
|
47
47
|
const lodash_1 = require("lodash");
|
|
@@ -49,25 +49,28 @@ const react_1 = __importStar(require("react"));
|
|
|
49
49
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
50
50
|
const array_reducer_1 = require("../../lib/array-reducer");
|
|
51
51
|
const authors_1 = require("../../lib/authors");
|
|
52
|
-
const
|
|
53
|
-
const
|
|
52
|
+
const ConfirmationDialog_1 = require("../dialog/ConfirmationDialog");
|
|
53
|
+
const FormFooter_1 = __importDefault(require("../form/FormFooter"));
|
|
54
|
+
const FormPlaceholder_1 = require("../form/FormPlaceholder");
|
|
55
|
+
const ModalFormActions_1 = require("../form/ModalFormActions");
|
|
54
56
|
const AuthorDetailsForm_1 = require("./AuthorDetailsForm");
|
|
55
|
-
const AuthorFormPlaceholder_1 = require("./AuthorFormPlaceholder");
|
|
56
57
|
const AuthorList_1 = require("./AuthorList");
|
|
57
|
-
const RequiredFieldConfirmationDialog_1 = require("./RequiredFieldConfirmationDialog");
|
|
58
|
-
const SaveAuthorConfirmationDialog_1 = require("./SaveAuthorConfirmationDialog");
|
|
59
58
|
const AddAuthorButton = styled_components_1.default.div `
|
|
60
59
|
display: flex;
|
|
61
60
|
align-items: center;
|
|
62
|
-
|
|
63
|
-
margin-left: ${(props) => props.theme.grid.unit * 4}px;
|
|
61
|
+
padding: 12px 8px 12px 12px;
|
|
64
62
|
cursor: pointer;
|
|
63
|
+
&[data-active='true'] {
|
|
64
|
+
background: ${(props) => props.theme.colors.background.fifth};
|
|
65
|
+
border: 1px solid ${(props) => props.theme.colors.border.primary};
|
|
66
|
+
border-left: 0;
|
|
67
|
+
border-right: 0;
|
|
68
|
+
}
|
|
65
69
|
`;
|
|
66
70
|
const ActionTitle = styled_components_1.default.div `
|
|
67
71
|
padding-left: ${(props) => props.theme.grid.unit * 2}px;
|
|
68
72
|
`;
|
|
69
73
|
const FormLabel = styled_components_1.default.legend `
|
|
70
|
-
margin-top: 12px;
|
|
71
74
|
margin-bottom: 12px;
|
|
72
75
|
font: ${(props) => props.theme.font.weight.normal}
|
|
73
76
|
${(props) => props.theme.font.size.xlarge} /
|
|
@@ -79,28 +82,73 @@ const FormLabel = styled_components_1.default.legend `
|
|
|
79
82
|
const AuthorForms = styled_components_1.default.div `
|
|
80
83
|
padding-left: ${(props) => props.theme.grid.unit * 3}px;
|
|
81
84
|
padding-right: ${(props) => props.theme.grid.unit * 3}px;
|
|
85
|
+
position: relative;
|
|
86
|
+
margin-top: 20px;
|
|
82
87
|
`;
|
|
83
88
|
const StyledSidebarContent = (0, styled_components_1.default)(style_guide_1.SidebarContent) `
|
|
84
89
|
padding: 0;
|
|
85
90
|
`;
|
|
86
|
-
const
|
|
87
|
-
|
|
91
|
+
const AuthorsSection = styled_components_1.default.div `
|
|
92
|
+
margin-top: ${(props) => props.theme.grid.unit * 4}px;
|
|
93
|
+
padding-top: ${(props) => props.theme.grid.unit * 4}px;
|
|
94
|
+
border-top: 1px solid ${(props) => props.theme.colors.border.tertiary};
|
|
95
|
+
`;
|
|
96
|
+
const AuthorsHeader = styled_components_1.default.div `
|
|
97
|
+
display: flex;
|
|
98
|
+
justify-content: space-between;
|
|
99
|
+
align-items: flex-start;
|
|
100
|
+
flex-direction: column;
|
|
101
|
+
margin-bottom: ${(props) => props.theme.grid.unit * 2}px;
|
|
102
|
+
`;
|
|
103
|
+
const AuthorsTitle = styled_components_1.default.h3 `
|
|
104
|
+
margin: 0;
|
|
105
|
+
font-weight: ${(props) => props.theme.font.weight.normal};
|
|
106
|
+
font-size: ${(props) => props.theme.font.size.large};
|
|
107
|
+
font-family: ${(props) => props.theme.font.family.sans};
|
|
108
|
+
color: ${(props) => props.theme.colors.text.secondary};
|
|
109
|
+
`;
|
|
110
|
+
const AffiliateButton = styled_components_1.default.button `
|
|
111
|
+
color: ${(props) => props.theme.colors.brand.default};
|
|
112
|
+
background: none;
|
|
113
|
+
border: none;
|
|
114
|
+
cursor: pointer;
|
|
115
|
+
padding: 0;
|
|
116
|
+
font: ${(props) => props.theme.font.weight.normal}
|
|
117
|
+
${(props) => props.theme.font.size.normal}
|
|
118
|
+
${(props) => props.theme.font.family.sans};
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: 4px;
|
|
122
|
+
margin-top: ${(props) => props.theme.grid.unit * 2}px;
|
|
123
|
+
&:hover {
|
|
124
|
+
opacity: 0.8;
|
|
125
|
+
}
|
|
126
|
+
`;
|
|
127
|
+
const StyledModalBody = (0, styled_components_1.default)(style_guide_1.ModalBody) `
|
|
128
|
+
position: relative;
|
|
129
|
+
height: calc(90vh - 40px);
|
|
130
|
+
`;
|
|
131
|
+
const StyledModalSidebarHeader = (0, styled_components_1.default)(style_guide_1.ModalSidebarHeader) `
|
|
132
|
+
margin-bottom: 16px;
|
|
133
|
+
`;
|
|
134
|
+
exports.authorsReducer = (0, array_reducer_1.arrayReducer)((a, b) => a.id === b.id);
|
|
135
|
+
exports.affiliationsReducer = (0, array_reducer_1.arrayReducer)((a, b) => a.id === b.id);
|
|
88
136
|
const normalize = (author) => ({
|
|
89
137
|
id: author.id,
|
|
90
|
-
role: author.role,
|
|
91
|
-
affiliations: author.affiliations || [],
|
|
138
|
+
role: author.role || 'author',
|
|
139
|
+
affiliations: (author.affiliations || []).sort(),
|
|
92
140
|
bibliographicName: author.bibliographicName,
|
|
93
141
|
email: author.email || '',
|
|
94
142
|
isCorresponding: author.isCorresponding || false,
|
|
95
143
|
ORCIDIdentifier: author.ORCIDIdentifier || '',
|
|
96
|
-
priority: author.priority,
|
|
144
|
+
priority: author.priority || 0,
|
|
97
145
|
isJointContributor: author.isJointContributor || false,
|
|
98
|
-
userID: '',
|
|
99
|
-
invitationID: '',
|
|
146
|
+
userID: author.userID || '',
|
|
147
|
+
invitationID: author.invitationID || '',
|
|
100
148
|
footnote: author.footnote || [],
|
|
101
149
|
corresp: author.corresp || [],
|
|
102
150
|
});
|
|
103
|
-
const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author, onSaveAuthor, onDeleteAuthor,
|
|
151
|
+
const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author, onSaveAuthor, onDeleteAuthor, addNewAuthor = false, }) => {
|
|
104
152
|
const [isOpen, setOpen] = (0, react_1.useState)(true);
|
|
105
153
|
const [isDisableSave, setDisableSave] = (0, react_1.useState)(true);
|
|
106
154
|
const [isEmailRequired, setEmailRequired] = (0, react_1.useState)(false);
|
|
@@ -113,38 +161,74 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
113
161
|
const [nextAuthor, setNextAuthor] = (0, react_1.useState)(null);
|
|
114
162
|
const [isSwitchingAuthor, setIsSwitchingAuthor] = (0, react_1.useState)(false);
|
|
115
163
|
const [isCreatingNewAuthor, setIsCreatingNewAuthor] = (0, react_1.useState)(false);
|
|
164
|
+
const [showAffiliationDrawer, setShowAffiliationDrawer] = (0, react_1.useState)(false);
|
|
165
|
+
const [selectedAffiliations, setSelectedAffiliations] = (0, react_1.useState)([]);
|
|
116
166
|
const valuesRef = (0, react_1.useRef)();
|
|
117
167
|
const actionsRef = (0, react_1.useRef)();
|
|
118
|
-
const [authors, dispatchAuthors] = (0, react_1.useReducer)(authorsReducer, $authors.sort(authors_1.authorComparator));
|
|
119
|
-
const [affiliations
|
|
168
|
+
const [authors, dispatchAuthors] = (0, react_1.useReducer)(exports.authorsReducer, $authors.sort(authors_1.authorComparator));
|
|
169
|
+
const [affiliations] = (0, react_1.useReducer)(exports.affiliationsReducer, $affiliations);
|
|
170
|
+
const affiliationItems = affiliations.map((affiliation) => ({
|
|
171
|
+
id: affiliation.id,
|
|
172
|
+
label: affiliation.institution,
|
|
173
|
+
country: affiliation.country,
|
|
174
|
+
city: affiliation.city,
|
|
175
|
+
state: affiliation.county,
|
|
176
|
+
}));
|
|
177
|
+
const [selectedAffiliationIds, setSelectedAffiliationIds] = (0, react_1.useState)([]);
|
|
120
178
|
(0, react_1.useEffect)(() => {
|
|
121
179
|
if (addNewAuthor) {
|
|
122
180
|
handleAddAuthor();
|
|
123
181
|
}
|
|
124
182
|
}, [addNewAuthor]);
|
|
125
183
|
const [selection, setSelection] = (0, react_1.useState)(author);
|
|
184
|
+
(0, react_1.useEffect)(() => {
|
|
185
|
+
const currentAuthor = selection;
|
|
186
|
+
const relevantAffiliations = affiliationItems.filter((item) => { var _a; return (_a = currentAuthor === null || currentAuthor === void 0 ? void 0 : currentAuthor.affiliations) === null || _a === void 0 ? void 0 : _a.includes(item.id); });
|
|
187
|
+
setSelectedAffiliations(relevantAffiliations);
|
|
188
|
+
setSelectedAffiliationIds(relevantAffiliations.map((item) => item.id));
|
|
189
|
+
}, []);
|
|
126
190
|
const handleSelect = (author) => {
|
|
127
191
|
const values = valuesRef.current;
|
|
128
192
|
setIsCreatingNewAuthor(false);
|
|
129
|
-
if (values && selection
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
193
|
+
if (values && selection) {
|
|
194
|
+
const normalizedSelection = normalize(selection);
|
|
195
|
+
const normalizedValues = normalize(values);
|
|
196
|
+
const hasChanges = !(0, lodash_1.isEqual)(normalizedSelection, normalizedValues);
|
|
197
|
+
if (hasChanges && !isDisableSave) {
|
|
198
|
+
setShowConfirmationDialog(true);
|
|
199
|
+
setNextAuthor(author);
|
|
200
|
+
}
|
|
201
|
+
else if (hasChanges && isDisableSave) {
|
|
202
|
+
setShowRequiredFieldConfirmationDialog(true);
|
|
203
|
+
setNextAuthor(author);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
updateAffiliationSelection(author);
|
|
207
|
+
setSelection(author);
|
|
208
|
+
setShowAffiliationDrawer(false);
|
|
209
|
+
setNewAuthor(false);
|
|
210
|
+
}
|
|
136
211
|
}
|
|
137
212
|
else {
|
|
213
|
+
setShowAffiliationDrawer(false);
|
|
214
|
+
updateAffiliationSelection(author);
|
|
138
215
|
setSelection(author);
|
|
139
216
|
setNewAuthor(false);
|
|
140
217
|
}
|
|
141
218
|
};
|
|
219
|
+
const updateAffiliationSelection = (author) => {
|
|
220
|
+
const relevantAffiliations = affiliationItems.filter((item) => { var _a; return (_a = author.affiliations) === null || _a === void 0 ? void 0 : _a.includes(item.id); });
|
|
221
|
+
setSelectedAffiliations(relevantAffiliations);
|
|
222
|
+
setSelectedAffiliationIds(relevantAffiliations.map((item) => item.id));
|
|
223
|
+
};
|
|
142
224
|
const handleClose = () => {
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
225
|
+
if (unSavedChanges) {
|
|
226
|
+
if (isDisableSave) {
|
|
227
|
+
setShowRequiredFieldConfirmationDialog(true);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
setShowConfirmationDialog(true);
|
|
231
|
+
}
|
|
148
232
|
}
|
|
149
233
|
else {
|
|
150
234
|
setShowRequiredFieldConfirmationDialog(false);
|
|
@@ -160,6 +244,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
160
244
|
setSelection(nextAuthor);
|
|
161
245
|
setNextAuthor(null);
|
|
162
246
|
setNewAuthor(false);
|
|
247
|
+
setShowAffiliationDrawer(false);
|
|
163
248
|
setIsCreatingNewAuthor(false);
|
|
164
249
|
}
|
|
165
250
|
else if (isCreatingNewAuthor) {
|
|
@@ -171,10 +256,14 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
171
256
|
const handleCancel = () => {
|
|
172
257
|
handleResetAuthor();
|
|
173
258
|
if (nextAuthor) {
|
|
259
|
+
const affiliations = nextAuthor.affiliations || [];
|
|
260
|
+
setSelectedAffiliationIds(affiliations);
|
|
261
|
+
setSelectedAffiliations(affiliationItems.filter((item) => affiliations.includes(item.id)));
|
|
174
262
|
setSelection(nextAuthor);
|
|
175
263
|
setNextAuthor(null);
|
|
176
264
|
setNewAuthor(false);
|
|
177
265
|
setIsCreatingNewAuthor(false);
|
|
266
|
+
setUnSavedChanges(false);
|
|
178
267
|
}
|
|
179
268
|
else if (newAuthor && unSavedChanges && !isSwitchingAuthor) {
|
|
180
269
|
setNewAuthor(false);
|
|
@@ -186,6 +275,8 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
186
275
|
setIsCreatingNewAuthor(false);
|
|
187
276
|
}
|
|
188
277
|
setShowConfirmationDialog(false);
|
|
278
|
+
setShowRequiredFieldConfirmationDialog(false);
|
|
279
|
+
setShowAffiliationDrawer(false);
|
|
189
280
|
};
|
|
190
281
|
const handleSaveAuthor = (values) => {
|
|
191
282
|
if (!values || !selection) {
|
|
@@ -201,6 +292,9 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
201
292
|
setSelection(author);
|
|
202
293
|
setShowConfirmationDialog(false);
|
|
203
294
|
setNewAuthor(false);
|
|
295
|
+
setSelectedAffiliationIds([]);
|
|
296
|
+
setSelectedAffiliations([]);
|
|
297
|
+
setShowAffiliationDrawer(false);
|
|
204
298
|
setIsCreatingNewAuthor(false);
|
|
205
299
|
dispatchAuthors({
|
|
206
300
|
type: 'update',
|
|
@@ -240,6 +334,8 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
240
334
|
footnote: [],
|
|
241
335
|
};
|
|
242
336
|
setIsSwitchingAuthor(!!selection);
|
|
337
|
+
setSelectedAffiliations([]);
|
|
338
|
+
setSelectedAffiliationIds([]);
|
|
243
339
|
setSelection(author);
|
|
244
340
|
setNewAuthor(true);
|
|
245
341
|
};
|
|
@@ -247,7 +343,9 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
247
343
|
const values = valuesRef.current;
|
|
248
344
|
setIsSwitchingAuthor(!!selection);
|
|
249
345
|
setIsCreatingNewAuthor(true);
|
|
250
|
-
if (values &&
|
|
346
|
+
if (values &&
|
|
347
|
+
selection &&
|
|
348
|
+
!(0, lodash_1.isEqual)(normalize(values), normalize(selection))) {
|
|
251
349
|
if (isDisableSave) {
|
|
252
350
|
setShowRequiredFieldConfirmationDialog(true);
|
|
253
351
|
}
|
|
@@ -258,6 +356,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
258
356
|
}
|
|
259
357
|
else {
|
|
260
358
|
createNewAuthor();
|
|
359
|
+
setShowAffiliationDrawer(false);
|
|
261
360
|
}
|
|
262
361
|
};
|
|
263
362
|
const handleDeleteAuthor = () => {
|
|
@@ -266,37 +365,26 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
266
365
|
}
|
|
267
366
|
onDeleteAuthor(selection);
|
|
268
367
|
setSelection(undefined);
|
|
368
|
+
setUnSavedChanges(false);
|
|
269
369
|
dispatchAuthors({
|
|
270
370
|
type: 'delete',
|
|
271
371
|
item: selection,
|
|
272
372
|
});
|
|
273
373
|
};
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
dispatchAffiliations({
|
|
277
|
-
type: 'update',
|
|
278
|
-
items: [affiliation],
|
|
279
|
-
});
|
|
280
|
-
};
|
|
281
|
-
const handleAddAffiliation = (affiliation) => {
|
|
282
|
-
if (!valuesRef.current) {
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
const values = valuesRef.current;
|
|
286
|
-
const affiliations = values.affiliations || [];
|
|
287
|
-
handleSaveAuthor(Object.assign(Object.assign({}, values), { affiliations: [...affiliations, affiliation.id] }));
|
|
288
|
-
};
|
|
289
|
-
const handleRemoveAffiliation = (affiliation) => {
|
|
290
|
-
var _a;
|
|
291
|
-
if (!valuesRef.current) {
|
|
374
|
+
const handleRemoveAffiliation = (affId) => {
|
|
375
|
+
if (!selection) {
|
|
292
376
|
return;
|
|
293
377
|
}
|
|
294
|
-
const
|
|
295
|
-
|
|
378
|
+
const newAffiliations = selectedAffiliationIds.filter((id) => id !== affId);
|
|
379
|
+
setSelectedAffiliationIds(newAffiliations);
|
|
380
|
+
setSelectedAffiliations(affiliationItems.filter((item) => newAffiliations.includes(item.id)));
|
|
296
381
|
};
|
|
297
382
|
const handleResetAuthor = () => {
|
|
298
383
|
var _a;
|
|
299
384
|
(_a = actionsRef.current) === null || _a === void 0 ? void 0 : _a.reset();
|
|
385
|
+
const affiliations = (selection === null || selection === void 0 ? void 0 : selection.affiliations) || [];
|
|
386
|
+
setSelectedAffiliationIds(affiliations);
|
|
387
|
+
setSelectedAffiliations(affiliationItems.filter((item) => affiliations.includes(item.id)));
|
|
300
388
|
setShowConfirmationDialog(false);
|
|
301
389
|
setShowRequiredFieldConfirmationDialog(false);
|
|
302
390
|
setUnSavedChanges(false);
|
|
@@ -311,61 +399,77 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
|
|
|
311
399
|
};
|
|
312
400
|
const handleChangeAuthor = (values) => {
|
|
313
401
|
const normalized = (0, lodash_1.omit)(normalize(selection), 'priority');
|
|
314
|
-
const updatedValues = (0, lodash_1.omit)(values, 'priority');
|
|
315
|
-
|
|
316
|
-
|
|
402
|
+
const updatedValues = (0, lodash_1.omit)(normalize(values), 'priority');
|
|
403
|
+
const isSameAuthor = updatedValues.id === normalized.id;
|
|
404
|
+
const hasChanges = !(0, lodash_1.isEqual)(updatedValues, normalized);
|
|
405
|
+
if (isSameAuthor && hasChanges) {
|
|
317
406
|
setUnSavedChanges(true);
|
|
318
407
|
}
|
|
319
|
-
|
|
320
|
-
|
|
408
|
+
else {
|
|
409
|
+
setUnSavedChanges(false);
|
|
410
|
+
}
|
|
411
|
+
valuesRef.current = Object.assign(Object.assign({}, updatedValues), { priority: values.priority });
|
|
321
412
|
const { given, family } = values.bibliographicName;
|
|
322
413
|
const { email, isCorresponding } = values;
|
|
323
414
|
const isNameFilled = (given === null || given === void 0 ? void 0 : given.length) && (family === null || family === void 0 ? void 0 : family.length);
|
|
324
|
-
if (
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
setDisableSave(false);
|
|
415
|
+
if (hasChanges && isNameFilled) {
|
|
416
|
+
if (isCorresponding) {
|
|
417
|
+
setDisableSave(!(email === null || email === void 0 ? void 0 : email.length));
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
setDisableSave(false);
|
|
421
|
+
}
|
|
332
422
|
}
|
|
333
423
|
else {
|
|
334
424
|
setDisableSave(true);
|
|
335
425
|
}
|
|
336
|
-
|
|
337
|
-
setEmailRequired(true);
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
setEmailRequired(false);
|
|
341
|
-
}
|
|
426
|
+
setEmailRequired(isCorresponding);
|
|
342
427
|
};
|
|
343
428
|
const handleShowDeleteDialog = () => {
|
|
344
429
|
setShowDeleteDialog((prev) => !prev);
|
|
345
430
|
};
|
|
431
|
+
const handleAffiliationSelect = (affiliationId) => {
|
|
432
|
+
if (!selection) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const currentAffiliations = selectedAffiliationIds || [];
|
|
436
|
+
const isAlreadySelected = currentAffiliations.includes(affiliationId);
|
|
437
|
+
const newAffiliations = isAlreadySelected
|
|
438
|
+
? currentAffiliations.filter((id) => id !== affiliationId)
|
|
439
|
+
: [...currentAffiliations, affiliationId];
|
|
440
|
+
setSelectedAffiliationIds(newAffiliations);
|
|
441
|
+
setSelectedAffiliations(affiliationItems.filter((item) => newAffiliations.includes(item.id)));
|
|
442
|
+
};
|
|
346
443
|
return (react_1.default.createElement(style_guide_1.StyledModal, { isOpen: isOpen, onRequestClose: () => handleClose(), shouldCloseOnOverlayClick: true },
|
|
347
444
|
react_1.default.createElement(style_guide_1.ModalContainer, null,
|
|
348
445
|
react_1.default.createElement(style_guide_1.ModalHeader, null,
|
|
349
446
|
react_1.default.createElement(style_guide_1.CloseButton, { onClick: () => handleClose(), "data-cy": "modal-close-button" })),
|
|
350
|
-
react_1.default.createElement(
|
|
447
|
+
react_1.default.createElement(StyledModalBody, null,
|
|
351
448
|
react_1.default.createElement(style_guide_1.ModalSidebar, { "data-cy": "authors-sidebar" },
|
|
352
|
-
react_1.default.createElement(
|
|
449
|
+
react_1.default.createElement(StyledModalSidebarHeader, null,
|
|
353
450
|
react_1.default.createElement(style_guide_1.ModalSidebarTitle, null, "Authors")),
|
|
354
451
|
react_1.default.createElement(StyledSidebarContent, null,
|
|
355
|
-
react_1.default.createElement(AddAuthorButton, { "data-cy": "add-author-button", onClick: handleAddAuthor },
|
|
452
|
+
react_1.default.createElement(AddAuthorButton, { "data-cy": "add-author-button", onClick: handleAddAuthor, "data-active": isCreatingNewAuthor },
|
|
356
453
|
react_1.default.createElement(style_guide_1.AddIcon, { width: 18, height: 18 }),
|
|
357
454
|
react_1.default.createElement(ActionTitle, null, "New Author")),
|
|
358
455
|
react_1.default.createElement(AuthorList_1.AuthorList, { author: selection, authors: authors, onSelect: handleSelect, onDelete: handleShowDeleteDialog, moveAuthor: handleMoveAuthor, lastSavedAuthor: lastSavedAuthor }))),
|
|
359
456
|
react_1.default.createElement(style_guide_1.ScrollableModalContent, { "data-cy": "author-modal-content" }, selection ? (react_1.default.createElement(AuthorForms, null,
|
|
360
|
-
react_1.default.createElement(
|
|
361
|
-
react_1.default.createElement(
|
|
362
|
-
react_1.default.createElement(
|
|
457
|
+
react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showRequiredFieldConfirmationDialog, onPrimary: () => setShowRequiredFieldConfirmationDialog(false), onSecondary: handleCancel, type: ConfirmationDialog_1.DialogType.REQUIRED, entityType: "author" }),
|
|
458
|
+
react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showConfirmationDialog, onPrimary: handleSave, onSecondary: handleCancel, type: ConfirmationDialog_1.DialogType.SAVE, entityType: "author" }),
|
|
459
|
+
react_1.default.createElement(ModalFormActions_1.ModalFormActions, { type: "author", onSave: () => handleSaveAuthor(valuesRef.current), onDelete: handleDeleteAuthor, showDeleteDialog: showDeleteDialog, handleShowDeleteDialog: handleShowDeleteDialog, newEntity: newAuthor ||
|
|
363
460
|
(isCreatingNewAuthor &&
|
|
364
461
|
!showConfirmationDialog &&
|
|
365
462
|
!showRequiredFieldConfirmationDialog), isDisableSave: isDisableSave }),
|
|
366
463
|
react_1.default.createElement(FormLabel, null, "Details"),
|
|
367
|
-
react_1.default.createElement(AuthorDetailsForm_1.AuthorDetailsForm, { values: normalize(selection), onChange: handleChangeAuthor, onSave: handleSaveAuthor, actionsRef: actionsRef, isEmailRequired: isEmailRequired }),
|
|
368
|
-
react_1.default.createElement(
|
|
369
|
-
|
|
464
|
+
react_1.default.createElement(AuthorDetailsForm_1.AuthorDetailsForm, { values: normalize(selection), onChange: handleChangeAuthor, onSave: handleSaveAuthor, actionsRef: actionsRef, isEmailRequired: isEmailRequired, selectedAffiliations: selectedAffiliationIds }),
|
|
465
|
+
react_1.default.createElement(AuthorsSection, null,
|
|
466
|
+
react_1.default.createElement(AuthorsHeader, null,
|
|
467
|
+
react_1.default.createElement(AuthorsTitle, null, "Authors"),
|
|
468
|
+
react_1.default.createElement(AffiliateButton, { onClick: () => setShowAffiliationDrawer(true), "data-cy": "affiliate-authors-button" },
|
|
469
|
+
react_1.default.createElement(style_guide_1.AddInstitutionIcon, { width: 16, height: 16 }),
|
|
470
|
+
"Assign Institutions")),
|
|
471
|
+
react_1.default.createElement(style_guide_1.SelectedItemsBox, { items: selectedAffiliations, onRemove: handleRemoveAffiliation, placeholder: "No institutions assigned" })),
|
|
472
|
+
showAffiliationDrawer && (react_1.default.createElement(style_guide_1.Drawer, { items: affiliationItems, selectedIds: selectedAffiliationIds, title: "Authors", onSelect: handleAffiliationSelect, onBack: () => setShowAffiliationDrawer(false), width: "100%" })))) : (react_1.default.createElement(FormPlaceholder_1.FormPlaceholder, { type: "author", title: 'Author Details', message: 'Select an author from the list to display their details here.', placeholderIcon: react_1.default.createElement(style_guide_1.AuthorPlaceholderIcon, null) })))),
|
|
473
|
+
react_1.default.createElement(FormFooter_1.default, { onCancel: handleClose }))));
|
|
370
474
|
};
|
|
371
475
|
exports.AuthorsModal = AuthorsModal;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ConfirmationDialog = exports.DialogType = void 0;
|
|
7
|
+
const style_guide_1 = require("@manuscripts/style-guide");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
10
|
+
const StyledIcon = (0, styled_components_1.default)(style_guide_1.AttentionOrangeIcon) `
|
|
11
|
+
margin-right: 8px;
|
|
12
|
+
`;
|
|
13
|
+
const MessageBox = styled_components_1.default.div `
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
justify-content: space-between;
|
|
17
|
+
min-height: 90px;
|
|
18
|
+
`;
|
|
19
|
+
var DialogType;
|
|
20
|
+
(function (DialogType) {
|
|
21
|
+
DialogType["SAVE"] = "save";
|
|
22
|
+
DialogType["DELETE"] = "delete";
|
|
23
|
+
DialogType["REQUIRED"] = "required";
|
|
24
|
+
})(DialogType = exports.DialogType || (exports.DialogType = {}));
|
|
25
|
+
const getDialogConfig = (dialogType, entityType) => {
|
|
26
|
+
const configs = {
|
|
27
|
+
[DialogType.SAVE]: {
|
|
28
|
+
title: 'Unsaved changes',
|
|
29
|
+
message: {
|
|
30
|
+
primary: "You've made changes but not saved them!",
|
|
31
|
+
secondary: 'Would you like to save or discard your changes?',
|
|
32
|
+
},
|
|
33
|
+
buttons: {
|
|
34
|
+
primary: 'Save',
|
|
35
|
+
secondary: 'Discard',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
[DialogType.DELETE]: {
|
|
39
|
+
title: `Delete ${entityType}`,
|
|
40
|
+
message: {
|
|
41
|
+
primary: entityType === 'affiliation'
|
|
42
|
+
? 'This action will delete the institution and any links to authors affiliated to it.'
|
|
43
|
+
: `Are you sure you want to remove this ${entityType} from the list?`,
|
|
44
|
+
secondary: 'Do you want to continue?',
|
|
45
|
+
},
|
|
46
|
+
buttons: {
|
|
47
|
+
primary: 'Delete',
|
|
48
|
+
secondary: 'Cancel',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
[DialogType.REQUIRED]: {
|
|
52
|
+
title: 'Empty required field',
|
|
53
|
+
message: {
|
|
54
|
+
primary: 'A required field has been left empty. If you discard, any updates will not be saved!',
|
|
55
|
+
secondary: 'Would you like to discard or continue editing?',
|
|
56
|
+
},
|
|
57
|
+
buttons: {
|
|
58
|
+
primary: 'Continue editing',
|
|
59
|
+
secondary: 'Discard',
|
|
60
|
+
},
|
|
61
|
+
minHeight: '90px',
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
return configs[dialogType];
|
|
65
|
+
};
|
|
66
|
+
const ConfirmationDialog = ({ isOpen, type, entityType, onPrimary, onSecondary, }) => {
|
|
67
|
+
const config = getDialogConfig(type, entityType);
|
|
68
|
+
const Header = () => (react_1.default.createElement(react_1.default.Fragment, null,
|
|
69
|
+
react_1.default.createElement(StyledIcon, null),
|
|
70
|
+
" ",
|
|
71
|
+
config.title));
|
|
72
|
+
const Message = () => (react_1.default.createElement(MessageBox, null,
|
|
73
|
+
react_1.default.createElement("div", null, config.message.primary),
|
|
74
|
+
config.message.secondary && react_1.default.createElement("div", null, config.message.secondary)));
|
|
75
|
+
return (react_1.default.createElement(style_guide_1.Dialog, { isOpen: isOpen, category: style_guide_1.Category.confirmation, header: react_1.default.createElement(Header, null), message: react_1.default.createElement(Message, null), actions: {
|
|
76
|
+
primary: {
|
|
77
|
+
action: onPrimary,
|
|
78
|
+
title: config.buttons.primary,
|
|
79
|
+
},
|
|
80
|
+
secondary: {
|
|
81
|
+
action: onSecondary,
|
|
82
|
+
title: config.buttons.secondary,
|
|
83
|
+
},
|
|
84
|
+
} }));
|
|
85
|
+
};
|
|
86
|
+
exports.ConfirmationDialog = ConfirmationDialog;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
8
|
+
const Footer = styled_components_1.default.div `
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: flex-end;
|
|
11
|
+
align-items: center;
|
|
12
|
+
padding: 16px 32px;
|
|
13
|
+
height: 40px;
|
|
14
|
+
box-shadow: 0px -2px 12px 0px rgba(216, 216, 216, 0.26);
|
|
15
|
+
border-radius: 0px 0px 8px 8px;
|
|
16
|
+
`;
|
|
17
|
+
const RemoveButton = styled_components_1.default.button `
|
|
18
|
+
background-color: #0d79d0;
|
|
19
|
+
color: ${(props) => props.theme.colors.text.onDark};
|
|
20
|
+
padding: 8px 32px;
|
|
21
|
+
border-radius: 4px;
|
|
22
|
+
border: 1px solid #0d79d0;
|
|
23
|
+
&:hover {
|
|
24
|
+
background-color: ${(props) => props.theme.colors.background.hover};
|
|
25
|
+
}
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
`;
|
|
28
|
+
const FormFooter = ({ onCancel }) => {
|
|
29
|
+
return (react_1.default.createElement(Footer, null,
|
|
30
|
+
react_1.default.createElement(RemoveButton, { onClick: onCancel }, "Close")));
|
|
31
|
+
};
|
|
32
|
+
exports.default = FormFooter;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FormPlaceholder = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
|
+
const Container = styled_components_1.default.div `
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
height: 100%;
|
|
15
|
+
overflow-y: auto;
|
|
16
|
+
`;
|
|
17
|
+
const Placeholder = styled_components_1.default.div `
|
|
18
|
+
margin-bottom: ${(props) => props.theme.grid.unit * 5}px;
|
|
19
|
+
`;
|
|
20
|
+
const Action = styled_components_1.default.div `
|
|
21
|
+
font-size: ${(props) => props.theme.font.size.xlarge};
|
|
22
|
+
font-weight: ${(props) => props.theme.font.weight.medium};
|
|
23
|
+
letter-spacing: -0.5px;
|
|
24
|
+
`;
|
|
25
|
+
const Message = styled_components_1.default.div `
|
|
26
|
+
max-width: 400px;
|
|
27
|
+
font-size: ${(props) => props.theme.font.size.xlarge};
|
|
28
|
+
margin-top: ${(props) => props.theme.grid.unit * 6}px;
|
|
29
|
+
font-weight: ${(props) => props.theme.font.weight.light};
|
|
30
|
+
color: ${(props) => props.theme.colors.text.secondary};
|
|
31
|
+
text-align: center;
|
|
32
|
+
|
|
33
|
+
@media (max-width: 850px) {
|
|
34
|
+
margin-right: ${(props) => props.theme.grid.unit * 5}px;
|
|
35
|
+
margin-left: ${(props) => props.theme.grid.unit * 5}px;
|
|
36
|
+
max-width: 350px;
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
const FormPlaceholder = ({ type, title, message, placeholderIcon, }) => (react_1.default.createElement(Container, { "data-cy": `${type}-details` },
|
|
40
|
+
react_1.default.createElement(Placeholder, null, placeholderIcon),
|
|
41
|
+
react_1.default.createElement(Action, null, title),
|
|
42
|
+
react_1.default.createElement(Message, null, message)));
|
|
43
|
+
exports.FormPlaceholder = FormPlaceholder;
|