Project

General

Profile

Download (21 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.view.registration;
10

    
11
import static eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStyles.LABEL_NOWRAP;
12

    
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.Collections;
16
import java.util.EnumSet;
17
import java.util.HashMap;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.Stack;
23
import java.util.UUID;
24

    
25
import org.springframework.security.core.GrantedAuthority;
26
import org.vaadin.viritin.fields.LazyComboBox;
27

    
28
import com.vaadin.navigator.View;
29
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
30
import com.vaadin.server.FontAwesome;
31
import com.vaadin.server.Page;
32
import com.vaadin.shared.ui.label.ContentMode;
33
import com.vaadin.spring.annotation.SpringView;
34
import com.vaadin.ui.Alignment;
35
import com.vaadin.ui.Button;
36
import com.vaadin.ui.CssLayout;
37
import com.vaadin.ui.GridLayout;
38
import com.vaadin.ui.HorizontalLayout;
39
import com.vaadin.ui.Label;
40
import com.vaadin.ui.Notification;
41
import com.vaadin.ui.Panel;
42
import com.vaadin.ui.UI;
43
import com.vaadin.ui.VerticalLayout;
44
import com.vaadin.ui.Window;
45
import com.vaadin.ui.themes.ValoTheme;
46

    
47
import eu.etaxonomy.cdm.model.name.Registration;
48
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
49
import eu.etaxonomy.cdm.model.name.TaxonName;
50
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
51
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItem;
52
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItemButtons;
53
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItemNameAndTypeButtons;
54
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItemNameAndTypeButtons.TypeDesignationWorkingSetButton;
55
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItemsPanel;
56
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStateLabel;
57
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStyles;
58
import eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.EditorActionContext;
59
import eu.etaxonomy.cdm.vaadin.event.RegistrationEditorAction;
60
import eu.etaxonomy.cdm.vaadin.event.ShowDetailsEvent;
61
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
62
import eu.etaxonomy.cdm.vaadin.event.TypeDesignationWorkingsetEditorAction;
63
import eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkingsetAction;
64
import eu.etaxonomy.cdm.vaadin.model.EntityReference;
65
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
66
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
67
import eu.etaxonomy.cdm.vaadin.security.AccessRestrictedView;
68
import eu.etaxonomy.cdm.vaadin.security.PermissionDebugUtils;
69
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
70
import eu.etaxonomy.cdm.vaadin.theme.EditValoTheme;
71
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSetType;
72
import eu.etaxonomy.cdm.vaadin.view.AbstractPageView;
73
import eu.etaxonomy.vaadin.event.EditorActionType;
74

    
75
/**
76
 * @author a.kohlbecker
77
 * @since Mar 2, 2017
78
 *
79
 */
80
@SpringView(name=RegistrationWorksetViewBean.NAME)
81
public class RegistrationWorksetViewBean extends AbstractPageView<RegistrationWorkingsetPresenter>
82
    implements RegistrationWorkingsetView, View, AccessRestrictedView {
83

    
84
    /**
85
     *
86
     */
87
    private static final int COL_INDEX_STATE_LABEL = 0;
88

    
89
    /**
90
     *
91
     */
92
    private static final int COL_INDEX_REG_ITEM = 1;
93

    
94
    /**
95
     *
96
     */
97
    private static final int COL_INDEX_BUTTON_GROUP = 2;
98

    
99
    public static final String DOM_ID_WORKINGSET = "workingset";
100

    
101
    private static final long serialVersionUID = -213040114015958970L;
102

    
103
    public static final String NAME = "workingset";
104

    
105
    public RegistrationType regType = null;
106

    
107
    private List<CssLayout> registrations = new ArrayList<>();
108

    
109
    private String headerText = "Registration Workingset Editor";
110
    private String subheaderText = "";
111

    
112
    private UUID citationUuid;
113

    
114
    private Button addNewNameRegistrationButton;
115

    
116
    private LazyComboBox<TaxonName> existingNameCombobox;
117

    
118
    private GridLayout registrationsGrid;
119

    
120
    private Button addExistingNameButton;
121

    
122
    private RegistrationItem workingsetHeader;
123

    
124
    private Panel registrationListPanel;
125

    
126
    /**
127
     * uses the registrationId as key
128
     */
129
    private Map<UUID, RegistrationDetailsItem> registrationItemMap = new HashMap<>();
130

    
131
    /**
132
     * uses the registrationId as key
133
     */
134
    private Map<UUID, EntityReference> typifiedNamesMap = new HashMap<>();
135

    
136
    public RegistrationWorksetViewBean() {
137
        super();
138
    }
139

    
140

    
141
    /**
142
     * {@inheritDoc}
143
     */
144
    @Override
145
    protected void initContent() {
146
        getLayout().setId(NAME);
147
        updateHeader();
148
        // all content is added in createRegistrationsList()
149
    }
150

    
151

    
152
    /**
153
     * {@inheritDoc}
154
     */
155
    @Override
156
    public void enter(ViewChangeEvent event) {
157
        if(event.getParameters() != null){
158
            this.citationUuid = UUID.fromString(event.getParameters());
159

    
160
            getPresenter().handleViewEntered();
161
        }
162
    }
163

    
164
    /**
165
     * {@inheritDoc}
166
     */
167
    @Override
168
    public void setWorkingset(RegistrationWorkingSet workingset) {
169

    
170
        if(workingsetHeader != null){
171
            getLayout().removeComponent(workingsetHeader);
172
            getLayout().removeComponent(registrationListPanel);
173
        }
174
        workingsetHeader = new RegistrationItem(workingset, this);
175
        addContentComponent(workingsetHeader, null);
176

    
177
        registrationListPanel = createRegistrationsList(workingset);
178
        registrationListPanel.setHeight("100%");
179
        registrationListPanel.setStyleName("registration-list");
180
        registrationListPanel.setCaption("Registrations");
181
        addContentComponent(registrationListPanel, 1.0f);
182

    
183
    }
184

    
185
    @Override
186
    public void setBlockingRegistrations(UUID registrationUuid, Set<RegistrationDTO> blockingRegDTOs) {
187

    
188
        RegistrationDetailsItem regItem = registrationItemMap.get(registrationUuid);
189

    
190
        boolean blockingRegAdded = false;
191
        for(Iterator it = regItem.itemFooter.iterator(); it.hasNext(); ){
192
            if(it.next() instanceof RegistrationItemsPanel){
193
                blockingRegAdded = true;
194
                break;
195
            }
196
        }
197
        if(!blockingRegAdded){
198
            regItem.itemFooter.addComponent(new RegistrationItemsPanel(this, "Blocked by", blockingRegDTOs));
199
        }
200
    }
201

    
202
    /**
203
     * {@inheritDoc}
204
     */
205
    @Override
206
    @Deprecated // no longer needed
207
    public void addBlockingRegistration(RegistrationDTO blocking) {
208
        if(registrations == null) {
209
            throw new RuntimeException("A Workingset must be present prior adding blocking registrations.");
210
        }
211
        // add the blocking registration
212

    
213
    }
214

    
215
    /**
216
     * @param workingset
217
     * @return
218
     */
219
    public Panel createRegistrationsList(RegistrationWorkingSet workingset) {
220

    
221
        registrationsGrid = new GridLayout(3, 1);
222
        registrationsGrid.setWidth("100%");
223
        // allow vertical scrolling:
224
        registrationsGrid.setHeightUndefined();
225

    
226
        //registrationsGrid.setColumnExpandRatio(0, 0.1f);
227
        registrationsGrid.setColumnExpandRatio(1, 1f);
228

    
229
        registrationItemMap.clear();
230
        registrationsGrid.setRows(workingset.getRegistrationDTOs().size() * 2  + 2);
231
        int row = 0;
232
        for(RegistrationDTO dto : workingset.getRegistrationDTOs()) {
233
            row = putRegistrationListComponent(row, dto);
234
        }
235

    
236
        Label addRegistrationLabel_1 = new Label("Add a new registration for a");
237
        Label addRegistrationLabel_2 = new Label("or an");
238

    
239
        addNewNameRegistrationButton = new Button("new name");
240
        addNewNameRegistrationButton.setDescription("A name which is newly published in this publication.");
241
        addNewNameRegistrationButton.addClickListener(
242
                e -> getViewEventBus().publish(this, new TaxonNameEditorAction(EditorActionType.ADD, null, addNewNameRegistrationButton, this)));
243

    
244
        addExistingNameButton = new Button("existing name:");
245
        addExistingNameButton.setDescription("A name which was previously published in a earlier publication.");
246
        addExistingNameButton.setEnabled(false);
247
        addExistingNameButton.addClickListener(
248
                e -> getViewEventBus().publish(this, new RegistrationWorkingsetAction(citationUuid, RegistrationWorkingsetAction.Action.start))
249
                );
250

    
251
        existingNameCombobox = new LazyComboBox<TaxonName>(TaxonName.class);
252
        existingNameCombobox.addValueChangeListener(
253
                e -> addExistingNameButton.setEnabled(e.getProperty().getValue() != null)
254
                );
255

    
256
        HorizontalLayout buttonContainer = new HorizontalLayout(addRegistrationLabel_1, addNewNameRegistrationButton, addRegistrationLabel_2, addExistingNameButton, existingNameCombobox);
257
        buttonContainer.setSpacing(true);
258
//        buttonContainer.setWidth(100, Unit.PERCENTAGE);
259
        buttonContainer.setComponentAlignment(addRegistrationLabel_1, Alignment.MIDDLE_LEFT);
260
        buttonContainer.setComponentAlignment(addRegistrationLabel_2, Alignment.MIDDLE_LEFT);
261

    
262
        row++;
263
        registrationsGrid.addComponent(buttonContainer, 0, row, COL_INDEX_BUTTON_GROUP, row);
264
        registrationsGrid.setComponentAlignment(buttonContainer, Alignment.MIDDLE_RIGHT);
265

    
266
        Panel namesTypesPanel = new Panel(registrationsGrid);
267
        namesTypesPanel.setStyleName(EditValoTheme.PANEL_CONTENT_PADDING_LEFT);
268
        return namesTypesPanel;
269
    }
270

    
271

    
272

    
273
    protected int putRegistrationListComponent(int row, RegistrationDTO dto) {
274

    
275
        EntityReference typifiedNameReference = dto.getTypifiedNameRef();
276
        if(typifiedNameReference == null){
277
            typifiedNameReference = dto.getNameRef();
278
        }
279
        typifiedNamesMap.put(dto.getUuid(), typifiedNameReference);
280

    
281
        RegistrationItemNameAndTypeButtons regItemButtonGroup = new RegistrationItemNameAndTypeButtons(dto);
282
        UUID registrationEntityUuid = dto.getUuid();
283

    
284
        RegistrationItemButtons regItemButtons = new RegistrationItemButtons();
285

    
286
        CssLayout footer = new CssLayout();
287
        footer.setWidth(100, Unit.PERCENTAGE);
288
        footer.setStyleName("item-footer");
289

    
290
        RegistrationDetailsItem regDetailsItem = new RegistrationDetailsItem(regItemButtonGroup, regItemButtons, footer);
291
        registrationItemMap.put(registrationEntityUuid, regDetailsItem);
292

    
293
        Stack<EditorActionContext> context = new Stack<EditorActionContext>();
294
        context.push(new EditorActionContext(
295
                    new TypedEntityReference<>(Registration.class, registrationEntityUuid),
296
                    this)
297
                    );
298

    
299
        if(regItemButtonGroup.getNameButton() != null){
300
            regItemButtonGroup.getNameButton().getButton().addClickListener(e -> {
301
                UUID nameuUuid = regItemButtonGroup.getNameButton().getUuid();
302
                getViewEventBus().publish(this, new TaxonNameEditorAction(
303
                    EditorActionType.EDIT,
304
                    nameuUuid,
305
                    e.getButton(),
306
                    this,
307
                    context
308
                    )
309
                );
310
            });
311
        }
312

    
313
        for(TypeDesignationWorkingSetButton workingsetButton : regItemButtonGroup.getTypeDesignationButtons()){
314
            workingsetButton.getButton().addClickListener(e -> {
315
                TypedEntityReference baseEntityRef = workingsetButton.getBaseEntity();
316
                EntityReference typifiedNameRef = typifiedNamesMap.get(registrationEntityUuid);
317
                TypeDesignationWorkingSetType workingsetType = workingsetButton.getType();
318
                getViewEventBus().publish(this, new TypeDesignationWorkingsetEditorAction(
319
                        EditorActionType.EDIT,
320
                        baseEntityRef,
321
                        workingsetType,
322
                        registrationEntityUuid,
323
                        typifiedNameRef.getUuid(),
324
                        e.getButton(),
325
                        this,
326
                        context
327
                        )
328
                    );
329
            });
330
        }
331

    
332
        regItemButtonGroup.getAddTypeDesignationButton().addClickListener(
333
                e -> chooseNewTypeRegistrationWorkingset(dto.getUuid())
334
                );
335

    
336

    
337
        Button blockingRegistrationButton = regItemButtons.getBlockingRegistrationButton();
338
        blockingRegistrationButton.setStyleName(ValoTheme.BUTTON_TINY);
339
        blockingRegistrationButton.setDescription("No blocking registrations");
340
        if(dto.isBlocked()){
341
            blockingRegistrationButton.setEnabled(true);
342
            blockingRegistrationButton.setDescription("This registration is currently blocked by other registrations");
343
            blockingRegistrationButton.addStyleName(EditValoTheme.BUTTON_HIGHLITE);
344
            blockingRegistrationButton.addClickListener(e -> getViewEventBus().publish(
345
                    this,
346
                    new ShowDetailsEvent<RegistrationDTO, UUID>(
347
                            e,
348
                            RegistrationDTO.class,
349
                            dto.getUuid(),
350
                            RegistrationItem.BLOCKED_BY
351
                            )
352
                    ));
353
        }
354

    
355
        Button validationProblemsButton = regItemButtons.getValidationProblemsButton();
356
        validationProblemsButton.setStyleName(ValoTheme.BUTTON_TINY); //  + " " + RegistrationStyles.STYLE_FRIENDLY_FOREGROUND);
357

    
358
        if(!dto.getValidationProblems().isEmpty()){
359
            validationProblemsButton.setEnabled(true);
360
            validationProblemsButton.addClickListener(e -> getViewEventBus().publish(this,
361
                    new ShowDetailsEvent<RegistrationDTO, UUID>(
362
                        e,
363
                        RegistrationDTO.class,
364
                        dto.getUuid(),
365
                        RegistrationItem.VALIDATION_PROBLEMS
366
                        )
367
                    )
368
                );
369
        }
370
        validationProblemsButton.setCaption("<span class=\"" + RegistrationStyles.BUTTON_BADGE +"\"> " + dto.getValidationProblems().size() + "</span>");
371
        validationProblemsButton.setCaptionAsHtml(true);
372

    
373
        Button messageButton = regItemButtons.getMessagesButton();
374
        messageButton.addClickListener(e -> getViewEventBus().publish(this,
375
                    new ShowDetailsEvent<RegistrationDTO, UUID>(
376
                        e,
377
                        RegistrationDTO.class,
378
                        dto.getUuid(),
379
                        RegistrationItem.MESSAGES
380
                        )
381
                    )
382
                );
383
        messageButton.setStyleName(ValoTheme.BUTTON_TINY);
384

    
385
        RegistrationStateLabel stateLabel = new RegistrationStateLabel().update(dto.getStatus());
386
        Label submitterLabel = new Label(dto.getSubmitterUserName());
387
        submitterLabel.setStyleName(LABEL_NOWRAP + " submitter");
388
        submitterLabel.setIcon(FontAwesome.USER);
389
        submitterLabel.setContentMode(ContentMode.HTML);
390
        CssLayout stateAndSubmitter = new CssLayout(stateLabel, submitterLabel);
391

    
392

    
393
        if(UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin()) {
394
            Button editRegistrationButton = new Button(FontAwesome.COG);
395
            editRegistrationButton.setStyleName(ValoTheme.BUTTON_TINY);
396
            editRegistrationButton.setDescription("Edit registration");
397
            editRegistrationButton.addClickListener(e -> getViewEventBus().publish(this, new RegistrationEditorAction(
398
                EditorActionType.EDIT,
399
                dto.getUuid(),
400
                null,
401
                this
402
                )));
403
            regItemButtons.addComponent(editRegistrationButton);
404
        }
405

    
406
        PermissionDebugUtils.addGainPerEntityPermissionButton(regItemButtons, Registration.class, dto.getUuid(),
407
                EnumSet.of(CRUD.UPDATE), RegistrationStatus.PREPARATION.name());
408

    
409
        row++;
410
        registrationsGrid.addComponent(stateAndSubmitter, COL_INDEX_STATE_LABEL, row);
411
        // registrationsGrid.setComponentAlignment(stateLabel, Alignment.TOP_LEFT);
412
        registrationsGrid.addComponent(regItemButtonGroup, COL_INDEX_REG_ITEM, row);
413
        registrationsGrid.addComponent(regItemButtons, COL_INDEX_BUTTON_GROUP, row);
414
        registrationsGrid.setComponentAlignment(regItemButtons, Alignment.TOP_LEFT);
415

    
416
        row++;
417
        registrationsGrid.addComponent(footer, 0, row, COL_INDEX_BUTTON_GROUP, row);
418

    
419
        return row;
420
    }
421

    
422
    /**
423
     * @param button
424
     * @param registrationEntityId
425
     *
426
     */
427
    @Override
428
    public void chooseNewTypeRegistrationWorkingset(UUID registrationEntityUuid){
429
        Window typeDesignationTypeCooser = new Window();
430
        typeDesignationTypeCooser.setModal(true);
431
        typeDesignationTypeCooser.setResizable(false);
432
        typeDesignationTypeCooser.setCaption("Add new type designation");
433
        Label label = new Label("Please select kind of type designation to be created.");
434
        Button newSpecimenTypeDesignationButton = new Button("Specimen type designation",
435
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET, registrationEntityUuid, typeDesignationTypeCooser));
436
        Button newNameTypeDesignationButton = new Button("Name type designation",
437
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET, registrationEntityUuid, typeDesignationTypeCooser));
438

    
439
        VerticalLayout layout = new VerticalLayout(label, newSpecimenTypeDesignationButton, newNameTypeDesignationButton);
440
        layout.setMargin(true);
441
        layout.setSpacing(true);
442
        layout.setComponentAlignment(newSpecimenTypeDesignationButton, Alignment.MIDDLE_CENTER);
443
        layout.setComponentAlignment(newNameTypeDesignationButton, Alignment.MIDDLE_CENTER);
444
        typeDesignationTypeCooser.setContent(layout);
445
        UI.getCurrent().addWindow(typeDesignationTypeCooser);
446
    }
447

    
448
    /**
449
     * @param button
450
     *
451
     */
452
    protected void addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType newWorkingsetType, UUID registrationEntityUuid, Window typeDesignationTypeCooser) {
453
        UI.getCurrent().removeWindow(typeDesignationTypeCooser);
454
        EntityReference typifiedNameRef = typifiedNamesMap.get(registrationEntityUuid);
455
        getViewEventBus().publish(this, new TypeDesignationWorkingsetEditorAction(
456
                EditorActionType.ADD,
457
                newWorkingsetType,
458
                registrationEntityUuid,
459
                typifiedNameRef.getUuid(),
460
                null,
461
                this
462
                ));
463
    }
464

    
465
    /**
466
     * {@inheritDoc}
467
     */
468
    @Override
469
    public void openReferenceEditor(UUID referenceUuid) {
470
        // TODO Auto-generated method stub
471

    
472
    }
473

    
474
    /**
475
     * {@inheritDoc}
476
     */
477
    @Override
478
    public void openNameEditor(UUID nameUuid) {
479
        // TODO Auto-generated method stub
480

    
481
    }
482

    
483
    /**
484
     * {@inheritDoc}
485
     */
486
    @Override
487
    protected String getHeaderText() {
488
        return headerText;
489
    }
490

    
491
    /**
492
     * {@inheritDoc}
493
     */
494
    @Override
495
    public void setHeaderText(String text) {
496
        this.headerText = text;
497
        updateHeader();
498

    
499
    }
500

    
501
    /**
502
     * @return the subheaderText
503
     */
504
    public String getSubheaderText() {
505
        return subheaderText;
506
    }
507

    
508
    /**
509
     * {@inheritDoc}
510
     */
511
    @Override
512
    public void setSubheaderText(String text) {
513
        subheaderText = text;
514
        updateHeader();
515
    }
516

    
517
    /**
518
     * {@inheritDoc}
519
     */
520
    @Override
521
    protected String getSubHeaderText() {
522
        return subheaderText;
523
    }
524

    
525
    /**
526
     * {@inheritDoc}
527
     */
528
    @Override
529
    public void openDetailsPopup(String caption, List<String> messages) {
530
        StringBuffer sb = new StringBuffer();
531
        sb.append("<div class=\"details-popup-content\">");
532
        messages.forEach(s -> sb.append(s).append("</br>"));
533
        sb.append("</div>");
534
        new Notification(caption, sb.toString(), Notification.Type.HUMANIZED_MESSAGE, true).show(Page.getCurrent());
535
    }
536

    
537
    /**
538
     * {@inheritDoc}
539
     */
540
    @Override
541
    public boolean allowAnonymousAccess() {
542
        return false;
543
    }
544

    
545
    /**
546
     * {@inheritDoc}
547
     */
548
    @Override
549
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
550
        return null;
551
    }
552

    
553
    /**
554
     * @return the addNewNameRegistrationButton
555
     */
556
    @Override
557
    public Button getAddNewNameRegistrationButton() {
558
        return addNewNameRegistrationButton;
559
    }
560

    
561
    @Override
562
    public Button getAddExistingNameRegistrationButton() {
563
        return addExistingNameButton;
564
    }
565

    
566
    @Override
567
    public LazyComboBox<TaxonName> getAddExistingNameCombobox() {
568
        return existingNameCombobox;
569
    }
570

    
571
    /**
572
     * @return the citationID
573
     */
574
    @Override
575
    public UUID getCitationUuid() {
576
        return citationUuid;
577
    }
578

    
579
    @Override
580
    public Map<UUID, RegistrationDetailsItem> getRegistrationItemMap(){
581
        return Collections.unmodifiableMap(registrationItemMap);
582
    }
583

    
584

    
585
}
(18-18/23)