AccessionDetailsPage.tsx 54.7 KB
Newer Older
1
2
import * as React from 'react';
import { connect } from 'react-redux';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
3
import { compose } from 'redux';
4
5
import { WithTranslation, withTranslation } from 'react-i18next';
// Action
Maksym Tishchenko's avatar
Maksym Tishchenko committed
6
7
8
import {
  getAccessionAction,
  getAccessionInventories,
9
  uploadAccessionAttachments,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
10
11
12
13
14
15
16
  removeAccessionAction,
  removeAccessionInvNameAction,
  receiveAccessionInvNameSuccessAction,
  removeAccessionIprAction,
  receiveAccessionIprSuccessAction,
  receiveAccessionSourceSuccessAction,
  removeAccessionSourceAction,
17
18
  receiveAccessionSourceMapSuccessAction,
  removeAccessionSourceMapAction,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
19
20
21
22
23
24
  receiveAccessionPedigreeSuccessAction,
  removeAccessionPedigreeAction,
  receiveCitationSuccessAction,
  removeCitationAction,
  removeAccessionQuarantineAction,
  receiveAccessionQuarantineSuccessAction,
25
26
27
28
  removeAccessionAttachmentAction,
  receiveAccessionSuccessAction,
  removeAccessionAttachmentsAction,
  receiveAccessionAttachmentSuccessAction,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
29
} from 'accession/action/public';
30
// Service
31
import { UISecurity as P, AccessionService, InventoryService, SourceDescObservationService } from '@gringlobal-ce/client/service';
32
import navigateTo from '@gringlobal-ce/client/action/navigation';
Matija Obreza's avatar
Matija Obreza committed
33
import { showDialog } from '@gringlobal-ce/client/action/dialog';
34

35
// Models
Matija Obreza's avatar
Matija Obreza committed
36
37
38
import {
  AuditLog,
  Accession,
39
  Inventory,
Matija Obreza's avatar
Matija Obreza committed
40
41
42
  AccessionAction,
  AccessionIpr,
  AccessionSource,
43
  Geography,
44
  Cooperator, SourceDescObservationFilteredPage,
Matija Obreza's avatar
Matija Obreza committed
45
} from '@gringlobal-ce/client/model/gringlobal';
46
import { SortDirection, Page, IPageRequest } from '@gringlobal-ce/client/model/page';
47
// UI
48
import Loading from '@gringlobal-ce/client/ui/common/Loading';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
49
50
51
52
53
54
55
import {
  Card,
  CardContent,
  CardHeader,
  CardActions,
  Button,
} from '@material-ui/core';
56
57
import { Properties, PropertiesItem } from '@gringlobal-ce/client/ui/common/Properties';
import PrettyDate from '@gringlobal-ce/client/ui/common/time/PrettyDate';
58
import { PrintSpecies } from 'common/Taxonomy';
Matija Obreza's avatar
Matija Obreza committed
59
import { CodeValueDisplay } from 'common/CodeValue';
60
61
62
import ButtonBar from '@gringlobal-ce/client/ui/common/button/ButtonBar';
import PageTitle from '@gringlobal-ce/client/ui/common/PageTitle';
import FileUploader from '@gringlobal-ce/client/ui/common/file-uploader';
Oleksii Savran's avatar
Oleksii Savran committed
63
import AttachmentsDisplay from 'repository/ui/c/AttachmentsDisplay';
64
import AuditDataDisplay from 'common/AuditDataDisplay';
65
import AuditLogsTable from 'common/AuditLogsTable';
66
import Tab from '@material-ui/core/Tab';
67
68
69
import HeaderTabs from '@gringlobal-ce/client/ui/common/tabs/HeaderTabs';
import TabPanel from '@gringlobal-ce/client/ui/common/tabs/TabPanel';
import { GridContainer, GridItem } from '@gringlobal-ce/client/ui/common/grid';
70
import withTabs, { IWithTabs } from 'ui/common/withTabs';
71
72
73
import SlotLayout from '@gringlobal-ce/client/ui/common/layout/SlotLayout';
import confirm from '@gringlobal-ce/client/utilities/confirmAlert';
import { showSnackbar } from '@gringlobal-ce/client/action/snackbar';
Oleksii Savran's avatar
Oleksii Savran committed
74
import { BasicAccessionActionsTable } from 'accession/ui/c/AccessionActionsTable';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
75
// Dialog Forms
76
import AccessionForm from 'accession/ui/c/AccessionForm';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
77
78
79
80
81
import AccessionIprForm from 'accession/ui/c/AccessionIprForm';
import AccessionSourceForm from 'accession/ui/c/AccessionSourceForm';
import AccessionPedigreeForm from 'accession/ui/c/AccessionPedigreeForm';
import AccessionCitationForm from 'accession/ui/c/AccessionCitationForm';
import AccessionQuarantineForm from 'accession/ui/c/AccessionQuarantineForm';
82
import AccessionInvName from '@gringlobal-ce/client/model/gringlobal/AccessionInvName';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
83
import AccessionInvNameForm from 'accession/ui/c/AccessionInvNameForm';
84
85
86
import AccessionPedigree from '@gringlobal-ce/client/model/gringlobal/AccessionPedigree';
import Citation from '@gringlobal-ce/client/model/gringlobal/Citation';
import AccessionQuarantine from '@gringlobal-ce/client/model/gringlobal/AccessionQuarantine';
87
import InventoryTreeTable from 'inventory/ui/c/InventoryTreeTable';
88
import { AccessionLink, DOILink } from 'ui/common/Links';
89
import AccessionInvAttachForm from 'accession/ui/c/AccessionInvAttachForm';
90
import Table, { Renderers, TextAlign } from '@gringlobal-ce/client/ui/common/table/Table';
91
92
import { InventoryGroupTableDefaultConfig } from 'inventorygroup/ui/GroupBrowsePage';
import { CooperatorOwnedTableConfiguration as TableConfiguration } from '@gringlobal-ce/client/ui/common/table/TableConfiguration';
93
94
import AccessionSectionTable from './c/AccessionSectionTable';
import { ExtraRenderers } from 'common/ExtraRenderers';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
95
96
97
98
99
100
import AddNewButton from '@gringlobal-ce/client/ui/common/button/AddNewButton';
import FABMenu from '@gringlobal-ce/client/ui/common/button/FABMenu';
import AccessionActionDialog from 'accession/ui/c/AccessionActionDialog';
import { AccessionTableDefaultConfig } from 'accession/ui/AccessionBrowsePage';
import CancelOutlinedIcon from '@material-ui/icons/CancelOutlined';
import EditIcon from '@material-ui/icons/Edit';
101
102
103
import AccessionSourceMap from '@gringlobal-ce/client/model/gringlobal/AccessionSourceMap';
import { CooperatorTableDefaultConfig } from 'cooperator/ui/BrowsePage';
import AccessionSourceMapDialog from 'accession/ui/c/AccessionSourceMapDialog';
104
import { Link } from 'react-router-dom';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
105
import { WithBrowsePageBase } from 'ui/common/withBrowsePageBase';
106
107
108
import { SourceDescObservationTableDefaultConfig } from 'accession/ui/SourceDescObservationBrowsePage';
import SourceDescObservationDialog from 'accession/ui/c/SourceDescObservationDialog';
import TranslatedSourceDescObservation from '@gringlobal-ce/client/model/gringlobal/TranslatedSourceDescObservation';
Matija Obreza's avatar
Matija Obreza committed
109
import PrintReportDialog from 'common/PrintReportDialog';
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

const AccessionSourceTableDefaultConfig = {
  defaultColumns: [
    'id',
    'sourceTypeCode',
    'sourceDate',
    'isOrigin',
    'isWebVisible',
  ],
  ignoredColumns: [ 'accession' ],
  columnRenderers: {
    sourceDate: ({ value: sourceDate, row }: { value: Date, row: AccessionSource }) => <PrettyDate value={ sourceDate } format={ row.sourceDateCode } />,
    sourceTypeCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionSource.CodeGroup.sourceTypeCode),
    acquisitionSource: ExtraRenderers.CODEVALUE_RENDERER(AccessionSource.CodeGroup.acquisitionSource),
    collectedFormCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionSource.CodeGroup.collectedFormCode),
    unitQuantityCollectedCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionSource.CodeGroup.unitQuantityCollectedCode),
    georeferenceDatum: ExtraRenderers.CODEVALUE_RENDERER(AccessionSource.CodeGroup.georeferenceDatum),
    georeferenceProtocolCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionSource.CodeGroup.georeferenceProtocolCode),
    isOrigin: Renderers.STRING_BOOL_RENDERER,
    isWebVisible: Renderers.STRING_BOOL_RENDERER,
    geography: ({ value }: { value: Geography }) => value ? <>{ value.countryCode }</> : null,
  },
}
133

Maksym Tishchenko's avatar
Maksym Tishchenko committed
134
135
interface IDetailsPageState {
  auditLogs: Page<AuditLog>;
136
137
  error: string;
  accessionDialogIsOpen: boolean;
Maksym Tishchenko's avatar
Maksym Tishchenko committed
138
139
140
141
142
  actionDialogIsOpen: boolean;
  actions: AccessionAction[];
  selected: number[];
  selectedAction: AccessionAction;
  createNew: boolean;
143
144
145
  descObservationDialogIsOpen: boolean;
  selectedSourceObs: number[];
  sourceDescObservations: SourceDescObservationFilteredPage
146
147
}

148
149
150
151
152
enum AccessionDetailsTabs {
  INFO = 'info',
  ACTIONS = 'actions',
  INVENTORIES = 'inventories',
  ATTACHMENTS = 'attachments',
153
  GROUPS = 'groups',
154
  AUDITLOGS = 'auditlogs',
155
  SOURCE_OBSERVATIONS = 'sourceobs',
156
157
}

158
const InventoryGroupTableConfig = new TableConfiguration(InventoryGroupTableDefaultConfig);
Maksym Tishchenko's avatar
Maksym Tishchenko committed
159
const AccessionTableConfig = new TableConfiguration(AccessionTableDefaultConfig);
160
const SourceDescObservationTableConfig = new TableConfiguration(SourceDescObservationTableDefaultConfig);
161

Maksym Tishchenko's avatar
Maksym Tishchenko committed
162
class AccessionDetailsPage extends React.Component<PropsFromRedux & WithBrowsePageBase & WithTranslation & IWithTabs, IDetailsPageState> {
163
164
165
166
167
168

  protected static needs = [
    ({ params: { id } }) => getAccessionAction(id),
    ({ params: { id } }) => getAccessionInventories(id),
  ];

169
  public static defaultTab = AccessionDetailsTabs.INFO;
Matija Obreza's avatar
Matija Obreza committed
170
  private static PRINT_DIALOG_KEY = 'accession-print-pdf-dialog';
171

172
  public state = {
173
    auditLogs: null,
174
175
    error: null,
    accessionDialogIsOpen: false,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
176
177
178
179
180
    actionDialogIsOpen: false,
    actions: [],
    selected: [],
    selectedAction: null,
    createNew: true,
181
182
183
    descObservationDialogIsOpen: false,
    sourceDescObservations: null,
    selectedSourceObs: [],
184
185
  };

186
187
188
189
190
191
192
193
194
195
196
197
  public constructor(props) {
    super(props);
  }

  public componentDidMount(): void {
    const { getAccessionAction, id, getAccessionInventories, accessionCall } = this.props;
    if (id && !accessionCall || accessionCall.data.id !== +id) {
      getAccessionAction(id);
      getAccessionInventories(id);
    }
  }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
198
  public componentDidUpdate(prevProps, prevState) {
199
    const { accessionCall, id, getAccessionAction, getAccessionInventories, currentTab } = this.props;
200
    const { actions, selected, sourceDescObservations } = this.state;
201
202
203
204
205
    if (!accessionCall || !accessionCall.loading && (!accessionCall.error && id && +id !== accessionCall.data.id)) {
      getAccessionAction(id);
      getAccessionInventories(id);
    }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
206
207
208
209
    if (prevState.actions.length === 0 && actions.length === 0 && accessionCall?.data?.actions.length > 0) {
      this.setState({ actions: accessionCall.data.actions })
    }

210
    if (currentTab === AccessionDetailsTabs.AUDITLOGS && currentTab !== prevProps.currentTab) {
211
212
213
214
215
      if (!this.state.auditLogs) {
        AccessionService.accessionAuditLogs(+this.props.id)
          .then((auditLogs) => this.setState({ auditLogs }));
      }
    }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
216

217
218
219
220
221
222
    if (currentTab === AccessionDetailsTabs.SOURCE_OBSERVATIONS && currentTab !== prevProps.currentTab) {
      if (!sourceDescObservations || ! sourceDescObservations?.filter?.accessionSource?.accession?.id?.includes(id)) {
        this.loadSourceDescObservations();
      }
    }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
223
224
225
    if (prevState.selected.length !== 1 && selected.length === 1) {
      this.getSelectedAction(selected[0]);
    }
226
227
  }

228
  private handleUploading = (files: File[]) => {
229
    const { inventories, uploadAccessionAttachments } = this.props;
230
    const systemInventory = inventories.data.content.find((inv) => inv.formTypeCode === Inventory.SYSTEM_INVENTORY_FTC);
231
    if (systemInventory) {
232
      return uploadAccessionAttachments(systemInventory.id, files);
233
    }
234
235
  };

236
  private onSortChange = (sortBy: string, dir: SortDirection): void => {
Matija Obreza's avatar
Matija Obreza committed
237
    AccessionService.accessionAuditLogs(+this.props.id, { properties: [ sortBy ], direction: [ dir ] })
238
239
240
241
242
243
244
245
246
      .then((auditLogs) => this.setState({ auditLogs }));
  };

  private loadMore = (): void => {
    const { auditLogs } = this.state;
    AccessionService.accessionAuditLogs(+this.props.id, Page.nextPage(auditLogs))
      .then((newAuditLogs) => this.setState({ auditLogs: Page.merge(auditLogs, newAuditLogs) }));
  };

247
  private handleRemove = () => {
248
    const { removeAccessionAction, t, id, accessionCall, showSnackbar } = this.props;
249
250
251
252
253
    confirm(t('accession.public.p.details.delete', { name: accessionCall.data.accessionNumber }), {
      confirmLabel: t('common:label.yes'),
      abortLabel: t('common:label.no'),
    }).then(() => {
      removeAccessionAction(+id);
254
255
    }).catch((e) => {
      showSnackbar(e.data && e.data.error || e.toString());
256
257
258
    });
  };

Maksym Tishchenko's avatar
Maksym Tishchenko committed
259
260
261
262
263
264
265
266
267
268
269
270
  private addCurrentAccession = (el) => {
    const { accessionCall } = this.props;
    el.accession = { id: accessionCall.data.id }
    return el;
  }

  private addFirstInventory = (el) => {
    const { inventories } = this.props;
    el.inventory = { id: inventories.data.content[0].id };
    return el;
  }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  private handleCreateAction = (actionData: AccessionAction) => {
    const { accessionCall } = this.props;
    const { actions } = this.state;
    const { data: accession } = accessionCall
    this.setState({ error: null });
    actionData.accession = { id: accession.id } as Accession;

    AccessionService.createAction(actionData).then((action) => {
      const updatedActions = [action, ...actions];
      this.closeActionDialog();
      this.setState({ selected: [], actions: updatedActions });
    }).catch((e) => {
      this.setState({ error: e.data && e.data.error || e.toString() });
    });
  }

  private handleRemoveAction = () => {
    const { t, showSnackbar } = this.props;
    const { selected, actions } = this.state;

    confirm(t('common:label.deleteListConfirm', { what: t('accession.public.p.details.actions'), count: selected.length }), {
      confirmLabel: t('common:label.yes'),
      abortLabel: t('common:label.no'),
    }).then(async () => {
      for (let i = 0; i < selected.length; i++) {
        await AccessionService.removeAction(selected[i]);
      }
      const updatedActions = actions.filter((action) => !selected.includes(action.id))
      console.log("updatedActions", updatedActions);
300
      this.setState({ selected: [], actions: [ ...updatedActions ] });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
      console.log("actions", this.state.actions);
    }).catch((e) => {
      showSnackbar(e.data && e.data.error || e.toString());
    });
  }

  private handleUpdateAction = (actionData: AccessionAction) => {
    const { accessionCall } = this.props;
    const { actions } = this.state;
    const { data: accession } = accessionCall
    this.setState({ error: null });
    actionData.accession = { id: accession.id } as Accession;

    AccessionService.updateAction(actionData).then((response) => {
      const updatedActionIndex = accession.actions.findIndex((action) => +action.id === +response.id)
      const updatedActions = actions;
      updatedActions[updatedActionIndex] = response;
      this.closeActionDialog();
319
      this.setState({ selected: [], actions: [ ...updatedActions ] });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
    }).catch((e) => {
      this.setState({ error: e.data && e.data.error || e.toString() });
    });
  }

  private getSelectedAction = (id) => {
    AccessionService.getAction(id).then((response) => {
      this.setState({ selectedAction: response });
    }).catch((e) => {
      this.props.showSnackbar(e.data && e.data.error || e.toString());
    });
  }

  private openActionDialog = (createNew = true) => {
    this.setState({ actionDialogIsOpen: true, createNew });
  };

  private closeActionDialog = () => {
    this.setState({ actionDialogIsOpen: false, createNew: true });
  };

  private actionsSelected = (selectedRows: number[]) => {
    const { actions } = this.state;
    const selectedIds = selectedRows.map((rowIndex) => actions[rowIndex].id)
    this.setState({ selected: selectedIds });
  }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
347
348
349
  private handleInvNameSubmit = (name: AccessionInvName, edit: boolean) => {
    const { receiveAccessionInvNameSuccessAction, inventories, t } = this.props;
    let accessionInvNamePromise: Promise<AccessionInvName>;
350
    this.setState({ error: null });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
351
352
    name = this.addCurrentAccession(name);
    if (inventories.data.content.length === 0) {
353
      this.setState({ error: t('accession.public.c.error.noInventories') })
Maksym Tishchenko's avatar
Maksym Tishchenko committed
354
355
356
357
358
359
360
361
362
363
364
      return;
    }
    name = this.addFirstInventory(name);
    if (edit) {
      accessionInvNamePromise = AccessionService.updateAccessionInvName(name)
    } else {
      accessionInvNamePromise = AccessionService.createAccessionInvName(name)
    }
    accessionInvNamePromise.then((name) => {
      receiveAccessionInvNameSuccessAction(name);
    }).catch((e) => {
365
      this.setState({ error: e.data && e.data.error || e.toString() });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
366
367
368
369
370
371
372
    });
    return accessionInvNamePromise
  };

  private handleIprSubmit = (ipr: AccessionIpr, edit: boolean) => {
    const { receiveAccessionIprSuccessAction, accessionCall } = this.props;
    let accessionIprPromise: Promise<AccessionIpr>;
373
    this.setState({ error: null });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
374
375
376
377
378
379
380
381
382
383
    ipr = this.addCurrentAccession(ipr);
    if (edit) {
      accessionIprPromise = AccessionService.updateAccessionIpr(ipr)
    } else {
      ipr.accession = accessionCall.data as unknown as Accession;
      accessionIprPromise = AccessionService.createAccessionIpr(ipr)
    }
    accessionIprPromise.then((ipr) => {
      receiveAccessionIprSuccessAction(ipr);
    }).catch((e) => {
384
      this.setState({ error: e.data && e.data.error || e.toString() });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
385
386
387
388
389
390
391
    });
    return accessionIprPromise;
  };

  private handleSourceSubmit = (source: AccessionSource, edit: boolean) => {
    const { receiveAccessionSourceSuccessAction } = this.props;
    let accessionSourcePromise: Promise<AccessionSource>;
392
    this.setState({ error: null });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
393
394
395
396
397
398
399
400
401
    source = this.addCurrentAccession(source);
    if (edit) {
      accessionSourcePromise = AccessionService.updateAccessionSource(source)
    } else {
      accessionSourcePromise = AccessionService.createAccessionSource(source)
    }
    accessionSourcePromise.then((source) => {
      receiveAccessionSourceSuccessAction(source);
    }).catch((e) => {
402
      this.setState({ error: e.data && e.data.error || e.toString() });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
403
404
405
406
    });
    return accessionSourcePromise;
  };

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  private handleSourceMapSubmit = (sourceMap: AccessionSourceMap, edit: boolean) => {
    const { receiveAccessionSourceMapSuccessAction, t } = this.props;
    let accessionSourceMapPromise: Promise<AccessionSourceMap>;
    this.setState({ error: null });
    if (! sourceMap.accessionSource) {
      this.setState({ error: t("accession.public.c.error.noAccessionSource") });
      return;
    }
    sourceMap.accessionSource = this.addCurrentAccession(sourceMap.accessionSource);
    if (edit) {
      accessionSourceMapPromise = AccessionService.updateSourceMap(sourceMap)
    } else {
      accessionSourceMapPromise = AccessionService.createSourceMap(sourceMap)
    }
    accessionSourceMapPromise.then((sourceMap) => {
      receiveAccessionSourceMapSuccessAction(sourceMap);
    }).catch((e) => {
      this.setState({ error: e.data && e.data.error || e.toString() });
    });
    return accessionSourceMapPromise;
  };

Maksym Tishchenko's avatar
Maksym Tishchenko committed
429
430
431
  private handlePedigreeSubmit = (pedigree: AccessionPedigree, edit: boolean) => {
    const { receiveAccessionPedigreeSuccessAction } = this.props;
    let accessionPedigreePromise: Promise<AccessionPedigree>;
432
    this.setState({ error: null });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
433
434
435
436
437
438
439
440
441
    pedigree = this.addCurrentAccession(pedigree);
    if (edit) {
      accessionPedigreePromise = AccessionService.updateAccessionPedigree(pedigree)
    } else {
      accessionPedigreePromise = AccessionService.createAccessionPedigree(pedigree)
    }
    accessionPedigreePromise.then((pedigree) => {
      receiveAccessionPedigreeSuccessAction(pedigree);
    }).catch((e) => {
442
      this.setState({ error: e.data && e.data.error || e.toString() });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
443
444
445
446
447
448
449
    });
    return accessionPedigreePromise;
  };

  private handleCitationSubmit = (citation: Citation, edit: boolean) => {
    const { receiveCitationSuccessAction } = this.props;
    let accessionCitationPromise: Promise<Citation>;
450
    this.setState({ error: null });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
451
452
453
454
455
456
457
458
459
    citation = this.addCurrentAccession(citation);
    if (edit) {
      accessionCitationPromise = AccessionService.updateCitation(citation)
    } else {
      accessionCitationPromise = AccessionService.createCitation(citation)
    }
    accessionCitationPromise.then((citation) => {
      receiveCitationSuccessAction(citation);
    }).catch((e) => {
460
      this.setState({ error: e.data && e.data.error || e.toString() });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
461
462
463
464
465
466
467
    });
    return accessionCitationPromise;
  };

  private handleQuarantineSubmit = (quarantine: AccessionQuarantine, edit: boolean) => {
    const { receiveAccessionQuarantineSuccessAction } = this.props;
    let accessionQuarantinePromise: Promise<AccessionQuarantine>;
468
    this.setState({ error: null });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
469
470
471
472
473
474
475
476
477
    quarantine = this.addCurrentAccession(quarantine);
    if (edit) {
      accessionQuarantinePromise = AccessionService.updateAccessionQuarantine(quarantine)
    } else {
      accessionQuarantinePromise = AccessionService.createAccessionQuarantine(quarantine)
    }
    accessionQuarantinePromise.then((quarantine) => {
      receiveAccessionQuarantineSuccessAction(quarantine);
    }).catch((e) => {
478
      this.setState({ error: e.data && e.data.error || e.toString() });
Maksym Tishchenko's avatar
Maksym Tishchenko committed
479
480
481
482
    });
    return accessionQuarantinePromise;
  };

483
484
  private clearError = () => {
    this.setState({ error: null })
Maksym Tishchenko's avatar
Maksym Tishchenko committed
485
  }
486

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
  private openAccessionDialog = () => {
    this.setState({ accessionDialogIsOpen: true });
  };

  private closeAccessionDialog = () => {
    this.setState({ accessionDialogIsOpen: false });
  };

  private handleSubmit = (accessionData: Accession) => {
    const { receiveAccessionSuccessAction, navigateTo } = this.props;
    this.setState({ error: null });
    AccessionService.update(accessionData).then((accession) => {
      this.closeAccessionDialog();
      navigateTo(`/a/${accession.id}`);
      receiveAccessionSuccessAction(accession);
    }).catch((e) => {
      this.setState({ error: e.data && e.data.error || e.toString() });
    });
  };

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
  private handleAttachmentSubmit = (data, closeDialog) => {
    const { receiveAccessionAttachmentSuccessAction } = this.props
    if(data.inventory && !data.inventory.id) {
      data.inventory = { id: data.inventory }
    }
    InventoryService.updateAccessionInvAttach(data)
      .then((updatedAttach) => {
        closeDialog();
        receiveAccessionAttachmentSuccessAction(updatedAttach);
      })
      .catch((e) => {
        this.setState({ error: e.data && e.data.error || e.toString() })
      })
  }

  private handleEditFile = (fileId, openDialog, updateFileMeta) => {
    InventoryService.getAccessionInvAttach(fileId)
      .then((fileMeta) => {
        updateFileMeta(fileMeta);
        openDialog();
      })
  }

530
531
532
533
  private resetError = () => {
    return this.setState({ error: null });
  }

534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  private handleSubmitSourceObs = (data: TranslatedSourceDescObservation) => {
    const { sourceDescObservations } = this.state;
    this.resetError();
    let SourceDescObservationPromise: Promise<TranslatedSourceDescObservation>;

    if (data.id) {
      SourceDescObservationPromise = SourceDescObservationService.update(data)
    } else {
      SourceDescObservationPromise = SourceDescObservationService.create(data)
    }

    SourceDescObservationPromise.then((receivedSourceDescObs) => {
      this.closeSourceObsDialog();
      const updatedObs = sourceDescObservations
      if (data.id) {
        updatedObs.content = sourceDescObservations.content.map((sourceObs) => sourceObs.id === receivedSourceDescObs.id ? { ...sourceObs, ...receivedSourceDescObs } : sourceObs)
        this.setState({ sourceDescObservations: updatedObs })
      } else {
        updatedObs.content = [ ...sourceDescObservations.content, receivedSourceDescObs ]
        this.setState({ sourceDescObservations: updatedObs })
      }
    }).catch((e) => {
      this.setState({ error: e.data && e.data.error || e.toString() });
    });
  };

  private removeSourceObs = () => {
    const { t } = this.props;
    const { selectedSourceObs } = this.state;

    confirm(t('common:label.deleteListConfirm', { count: selectedSourceObs.length, what: t('client:model.name.SourceDescObservation', { count: selectedSourceObs.length }) }), {
      confirmLabel: t('common:label.yes'),
      abortLabel: t('common:label.no'),
    }).then(() => {
      Promise.all(selectedSourceObs.map(async (sourceObs) => await SourceDescObservationService.remove(sourceObs.id)))
        .then(() => {
          this.loadSourceDescObservations().then(() => {
            this.setState({
              selectedSourceObs: [],
            });
          }).catch((e) => console.log('Loading source descriptor observations error: ', e));
        })
        .catch((e) => {
          console.log('SourceDescObservation removing error: ', e);
        });
    });
  };

  private sourceDescObsRowsToggled = (selectedRows: number[]) => {
    const { sourceDescObservations } = this.state;
    const selectedIds = selectedRows.map((rowIndex) => sourceDescObservations.content[rowIndex].id)
    this.setState({ selectedSourceObs: selectedIds });
  }

  private onSourceObsSortChange = (sortBy: string, dir: SortDirection): void => {
    this.loadSourceDescObservations({ properties: [ sortBy ], direction: [ dir ] })
  };

  private loadSourceDescObservations = (page: IPageRequest = {}) => {
    const { id } = this.props;
    const { sourceDescObservations } = this.state;
595
    return SourceDescObservationService.listTranslated({ accessionSource: { accession: { id } } }, page)
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
      .then((newSourceDescObservations) => this.setState({ sourceDescObservations: Page.merge(sourceDescObservations, newSourceDescObservations) }))
      .catch((e) => console.log('Loading source descriptor observations error: ', e));
  }

  private loadMoreSourceObs = (): void => {
    const { sourceDescObservations } = this.state;
    this.loadSourceDescObservations(Page.nextPage(sourceDescObservations))
  };

  private openSourceObsDialog = (createNew = true) => {
    this.setState({ descObservationDialogIsOpen: true, createNew });
  };

  private closeSourceObsDialog = () => {
    this.setState({ descObservationDialogIsOpen: false, createNew: true });
  };

613

614
  public render(): React.ReactNode {
Maksym Tishchenko's avatar
Maksym Tishchenko committed
615
    const {
616
      id, inventories, accessionCall, t, currentTab, onTabChange,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
617
      removeAccessionInvNameAction, removeAccessionIprAction,
618
619
      removeAccessionSourceAction, removeAccessionSourceMapAction,
      removeAccessionPedigreeAction, removeCitationAction, removeAccessionQuarantineAction,
620
      removeAccessionAttachmentAction, removeAccessionAttachmentsAction
Maksym Tishchenko's avatar
Maksym Tishchenko committed
621
    } = this.props;
622
    const { auditLogs, error, accessionDialogIsOpen, actionDialogIsOpen, actions, selectedAction, selected, createNew, selectedSourceObs, descObservationDialogIsOpen, sourceDescObservations } = this.state;
623
    // const columns = InventoryTableConfig.getColumns(inventories && inventories.data && inventories.data.content ? inventories.data.content[0] : null);
624
625
626
627
628
    if (!accessionCall) {
      return null;
    }

    const { loading, data: accession } = accessionCall;
629
    const systemInventory = inventories?.data?.content?.find((inv) => inv.formTypeCode === Inventory.SYSTEM_INVENTORY_FTC);
630
    const groupsColumns = InventoryGroupTableConfig.getColumns(accession && accession.groups && accession.groups.length ? accession.groups[0] : null );
631
    const sourceDescObsColumns = SourceDescObservationTableConfig.getColumns(sourceDescObservations?.content ? sourceDescObservations.content[0] : null);
632

Maksym Tishchenko's avatar
Maksym Tishchenko committed
633
634
635
636
637
638
639
640
641
642
643
644
645
646
    const fabActions = [
      {
        title: 'common:action.remove',
        action: this.handleRemoveAction,
        icon: <CancelOutlinedIcon/>,
      },
      {
        title: 'common:action.edit',
        action: () => this.openActionDialog(false),
        icon: <EditIcon/>,
        disabled: selected.length !== 1
      },
    ]

647
648
649
650
651
652
653
654
655
656
657
658
659
660
    const sourceObsActions = [
      {
        title: 'common:action.remove',
        action: this.removeSourceObs,
        icon: <CancelOutlinedIcon/>,
      },
      {
        title: 'common:action.edit',
        action: () => this.openSourceObsDialog(false),
        icon: <EditIcon/>,
        disabled: selectedSourceObs.length !== 1
      },
    ]

661
662
    return (
      <>
663
        <PageTitle title={ accession ? accession.accessionNumber : t('accession.public.p.details.title') }/>
664
        <HeaderTabs
665
          value={ currentTab }
666
          textColor="primary"
667
          onChange={ onTabChange }
668
669
670
671
          variant="scrollable"
          scrollButtons="auto"
          aria-label="Inventory tabs"
        >
672
673
674
          <Tab value={ AccessionDetailsTabs.INFO } label={ accession ? <>{ accession.accessionNumber }</> : t('accession.public.p.details.title') } />
          <Tab value={ AccessionDetailsTabs.INVENTORIES } label={ t('client:model.name.Inventory_plural') } />
          <Tab value={ AccessionDetailsTabs.ATTACHMENTS } label={ t('accession.public.p.details.attachments') } />
675
          <Tab value={ AccessionDetailsTabs.GROUPS } label={ t('accession.public.p.details.groups') } />
676
          <Tab value={ AccessionDetailsTabs.SOURCE_OBSERVATIONS } label={ t('client:model.name.SourceDescObservation_plural') } />
677
678
          <Tab value={ AccessionDetailsTabs.ACTIONS } label={ t('accession.public.p.details.actions') } />
          <Tab value={ AccessionDetailsTabs.AUDITLOGS } label={ t('accession.public.p.details.auditLogs') } />
679
        </HeaderTabs>
680
681
682
        { loading && <Loading/> }
        { accession &&
          <>
683
            <TabPanel value={ currentTab } index={ AccessionDetailsTabs.INFO }>
Matija Obreza's avatar
Matija Obreza committed
684
685
686
687
              <GridContainer>
                <GridItem>
                  <Card>
                    <CardHeader
688
689
690
                      title={ accession.accessionNumber }
                      subheader={ <PrintSpecies taxonomySpecies={ accession.taxonomySpecies } /> }
                    />
691

Matija Obreza's avatar
Matija Obreza committed
692
693
                    <CardActions>
                      <ButtonBar>
694
                        <P.HasAccess action={ P.PassportData } permission={ P.write } siteId={ accession.site.id }>
695
                          <Button onClick={ this.openAccessionDialog } variant="contained" color="secondary">{ t('common:action.edit') }</Button>
696
697
698
699
                        </P.HasAccess>
                        <P.HasAccess action={ P.PassportData } permission={ P.delete } siteId={ accession.site.id }>
                          <Button onClick={ this.handleRemove } variant="text">{ t('common:action.delete') }</Button>
                        </P.HasAccess>
Matija Obreza's avatar
Matija Obreza committed
700
701
702
                        <Button variant="outlined" color="secondary" onClick={ () => this.props.showDialog(AccessionDetailsPage.PRINT_DIALOG_KEY) }>
                          { t('common:action.generatePdf') }
                        </Button>
Matija Obreza's avatar
Matija Obreza committed
703
704
705
                      </ButtonBar>
                    </CardActions>
                    <CardContent>
706
                      <Properties>
Matija Obreza's avatar
Matija Obreza committed
707
                        { accession.accessionNumberPart1 &&
708
                          <PropertiesItem title={ t(['client:model.Accession.accessionNumberPart1', 'client:model._.accessionNumberPart1']) }>
Matija Obreza's avatar
Matija Obreza committed
709
710
711
712
                            { accession.accessionNumberPart1 }
                          </PropertiesItem>
                        }
                        { accession.accessionNumberPart2 &&
713
                          <PropertiesItem title={ t(['client:model.Accession.accessionNumberPart2', 'client:model._.accessionNumberPart2']) }>
Matija Obreza's avatar
Matija Obreza committed
714
715
716
717
                            { accession.accessionNumberPart2 }
                          </PropertiesItem>
                        }
                        { accession.accessionNumberPart3 &&
718
                          <PropertiesItem title={ t(['client:model.Accession.accessionNumberPart3', 'client:model._.accessionNumberPart3']) }>
Matija Obreza's avatar
Matija Obreza committed
719
720
721
722
                            { accession.accessionNumberPart3 }
                          </PropertiesItem>
                        }
                        { accession.taxonomySpecies &&
723
                          <PropertiesItem title={ t(['client:model.Accession.taxonomySpecies', 'client:model._.taxonomySpecies']) }>
Matija Obreza's avatar
Matija Obreza committed
724
725
726
                            <PrintSpecies taxonomySpecies={ accession.taxonomySpecies } />
                          </PropertiesItem>
                        }
Matija Obreza's avatar
Matija Obreza committed
727
                        <PropertiesItem title={ t([ 'client:model.Accession.site', 'client:model._.site' ]) }>
728
729
                          <code>{ accession.site.siteShortName }</code> { accession.site.siteLongName }
                        </PropertiesItem>
Matija Obreza's avatar
Matija Obreza committed
730
                        { accession.statusCode &&
731
                          <PropertiesItem title={ t(['client:model.Accession.statusCode', 'client:model._.statusCode']) }>
Matija Obreza's avatar
Matija Obreza committed
732
733
734
                            <CodeValueDisplay codeGroup={ Accession.CodeGroup.statusCode } value={ accession.statusCode } />
                          </PropertiesItem>
                        }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
735
                        { accession.mlsStatus &&
736
                        <PropertiesItem title={ t(['client:model.Accession.mlsStatus', 'client:model._.mlsStatus']) }>
Maksym Tishchenko's avatar
Maksym Tishchenko committed
737
738
739
                          <CodeValueDisplay codeGroup={ Accession.CodeGroup.mlsStatus } value={ accession.mlsStatus } />
                        </PropertiesItem>
                        }
Matija Obreza's avatar
Matija Obreza committed
740
                        { accession.lifeFormCode &&
741
                          <PropertiesItem title={ t(['client:model.Accession.lifeFormCode', 'client:model._.lifeFormCode']) }>
Matija Obreza's avatar
Matija Obreza committed
742
743
744
745
                            <CodeValueDisplay codeGroup={ Accession.CodeGroup.lifeFormCode } value={ accession.lifeFormCode } />
                          </PropertiesItem>
                        }
                        { accession.improvementStatusCode &&
746
                          <PropertiesItem title={ t(['client:model.Accession.improvementStatusCode', 'client:model._.improvementStatusCode']) }>
Matija Obreza's avatar
Matija Obreza committed
747
748
749
750
                            <CodeValueDisplay codeGroup={ Accession.CodeGroup.improvementStatusCode } value={ accession.improvementStatusCode } />
                          </PropertiesItem>
                        }
                        { accession.reproductiveUniformityCode &&
751
                          <PropertiesItem title={ t(['client:model.Accession.reproductiveUniformityCode', 'client:model._.reproductiveUniformityCode']) }>
Matija Obreza's avatar
Matija Obreza committed
752
753
754
755
                            <CodeValueDisplay codeGroup={ Accession.CodeGroup.reproductiveUniformityCode } value={ accession.reproductiveUniformityCode } />
                          </PropertiesItem>
                        }
                        { accession.doi &&
756
                          <PropertiesItem title={ t(['client:model.Accession.doi', 'client:model._.doi']) }>
757
                            <DOILink doi={ accession.doi } />
Matija Obreza's avatar
Matija Obreza committed
758
759
760
                          </PropertiesItem>
                        }
                        { /* accession.isCore &&
761
                          <PropertiesItem title={ t(['client:model.Accession.isCore', 'client:model._.isCore']) }>
Matija Obreza's avatar
Matija Obreza committed
762
763
764
765
                            { accession.isCore }
                          </PropertiesItem>
                        */ }
                        { /* accession.isBackedUp &&
766
                          <PropertiesItem title={ t(['client:model.Accession.isBackedUp', 'client:model._.isBackedUp']) }>
Matija Obreza's avatar
Matija Obreza committed
767
768
769
770
                            { accession.isBackedUp }
                          </PropertiesItem>
                        */ }
                        { accession.initialReceivedDate &&
771
                          <PropertiesItem title={ t(['client:model.Accession.initialReceivedDate', 'client:model._.initialReceivedDate']) }>
772
                            <PrettyDate value={ accession.initialReceivedDate } format={ accession.initialReceivedDateCode } withCaption />
Matija Obreza's avatar
Matija Obreza committed
773
774
775
                          </PropertiesItem>
                        }
                        { accession.initialReceivedDateCode &&
776
                          <PropertiesItem title={ t(['client:model.Accession.initialReceivedDateCode', 'client:model._.initialReceivedDateCode']) }>
Matija Obreza's avatar
Matija Obreza committed
777
                            { accession.initialReceivedDateCode }
778
                          </PropertiesItem>
Matija Obreza's avatar
Matija Obreza committed
779
780
                        }
                        { accession.initialReceivedFormCode &&
781
                          <PropertiesItem title={ t(['client:model.Accession.initialReceivedFormCode', 'client:model._.initialReceivedFormCode']) }>
Matija Obreza's avatar
Matija Obreza committed
782
783
784
                            <CodeValueDisplay codeGroup={ Accession.CodeGroup.initialReceivedFormCode } value={ accession.initialReceivedFormCode } />
                          </PropertiesItem>
                        }
785
                        { accession.backupLocation1Site &&
786
                          <PropertiesItem title={ t(['client:model.Accession.backupLocation1Site', 'client:model._.backupLocation1Site']) }>
787
                            <code>{ accession.backupLocation1Site.siteShortName }</code> { accession.backupLocation1Site.siteLongName }
Matija Obreza's avatar
Matija Obreza committed
788
                          </PropertiesItem>
789
790
                        }
                        { accession.backupLocation2Site &&
791
                          <PropertiesItem title={ t(['client:model.Accession.backupLocation2Site', 'client:model._.backupLocation2Site']) }>
792
                            <code>{ accession.backupLocation2Site.siteShortName }</code> { accession.backupLocation2Site.siteLongName }
Matija Obreza's avatar
Matija Obreza committed
793
                          </PropertiesItem>
794
                        }
Matija Obreza's avatar
Matija Obreza committed
795
                        { accession.note &&
Matija Obreza's avatar
Matija Obreza committed
796
                          <PropertiesItem title={ t([ 'client:model.Accession.note', 'client:model._.note' ]) }>
Matija Obreza's avatar
Matija Obreza committed
797
798
799
800
                            { accession.note }
                          </PropertiesItem>
                        }
                        <AuditDataDisplay item={ accession }/>
801
802
                      </Properties>
                    </CardContent>
Matija Obreza's avatar
Matija Obreza committed
803
804
                  </Card>
                </GridItem>
805

806
807
                <AccessionSectionTable
                  sectionName="names"
Maksym Tishchenko's avatar
Maksym Tishchenko committed
808
                  model={ { modelName: 'AccessionInvName', modelClass: AccessionInvName } }
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
                  tableConfig={ {
                    defaultColumns: [
                      'id',
                      'categoryCode',
                      'plantName',
                      'plantNameRank',
                      'isWebVisible',
                      'nameGroup',
                    ],
                    ignoredColumns: [ 'inventory', 'nameGroup' ],
                    defaultColumnSettings: {
                      plantName: { bold: true },
                    },
                    columnRenderers: {
                      categoryCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionInvName.CodeGroup.categoryCode),
                      isWebVisible: Renderers.STRING_BOOL_RENDERER,
                    },
                  } }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
827
828
829
                  dialogForm={ AccessionInvNameForm }
                  removeAction={ removeAccessionInvNameAction }
                  handleSubmit={ this.handleInvNameSubmit }
830
                  error={ { error, clear: this.clearError } }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
831
832
                />

833
834
                <AccessionSectionTable
                  sectionName="sources"
Maksym Tishchenko's avatar
Maksym Tishchenko committed
835
                  model={ { modelName: 'AccessionSource', modelClass: AccessionSource } }
836
837
838
839
840
841
842
843
844
845
846
                  tableConfig={ AccessionSourceTableDefaultConfig }
                  dialogForm={ AccessionSourceForm }
                  removeAction={ removeAccessionSourceAction }
                  handleSubmit={ this.handleSourceSubmit }
                  error={ { error, clear: this.clearError } }
                  hasMap
                />

                <AccessionSectionTable
                  sectionName="sourceCooperators"
                  model={ { modelName: 'AccessionSourceMap', modelClass: AccessionSourceMap } }
847
848
849
850
                  tableConfig={ {
                    defaultColumns: [
                      'id',
                      'sourceTypeCode',
851
852
853
854
855
856
857
                      'sourceId',
                      'cooperatorId',
                      ...CooperatorTableDefaultConfig.defaultColumns,
                      'site',
                      'statusCode',
                      'categoryCode',
                      'disciplineCode',
858
                    ],
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
                    ignoredColumns: [ 'cooperator', 'accessionSource' ],
                    defaultColumnSettings: {
                      id: { readonly: true, align: TextAlign.right },
                      sourceId: { readonly: true, align: TextAlign.right },
                      cooperatorId: { readonly: true, align: TextAlign.right },
                      name: { readonly: true, label: ["client:model.Cooperator.name", "client:model._.name"] },
                      title: { align: TextAlign.right, label: "client:model.Cooperator.title" },
                      lastName: { label: "client:model.Cooperator.lastName" },
                      firstName: { label: "client:model.Cooperator.firstName" },
                      organization: { label: "client:model.Cooperator.organization" },
                      job: { label: "client:model.Cooperator.job" },
                      geography: { label: "client:model.Cooperator.geography" },
                      faoInstituteNumber: { label: "client:model.Cooperator.faoInstituteNumber" },
                      site: { label: "client:model.Cooperator.site" },
                      statusCode: { label: "client:model.Cooperator.statusCode" },
                      categoryCode: { label: "client:model.Cooperator.categoryCode" },
                      disciplineCode: { label: "client:model.Cooperator.disciplineCode" },
                    },
877
                    columnRenderers: {
878
                      ...CooperatorTableDefaultConfig.columnRenderers,
879
880
                      sourceTypeCode: ({ row: sourceMap }: { row: AccessionSourceMap }) => <CodeValueDisplay codeGroup={ AccessionSource.CodeGroup.sourceTypeCode } value={ sourceMap?.accessionSource?.sourceTypeCode } />,
                      sourceId: ({ row: sourceMap }: { row: AccessionSourceMap }) => sourceMap?.accessionSource && <>{ sourceMap.accessionSource.id }</>,
881
882
883
884
885
886
887
888
889
890
891
                      // Fix cooperator link!
                      name: ({ row: cooperator }: { row: Cooperator & { cooperatorId: number } }): JSX.Element => (
                        <Link to={ `/cooperator/${cooperator.cooperatorId}` }>
                          { (cooperator.firstName || cooperator.lastName) && (
                            <>{ cooperator.title } { cooperator.firstName } { cooperator.lastName }</>
                          ) }
                          { ! (cooperator.firstName || cooperator.lastName) && (
                            <>{ cooperator.organization }</>
                          ) }
                        </Link>
                      ),
892
893
                    },
                  } }
894
895
896
897
898
                  createDisabled={ accession.sources?.length === 0 }
                  customDialogTableConfig={ AccessionSourceTableDefaultConfig }
                  CustomDialog={ AccessionSourceMapDialog }
                  removeAction={ removeAccessionSourceMapAction }
                  handleSubmit={ this.handleSourceMapSubmit }
899
                  error={ { error, clear: this.clearError } }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
900
901
                />

Matija Obreza's avatar
Matija Obreza committed
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
                <AccessionSectionTable
                  sectionName="ipr"
                  model={ { modelName: 'AccessionIpr', modelClass: AccessionIpr } }
                  tableConfig={ {
                    defaultColumns: [
                      'id',
                      'typeCode',
                      'iprNumber',
                      'iprFullName',
                      'iprCropName',
                      'issuedDate',
                      'expectedDate',
                      'acceptedDate',
                      'expiredDate',
                    ],
917
918
919
920
921
922
923
924
925
926
                    defaultColumnSettings: {
                      sourceTypeCode: { label: 'client:model.AccessionSource.sourceTypeCode' },
                      name: { readonly: true, label: 'client:model.Cooperator.name' },
                      geography: { label: 'client:model.Cooperator.geography' },
                      site: { label: 'client:model.Cooperator.site' },
                      statusCode: { label: 'client:model.Cooperator.statusCode' },
                      categoryCode: { label: 'client:model.Cooperator.categoryCode' },
                      disciplineCode: { label: 'client:model.Cooperator.disciplineCode' },
                      title: { align: TextAlign.right, label: 'client:model.Cooperator.title' },
                    },
Matija Obreza's avatar
Matija Obreza committed
927
928
929
930
931
932
933
934
935
936
937
938
939
                    columnRenderers: {
                      acceptedDate: Renderers.DATE_RENDERER,
                      expectedDate: Renderers.DATE_RENDERER,
                      expiredDate: Renderers.DATE_RENDERER,
                      typeCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionIpr.CodeGroup.typeCode),
                    },
                  } }
                  dialogForm={ AccessionIprForm }
                  removeAction={ removeAccessionIprAction }
                  handleSubmit={ this.handleIprSubmit }
                  error={ { error, clear: this.clearError } }
                />

940
941
                <AccessionSectionTable
                  sectionName="pedigree"
Maksym Tishchenko's avatar
Maksym Tishchenko committed
942
                  model={ { modelName: 'AccessionPedigree', modelClass: AccessionPedigree } }
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
                  tableConfig={ {
                    defaultColumns: [
                      'id',
                      'crossCode',
                      'releasedDate',
                      'releasedDateCode',
                      'maleAccession',
                      'maleExternalAccession',
                      'femaleAccession',
                      'femaleExternalAccession',
                      'description',
                      'note',
                    ],
                    ignoredColumns: [ 'accession' ],
                    columnRenderers: {
                      crossCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionPedigree.CodeGroup.crossCode),
                      releasedDateCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionPedigree.CodeGroup.releasedDateCode),
                      releasedDate: Renderers.DATE_RENDERER,
                      establishedDate: Renderers.DATE_RENDERER,
                      expectedReleaseDate: Renderers.DATE_RENDERER,
                      custodialCooperator: ExtraRenderers.COOPERATORNAME_RENDERER,
                      maleAccession: ({ value }: { value: Accession }) => value && <AccessionLink accession={ value } />,
                      femaleAccession: ({ value }: { value: Accession }) => value && <AccessionLink accession={ value } />,
                    },
                  } }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
968
969
970
                  dialogForm={ AccessionPedigreeForm }
                  removeAction={ removeAccessionPedigreeAction }
                  handleSubmit={ this.handlePedigreeSubmit }
971
                  error={ { error, clear: this.clearError } }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
972
973
                />

974
975
                <AccessionSectionTable
                  sectionName="quarantine"
Maksym Tishchenko's avatar
Maksym Tishchenko committed
976
                  model={ { modelName: 'AccessionQuarantine', modelClass: AccessionQuarantine } }
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
                  tableConfig={ {
                    defaultColumns: [
                      'id',
                      'quarantineTypeCode',
                      'progressStatusCode',
                      'custodialCooperator',
                      'enteredDate',
                      'establishedDate',
                      'expectedReleaseDate',

                    ],
                    ignoredColumns: [ 'accession', 'inventory' ],
                    columnRenderers: {
                      quarantineTypeCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionQuarantine.CodeGroup.quarantineTypeCode),
                      progressStatusCode: ExtraRenderers.CODEVALUE_RENDERER(AccessionQuarantine.CodeGroup.progressStatusCode),
                      enteredDate: Renderers.DATE_RENDERER,
                      establishedDate: Renderers.DATE_RENDERER,
                      expectedReleaseDate: Renderers.DATE_RENDERER,
                      custodialCooperator: ExtraRenderers.COOPERATORNAME_RENDERER,
                    },
                  } }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
998
999
1000
                  dialogForm={ AccessionQuarantineForm }
                  removeAction={ removeAccessionQuarantineAction }
                  handleSubmit={ this.handleQuarantineSubmit }
For faster browsing, not all history is shown. View entire blame