Project

General

Profile

Download (20.8 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 Integer citationID;
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<Integer, RegistrationDetailsItem> registrationItemMap = new HashMap<>();
130

    
131
    /**
132
     * uses the registrationId as key
133
     */
134
    private Map<Integer, 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.citationID = Integer.valueOf(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(int registrationId, Set<RegistrationDTO> blockingRegDTOs) {
187

    
188
        RegistrationDetailsItem regItem = registrationItemMap.get(registrationId);
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(citationID, 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
        typifiedNamesMap.put(dto.getId(), dto.getTypifiedNameRef());
276

    
277
        RegistrationItemNameAndTypeButtons regItemButtonGroup = new RegistrationItemNameAndTypeButtons(dto);
278
        Integer registrationEntityID = dto.getId();
279

    
280
        RegistrationItemButtons regItemButtons = new RegistrationItemButtons();
281

    
282
        CssLayout footer = new CssLayout();
283
        footer.setWidth(100, Unit.PERCENTAGE);
284
        footer.setStyleName("item-footer");
285

    
286
        RegistrationDetailsItem regDetailsItem = new RegistrationDetailsItem(regItemButtonGroup, regItemButtons, footer);
287
        registrationItemMap.put(registrationEntityID, regDetailsItem);
288

    
289
        Stack<EditorActionContext> context = new Stack<EditorActionContext>();
290
        context.push(new EditorActionContext(
291
                    new TypedEntityReference<>(Registration.class, registrationEntityID),
292
                    this)
293
                    );
294

    
295
        if(regItemButtonGroup.getNameButton() != null){
296
            regItemButtonGroup.getNameButton().getButton().addClickListener(e -> {
297
                Integer nameId = regItemButtonGroup.getNameButton().getId();
298
                getViewEventBus().publish(this, new TaxonNameEditorAction(
299
                    EditorActionType.EDIT,
300
                    nameId,
301
                    e.getButton(),
302
                    this,
303
                    context
304
                    )
305
                );
306
            });
307
        }
308

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

    
328
        regItemButtonGroup.getAddTypeDesignationButton().addClickListener(
329
                e -> chooseNewTypeRegistrationWorkingset(dto.getId())
330
                );
331

    
332

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

    
351
        Button validationProblemsButton = regItemButtons.getValidationProblemsButton();
352
        validationProblemsButton.setStyleName(ValoTheme.BUTTON_TINY); //  + " " + RegistrationStyles.STYLE_FRIENDLY_FOREGROUND);
353

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

    
369
        Button messageButton = regItemButtons.getMessagesButton();
370
        messageButton.addClickListener(e -> getViewEventBus().publish(this,
371
                    new ShowDetailsEvent<RegistrationDTO, Integer>(
372
                        e,
373
                        RegistrationDTO.class,
374
                        dto.getId(),
375
                        RegistrationItem.MESSAGES
376
                        )
377
                    )
378
                );
379
        messageButton.setStyleName(ValoTheme.BUTTON_TINY);
380

    
381
        RegistrationStateLabel stateLabel = new RegistrationStateLabel().update(dto.getStatus());
382
        Label submitterLabel = new Label(dto.getSubmitterUserName());
383
        submitterLabel.setStyleName(LABEL_NOWRAP + " submitter");
384
        submitterLabel.setIcon(FontAwesome.USER);
385
        submitterLabel.setContentMode(ContentMode.HTML);
386
        CssLayout stateAndSubmitter = new CssLayout(stateLabel, submitterLabel);
387

    
388

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

    
402
        PermissionDebugUtils.addGainPerEntityPermissionButton(regItemButtons, Registration.class, dto.getId(),
403
                EnumSet.of(CRUD.UPDATE), RegistrationStatus.PREPARATION.name());
404

    
405
        row++;
406
        registrationsGrid.addComponent(stateAndSubmitter, COL_INDEX_STATE_LABEL, row);
407
        // registrationsGrid.setComponentAlignment(stateLabel, Alignment.TOP_LEFT);
408
        registrationsGrid.addComponent(regItemButtonGroup, COL_INDEX_REG_ITEM, row);
409
        registrationsGrid.addComponent(regItemButtons, COL_INDEX_BUTTON_GROUP, row);
410
        registrationsGrid.setComponentAlignment(regItemButtons, Alignment.TOP_LEFT);
411

    
412
        row++;
413
        registrationsGrid.addComponent(footer, 0, row, COL_INDEX_BUTTON_GROUP, row);
414

    
415
        return row;
416
    }
417

    
418
    /**
419
     * @param button
420
     * @param registrationEntityId
421
     *
422
     */
423
    @Override
424
    public void chooseNewTypeRegistrationWorkingset(Integer registrationEntityId) {
425

    
426
        Window typeDesignationTypeCooser = new Window();
427
        typeDesignationTypeCooser.setModal(true);
428
        typeDesignationTypeCooser.setResizable(false);
429
        typeDesignationTypeCooser.setCaption("Add new type designation");
430
        Label label = new Label("Please select kind of type designation to be created.");
431
        Button newSpecimenTypeDesignationButton = new Button("Specimen type designation",
432
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET, registrationEntityId, typeDesignationTypeCooser));
433
        Button newNameTypeDesignationButton = new Button("Name type designation",
434
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET, registrationEntityId, typeDesignationTypeCooser));
435

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

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

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

    
469
    }
470

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

    
478
    }
479

    
480
    /**
481
     * {@inheritDoc}
482
     */
483
    @Override
484
    protected String getHeaderText() {
485
        return headerText;
486
    }
487

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

    
496
    }
497

    
498
    /**
499
     * @return the subheaderText
500
     */
501
    public String getSubheaderText() {
502
        return subheaderText;
503
    }
504

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

    
514
    /**
515
     * {@inheritDoc}
516
     */
517
    @Override
518
    protected String getSubHeaderText() {
519
        return subheaderText;
520
    }
521

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

    
534
    /**
535
     * {@inheritDoc}
536
     */
537
    @Override
538
    public boolean allowAnonymousAccess() {
539
        return false;
540
    }
541

    
542
    /**
543
     * {@inheritDoc}
544
     */
545
    @Override
546
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
547
        return null;
548
    }
549

    
550
    /**
551
     * @return the addNewNameRegistrationButton
552
     */
553
    @Override
554
    public Button getAddNewNameRegistrationButton() {
555
        return addNewNameRegistrationButton;
556
    }
557

    
558
    @Override
559
    public Button getAddExistingNameRegistrationButton() {
560
        return addExistingNameButton;
561
    }
562

    
563
    @Override
564
    public LazyComboBox<TaxonName> getAddExistingNameCombobox() {
565
        return existingNameCombobox;
566
    }
567

    
568
    /**
569
     * @return the citationID
570
     */
571
    @Override
572
    public Integer getCitationID() {
573
        return citationID;
574
    }
575

    
576
    @Override
577
    public Map<Integer, RegistrationDetailsItem> getRegistrationItemMap(){
578
        return Collections.unmodifiableMap(registrationItemMap);
579
    }
580

    
581

    
582
}
(18-18/23)