Project

General

Profile

Download (19.2 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 java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.EnumSet;
14
import java.util.HashMap;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.Stack;
20
import java.util.UUID;
21

    
22
import org.springframework.security.core.GrantedAuthority;
23
import org.vaadin.viritin.fields.LazyComboBox;
24

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

    
43
import eu.etaxonomy.cdm.model.name.Registration;
44
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
45
import eu.etaxonomy.cdm.model.name.TaxonName;
46
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
47
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItem;
48
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItemEditButtonGroup;
49
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItemEditButtonGroup.TypeDesignationWorkingSetButton;
50
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItemsPanel;
51
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStateLabel;
52
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStyles;
53
import eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.EditorActionContext;
54
import eu.etaxonomy.cdm.vaadin.event.RegistrationEditorAction;
55
import eu.etaxonomy.cdm.vaadin.event.ShowDetailsEvent;
56
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
57
import eu.etaxonomy.cdm.vaadin.event.TypeDesignationWorkingsetEditorAction;
58
import eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkingsetAction;
59
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
60
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
61
import eu.etaxonomy.cdm.vaadin.security.AccessRestrictedView;
62
import eu.etaxonomy.cdm.vaadin.security.PermissionDebugUtils;
63
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
64
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSetType;
65
import eu.etaxonomy.cdm.vaadin.view.AbstractPageView;
66
import eu.etaxonomy.vaadin.event.EditorActionType;
67

    
68
/**
69
 * @author a.kohlbecker
70
 * @since Mar 2, 2017
71
 *
72
 */
73
@SpringView(name=RegistrationWorksetViewBean.NAME)
74
public class RegistrationWorksetViewBean extends AbstractPageView<RegistrationWorkingsetPresenter>
75
    implements RegistrationWorkingsetView, View, AccessRestrictedView {
76

    
77
    private class RegistrationDetailsItem {
78

    
79
        RegistrationItemEditButtonGroup registrationItemEditButtonGroup;
80
        CssLayout itemFooter;
81

    
82
        public RegistrationDetailsItem(RegistrationItemEditButtonGroup registrationItemEditButtonGroup, CssLayout itemFooter){
83
            this.registrationItemEditButtonGroup = registrationItemEditButtonGroup;
84
            this.itemFooter = itemFooter;
85
        }
86

    
87

    
88
    }
89

    
90
    /**
91
     *
92
     */
93
    private static final int COL_INDEX_STATE_LABEL = 0;
94

    
95
    /**
96
     *
97
     */
98
    private static final int COL_INDEX_REG_ITEM = 1;
99

    
100
    /**
101
     *
102
     */
103
    private static final int COL_INDEX_BUTTON_GROUP = 2;
104

    
105
    public static final String DOM_ID_WORKINGSET = "workingset";
106

    
107
    private static final long serialVersionUID = -213040114015958970L;
108

    
109
    public static final String NAME = "workingset";
110

    
111
    public RegistrationType regType = null;
112

    
113
    private List<CssLayout> registrations = new ArrayList<>();
114

    
115
    private String headerText = "Registration Workingset Editor";
116
    private String subheaderText = "";
117

    
118
    private Integer citationID;
119

    
120
    private Button addNewNameRegistrationButton;
121

    
122
    private LazyComboBox<TaxonName> existingNameCombobox;
123

    
124
    private GridLayout registrationsGrid;
125

    
126
    private Button addExistingNameButton;
127

    
128
    private RegistrationItem workingsetHeader;
129

    
130
    private Panel registrationListPanel;
131

    
132
    private Map<Integer, RegistrationDetailsItem> registrationItemMap = new HashMap<>();
133

    
134
    public RegistrationWorksetViewBean() {
135
        super();
136
    }
137

    
138

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

    
149

    
150
    /**
151
     * {@inheritDoc}
152
     */
153
    @Override
154
    public void enter(ViewChangeEvent event) {
155
        if(event.getParameters() != null){
156
            this.citationID = Integer.valueOf(event.getParameters());
157

    
158
            getPresenter().handleViewEntered();
159
        }
160
    }
161

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

    
168
        if(workingsetHeader != null){
169
            getLayout().removeComponent(workingsetHeader);
170
            getLayout().removeComponent(registrationListPanel);
171
        }
172
        workingsetHeader = new RegistrationItem(workingset, this);
173
        if(UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin()){
174
            workingsetHeader.getSubmitterLabel().setVisible(true);
175
        }
176
        addContentComponent(workingsetHeader, null);
177

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

    
184
    }
185

    
186
    @Override
187
    public void setBlockingRegistrations(int registrationId, Set<RegistrationDTO> blockingRegDTOs) {
188

    
189
        RegistrationDetailsItem regItem = registrationItemMap.get(registrationId);
190

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

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

    
214
    }
215

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

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

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

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

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

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

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

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

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

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

    
267
        Panel namesTypesPanel = new Panel(registrationsGrid);
268
        return namesTypesPanel;
269
    }
270

    
271

    
272

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

    
275
        RegistrationItemEditButtonGroup regItemButtonGroup = new RegistrationItemEditButtonGroup(dto);
276
        Integer registrationEntityID = dto.getId();
277
        CssLayout footer = new CssLayout();
278
        footer.setWidth(100, Unit.PERCENTAGE);
279
        footer.setStyleName("item-footer");
280
        RegistrationDetailsItem regDetailsItem = new RegistrationDetailsItem(regItemButtonGroup, footer);
281
        registrationItemMap.put(registrationEntityID, regDetailsItem);
282
        Stack<EditorActionContext> context = new Stack<EditorActionContext>();
283
        context.push(new EditorActionContext(
284
                    new TypedEntityReference<>(Registration.class, registrationEntityID),
285
                    this)
286
                    );
287

    
288
        if(regItemButtonGroup.getNameButton() != null){
289
            regItemButtonGroup.getNameButton().getButton().addClickListener(e -> {
290
                Integer nameId = regItemButtonGroup.getNameButton().getId();
291
                getViewEventBus().publish(this, new TaxonNameEditorAction(
292
                    EditorActionType.EDIT,
293
                    nameId,
294
                    e.getButton(),
295
                    this,
296
                    context
297
                    )
298
                );
299
            });
300
        }
301

    
302
        for(TypeDesignationWorkingSetButton workingsetButton : regItemButtonGroup.getTypeDesignationButtons()){
303
            workingsetButton.getButton().addClickListener(e -> {
304
                TypedEntityReference baseEntityRef = workingsetButton.getBaseEntity();
305
                TypeDesignationWorkingSetType workingsetType = workingsetButton.getType();
306
                getViewEventBus().publish(this, new TypeDesignationWorkingsetEditorAction(
307
                        EditorActionType.EDIT,
308
                        baseEntityRef,
309
                        workingsetType,
310
                        registrationEntityID,
311
                        e.getButton(),
312
                        this,
313
                        context
314
                        )
315
                    );
316
            });
317
        }
318

    
319
        regItemButtonGroup.getAddTypeDesignationButton().addClickListener(
320
                e -> chooseNewTypeRegistrationWorkingset(dto.getId())
321
                );
322

    
323

    
324
        CssLayout buttonGroup = new CssLayout();
325
        buttonGroup.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
326

    
327
        Button blockingRegistrationButton = new Button(FontAwesome.WARNING);
328
        blockingRegistrationButton.setStyleName(ValoTheme.BUTTON_TINY);
329
        if(!dto.isBlocked()){
330
            blockingRegistrationButton.setEnabled(false);
331
        } else {
332
            blockingRegistrationButton.addClickListener(e -> getViewEventBus().publish(
333
                    this,
334
                    new ShowDetailsEvent<RegistrationDTO, Integer>(
335
                            e,
336
                            RegistrationDTO.class,
337
                            dto.getId(),
338
                            "blockedBy"
339
                            )
340
                    ));
341
        }
342
        buttonGroup.addComponent(blockingRegistrationButton);
343

    
344
        Button messageButton = new Button(FontAwesome.COMMENT);
345
        messageButton.setStyleName(ValoTheme.BUTTON_TINY); //  + " " + RegistrationStyles.STYLE_FRIENDLY_FOREGROUND);
346
        if(dto.getMessages().isEmpty()){
347
            messageButton.setEnabled(false);
348
        } else {
349
            messageButton.addClickListener(e -> getViewEventBus().publish(this,
350
                    new ShowDetailsEvent<RegistrationDTO, Integer>(
351
                        e,
352
                        RegistrationDTO.class,
353
                        dto.getId(),
354
                        "messages"
355
                        )
356
                    )
357
                );
358
        }
359
        messageButton.setCaption("<span class=\"" + RegistrationStyles.BUTTON_BADGE +"\"> " + dto.getMessages().size() + "</span>");
360
        messageButton.setCaptionAsHtml(true);
361
        buttonGroup.addComponent(messageButton);
362

    
363
        RegistrationStateLabel stateLabel = new RegistrationStateLabel().update(dto.getStatus());
364

    
365

    
366
        if(UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin()) {
367
            Button editRegistrationButton = new Button(FontAwesome.COG);
368
            editRegistrationButton.setStyleName(ValoTheme.BUTTON_TINY);
369
            editRegistrationButton.setDescription("Edit registration");
370
            editRegistrationButton.addClickListener(e -> getViewEventBus().publish(this, new RegistrationEditorAction(
371
                EditorActionType.EDIT,
372
                dto.getId(),
373
                null,
374
                this
375
                )));
376
            buttonGroup.addComponent(editRegistrationButton);
377
        }
378

    
379
        PermissionDebugUtils.addGainPerEntityPermissionButton(buttonGroup, Registration.class, dto.getId(),
380
                EnumSet.of(CRUD.UPDATE), RegistrationStatus.PREPARATION.name());
381

    
382
        row++;
383
        registrationsGrid.addComponent(stateLabel, COL_INDEX_STATE_LABEL, row);
384
        registrationsGrid.setComponentAlignment(stateLabel, Alignment.TOP_LEFT);
385
        registrationsGrid.addComponent(regItemButtonGroup, COL_INDEX_REG_ITEM, row);
386
        registrationsGrid.addComponent(buttonGroup, COL_INDEX_BUTTON_GROUP, row);
387
        registrationsGrid.setComponentAlignment(buttonGroup, Alignment.TOP_LEFT);
388

    
389
        row++;
390
        registrationsGrid.addComponent(footer, 0, row, COL_INDEX_BUTTON_GROUP, row);
391

    
392
        return row;
393
    }
394

    
395
    /**
396
     * @param button
397
     * @param registrationEntityId
398
     *
399
     */
400
    @Override
401
    public void chooseNewTypeRegistrationWorkingset(Integer registrationEntityId) {
402

    
403
        Window typeDesignationTypeCooser = new Window();
404
        typeDesignationTypeCooser.setModal(true);
405
        typeDesignationTypeCooser.setResizable(false);
406
        typeDesignationTypeCooser.setCaption("Add new type designation");
407
        Label label = new Label("Please select kind of type designation to be created.");
408
        Button newSpecimenTypeDesignationButton = new Button("Specimen type designation",
409
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET, registrationEntityId, typeDesignationTypeCooser));
410
        Button newNameTypeDesignationButton = new Button("Name type designation",
411
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET, registrationEntityId, typeDesignationTypeCooser));
412

    
413
        VerticalLayout layout = new VerticalLayout(label, newSpecimenTypeDesignationButton, newNameTypeDesignationButton);
414
        layout.setMargin(true);
415
        layout.setSpacing(true);
416
        layout.setComponentAlignment(newSpecimenTypeDesignationButton, Alignment.MIDDLE_CENTER);
417
        layout.setComponentAlignment(newNameTypeDesignationButton, Alignment.MIDDLE_CENTER);
418
        typeDesignationTypeCooser.setContent(layout);
419
        UI.getCurrent().addWindow(typeDesignationTypeCooser);
420
    }
421

    
422
    /**
423
     * @param button
424
     *
425
     */
426
    protected void addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType newWorkingsetType, Integer registrationEntityId, Window typeDesignationTypeCooser) {
427
        UI.getCurrent().removeWindow(typeDesignationTypeCooser);
428
        getViewEventBus().publish(this, new TypeDesignationWorkingsetEditorAction(
429
                EditorActionType.ADD,
430
                newWorkingsetType,
431
                registrationEntityId,
432
                null,
433
                this
434
                ));
435
    }
436

    
437
    /**
438
     * {@inheritDoc}
439
     */
440
    @Override
441
    public void openReferenceEditor(UUID referenceUuid) {
442
        // TODO Auto-generated method stub
443

    
444
    }
445

    
446
    /**
447
     * {@inheritDoc}
448
     */
449
    @Override
450
    public void openNameEditor(UUID nameUuid) {
451
        // TODO Auto-generated method stub
452

    
453
    }
454

    
455
    /**
456
     * {@inheritDoc}
457
     */
458
    @Override
459
    protected String getHeaderText() {
460
        return headerText;
461
    }
462

    
463
    /**
464
     * {@inheritDoc}
465
     */
466
    @Override
467
    public void setHeaderText(String text) {
468
        this.headerText = text;
469
        updateHeader();
470

    
471
    }
472

    
473
    /**
474
     * @return the subheaderText
475
     */
476
    public String getSubheaderText() {
477
        return subheaderText;
478
    }
479

    
480
    /**
481
     * {@inheritDoc}
482
     */
483
    @Override
484
    public void setSubheaderText(String text) {
485
        subheaderText = text;
486
        updateHeader();
487
    }
488

    
489
    /**
490
     * {@inheritDoc}
491
     */
492
    @Override
493
    protected String getSubHeaderText() {
494
        return subheaderText;
495
    }
496

    
497
    /**
498
     * {@inheritDoc}
499
     */
500
    @Override
501
    public void openDetailsPopup(String caption, List<String> messages) {
502
        StringBuffer sb = new StringBuffer();
503
        sb.append("<div class=\"details-popup-content\">");
504
        messages.forEach(s -> sb.append(s).append("</br>"));
505
        sb.append("</div>");
506
        new Notification(caption, sb.toString(), Notification.Type.HUMANIZED_MESSAGE, true).show(Page.getCurrent());
507
    }
508

    
509
    /**
510
     * {@inheritDoc}
511
     */
512
    @Override
513
    public boolean allowAnonymousAccess() {
514
        return false;
515
    }
516

    
517
    /**
518
     * {@inheritDoc}
519
     */
520
    @Override
521
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
522
        return null;
523
    }
524

    
525
    /**
526
     * @return the addNewNameRegistrationButton
527
     */
528
    @Override
529
    public Button getAddNewNameRegistrationButton() {
530
        return addNewNameRegistrationButton;
531
    }
532

    
533
    @Override
534
    public Button getAddExistingNameRegistrationButton() {
535
        return addExistingNameButton;
536
    }
537

    
538
    @Override
539
    public LazyComboBox<TaxonName> getAddExistingNameCombobox() {
540
        return existingNameCombobox;
541
    }
542

    
543
    /**
544
     * @return the citationID
545
     */
546
    @Override
547
    public Integer getCitationID() {
548
        return citationID;
549
    }
550

    
551

    
552
}
(14-14/19)