Project

General

Profile

Download (20.3 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.TypedEntityReference;
65
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
66
import eu.etaxonomy.cdm.vaadin.security.AccessRestrictedView;
67
import eu.etaxonomy.cdm.vaadin.security.PermissionDebugUtils;
68
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
69
import eu.etaxonomy.cdm.vaadin.theme.EditValoTheme;
70
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSetType;
71
import eu.etaxonomy.cdm.vaadin.view.AbstractPageView;
72
import eu.etaxonomy.vaadin.event.EditorActionType;
73

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

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

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

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

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

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

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

    
104
    public RegistrationType regType = null;
105

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

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

    
111
    private Integer citationID;
112

    
113
    private Button addNewNameRegistrationButton;
114

    
115
    private LazyComboBox<TaxonName> existingNameCombobox;
116

    
117
    private GridLayout registrationsGrid;
118

    
119
    private Button addExistingNameButton;
120

    
121
    private RegistrationItem workingsetHeader;
122

    
123
    private Panel registrationListPanel;
124

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

    
130
    public RegistrationWorksetViewBean() {
131
        super();
132
    }
133

    
134

    
135
    /**
136
     * {@inheritDoc}
137
     */
138
    @Override
139
    protected void initContent() {
140
        getLayout().setId(NAME);
141
        updateHeader();
142
        // all content is added in createRegistrationsList()
143
    }
144

    
145

    
146
    /**
147
     * {@inheritDoc}
148
     */
149
    @Override
150
    public void enter(ViewChangeEvent event) {
151
        if(event.getParameters() != null){
152
            this.citationID = Integer.valueOf(event.getParameters());
153

    
154
            getPresenter().handleViewEntered();
155
        }
156
    }
157

    
158
    /**
159
     * {@inheritDoc}
160
     */
161
    @Override
162
    public void setWorkingset(RegistrationWorkingSet workingset) {
163

    
164
        if(workingsetHeader != null){
165
            getLayout().removeComponent(workingsetHeader);
166
            getLayout().removeComponent(registrationListPanel);
167
        }
168
        workingsetHeader = new RegistrationItem(workingset, this);
169
        addContentComponent(workingsetHeader, null);
170

    
171
        registrationListPanel = createRegistrationsList(workingset);
172
        registrationListPanel.setHeight("100%");
173
        registrationListPanel.setStyleName("registration-list");
174
        registrationListPanel.setCaption("Registrations");
175
        addContentComponent(registrationListPanel, 1.0f);
176

    
177
    }
178

    
179
    @Override
180
    public void setBlockingRegistrations(int registrationId, Set<RegistrationDTO> blockingRegDTOs) {
181

    
182
        RegistrationDetailsItem regItem = registrationItemMap.get(registrationId);
183

    
184
        boolean blockingRegAdded = false;
185
        for(Iterator it = regItem.itemFooter.iterator(); it.hasNext(); ){
186
            if(it.next() instanceof RegistrationItemsPanel){
187
                blockingRegAdded = true;
188
                break;
189
            }
190
        }
191
        if(!blockingRegAdded){
192
            regItem.itemFooter.addComponent(new RegistrationItemsPanel(this, "Blocked by", blockingRegDTOs));
193
        }
194
    }
195

    
196
    /**
197
     * {@inheritDoc}
198
     */
199
    @Override
200
    @Deprecated // no longer needed
201
    public void addBlockingRegistration(RegistrationDTO blocking) {
202
        if(registrations == null) {
203
            throw new RuntimeException("A Workingset must be present prior adding blocking registrations.");
204
        }
205
        // add the blocking registration
206

    
207
    }
208

    
209
    /**
210
     * @param workingset
211
     * @return
212
     */
213
    public Panel createRegistrationsList(RegistrationWorkingSet workingset) {
214

    
215
        registrationsGrid = new GridLayout(3, 1);
216
        registrationsGrid.setWidth("100%");
217
        // allow vertical scrolling:
218
        registrationsGrid.setHeightUndefined();
219

    
220
        //registrationsGrid.setColumnExpandRatio(0, 0.1f);
221
        registrationsGrid.setColumnExpandRatio(1, 1f);
222

    
223
        registrationItemMap.clear();
224
        registrationsGrid.setRows(workingset.getRegistrationDTOs().size() * 2  + 2);
225
        int row = 0;
226
        for(RegistrationDTO dto : workingset.getRegistrationDTOs()) {
227
            row = putRegistrationListComponent(row, dto);
228
        }
229

    
230
        Label addRegistrationLabel_1 = new Label("Add a new registration for a");
231
        Label addRegistrationLabel_2 = new Label("or an");
232

    
233
        addNewNameRegistrationButton = new Button("new name");
234
        addNewNameRegistrationButton.setDescription("A name which is newly published in this publication.");
235
        addNewNameRegistrationButton.addClickListener(
236
                e -> getViewEventBus().publish(this, new TaxonNameEditorAction(EditorActionType.ADD, null, addNewNameRegistrationButton, this)));
237

    
238
        addExistingNameButton = new Button("existing name:");
239
        addExistingNameButton.setDescription("A name which was previously published in a earlier publication.");
240
        addExistingNameButton.setEnabled(false);
241
        addExistingNameButton.addClickListener(
242
                e -> getViewEventBus().publish(this, new RegistrationWorkingsetAction(citationID, RegistrationWorkingsetAction.Action.start))
243
                );
244

    
245
        existingNameCombobox = new LazyComboBox<TaxonName>(TaxonName.class);
246
        existingNameCombobox.addValueChangeListener(
247
                e -> addExistingNameButton.setEnabled(e.getProperty().getValue() != null)
248
                );
249

    
250
        HorizontalLayout buttonContainer = new HorizontalLayout(addRegistrationLabel_1, addNewNameRegistrationButton, addRegistrationLabel_2, addExistingNameButton, existingNameCombobox);
251
        buttonContainer.setSpacing(true);
252
//        buttonContainer.setWidth(100, Unit.PERCENTAGE);
253
        buttonContainer.setComponentAlignment(addRegistrationLabel_1, Alignment.MIDDLE_LEFT);
254
        buttonContainer.setComponentAlignment(addRegistrationLabel_2, Alignment.MIDDLE_LEFT);
255

    
256
        row++;
257
        registrationsGrid.addComponent(buttonContainer, 0, row, COL_INDEX_BUTTON_GROUP, row);
258
        registrationsGrid.setComponentAlignment(buttonContainer, Alignment.MIDDLE_RIGHT);
259

    
260
        Panel namesTypesPanel = new Panel(registrationsGrid);
261
        namesTypesPanel.setStyleName(EditValoTheme.PANEL_CONTENT_PADDING_LEFT);
262
        return namesTypesPanel;
263
    }
264

    
265

    
266

    
267
    protected int putRegistrationListComponent(int row, RegistrationDTO dto) {
268

    
269
        RegistrationItemNameAndTypeButtons regItemButtonGroup = new RegistrationItemNameAndTypeButtons(dto);
270
        Integer registrationEntityID = dto.getId();
271

    
272
        RegistrationItemButtons regItemButtons = new RegistrationItemButtons();
273

    
274
        CssLayout footer = new CssLayout();
275
        footer.setWidth(100, Unit.PERCENTAGE);
276
        footer.setStyleName("item-footer");
277

    
278
        RegistrationDetailsItem regDetailsItem = new RegistrationDetailsItem(regItemButtonGroup, regItemButtons, footer);
279
        registrationItemMap.put(registrationEntityID, regDetailsItem);
280

    
281
        Stack<EditorActionContext> context = new Stack<EditorActionContext>();
282
        context.push(new EditorActionContext(
283
                    new TypedEntityReference<>(Registration.class, registrationEntityID),
284
                    this)
285
                    );
286

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

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

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

    
322

    
323
        Button blockingRegistrationButton = regItemButtons.getBlockingRegistrationButton();
324
        blockingRegistrationButton.setStyleName(ValoTheme.BUTTON_TINY);
325
        blockingRegistrationButton.setDescription("No blocking registrations");
326
        if(dto.isBlocked()){
327
            blockingRegistrationButton.setEnabled(true);
328
            blockingRegistrationButton.setDescription("This registration is currently blocked by other registrations");
329
            blockingRegistrationButton.addStyleName(EditValoTheme.BUTTON_HIGHLITE);
330
            blockingRegistrationButton.addClickListener(e -> getViewEventBus().publish(
331
                    this,
332
                    new ShowDetailsEvent<RegistrationDTO, Integer>(
333
                            e,
334
                            RegistrationDTO.class,
335
                            dto.getId(),
336
                            RegistrationItem.BLOCKED_BY
337
                            )
338
                    ));
339
        }
340

    
341
        Button validationProblemsButton = regItemButtons.getValidationProblemsButton();
342
        validationProblemsButton.setStyleName(ValoTheme.BUTTON_TINY); //  + " " + RegistrationStyles.STYLE_FRIENDLY_FOREGROUND);
343

    
344
        if(!dto.getValidationProblems().isEmpty()){
345
            validationProblemsButton.setEnabled(true);
346
            validationProblemsButton.addClickListener(e -> getViewEventBus().publish(this,
347
                    new ShowDetailsEvent<RegistrationDTO, Integer>(
348
                        e,
349
                        RegistrationDTO.class,
350
                        dto.getId(),
351
                        RegistrationItem.VALIDATION_PROBLEMS
352
                        )
353
                    )
354
                );
355
        }
356
        validationProblemsButton.setCaption("<span class=\"" + RegistrationStyles.BUTTON_BADGE +"\"> " + dto.getValidationProblems().size() + "</span>");
357
        validationProblemsButton.setCaptionAsHtml(true);
358

    
359
        Button messageButton = regItemButtons.getMessagesButton();
360
        messageButton.addClickListener(e -> getViewEventBus().publish(this,
361
                    new ShowDetailsEvent<RegistrationDTO, Integer>(
362
                        e,
363
                        RegistrationDTO.class,
364
                        dto.getId(),
365
                        RegistrationItem.MESSAGES
366
                        )
367
                    )
368
                );
369
        messageButton.setStyleName(ValoTheme.BUTTON_TINY);
370

    
371
        RegistrationStateLabel stateLabel = new RegistrationStateLabel().update(dto.getStatus());
372
        Label submitterLabel = new Label(dto.getSubmitterUserName());
373
        submitterLabel.setStyleName(LABEL_NOWRAP + " submitter");
374
        submitterLabel.setIcon(FontAwesome.USER);
375
        submitterLabel.setContentMode(ContentMode.HTML);
376
        CssLayout stateAndSubmitter = new CssLayout(stateLabel, submitterLabel);
377

    
378

    
379
        if(UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin()) {
380
            Button editRegistrationButton = new Button(FontAwesome.COG);
381
            editRegistrationButton.setStyleName(ValoTheme.BUTTON_TINY);
382
            editRegistrationButton.setDescription("Edit registration");
383
            editRegistrationButton.addClickListener(e -> getViewEventBus().publish(this, new RegistrationEditorAction(
384
                EditorActionType.EDIT,
385
                dto.getId(),
386
                null,
387
                this
388
                )));
389
            regItemButtons.addComponent(editRegistrationButton);
390
        }
391

    
392
        PermissionDebugUtils.addGainPerEntityPermissionButton(regItemButtons, Registration.class, dto.getId(),
393
                EnumSet.of(CRUD.UPDATE), RegistrationStatus.PREPARATION.name());
394

    
395
        row++;
396
        registrationsGrid.addComponent(stateAndSubmitter, COL_INDEX_STATE_LABEL, row);
397
        // registrationsGrid.setComponentAlignment(stateLabel, Alignment.TOP_LEFT);
398
        registrationsGrid.addComponent(regItemButtonGroup, COL_INDEX_REG_ITEM, row);
399
        registrationsGrid.addComponent(regItemButtons, COL_INDEX_BUTTON_GROUP, row);
400
        registrationsGrid.setComponentAlignment(regItemButtons, Alignment.TOP_LEFT);
401

    
402
        row++;
403
        registrationsGrid.addComponent(footer, 0, row, COL_INDEX_BUTTON_GROUP, row);
404

    
405
        return row;
406
    }
407

    
408
    /**
409
     * @param button
410
     * @param registrationEntityId
411
     *
412
     */
413
    @Override
414
    public void chooseNewTypeRegistrationWorkingset(Integer registrationEntityId) {
415

    
416
        Window typeDesignationTypeCooser = new Window();
417
        typeDesignationTypeCooser.setModal(true);
418
        typeDesignationTypeCooser.setResizable(false);
419
        typeDesignationTypeCooser.setCaption("Add new type designation");
420
        Label label = new Label("Please select kind of type designation to be created.");
421
        Button newSpecimenTypeDesignationButton = new Button("Specimen type designation",
422
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET, registrationEntityId, typeDesignationTypeCooser));
423
        Button newNameTypeDesignationButton = new Button("Name type designation",
424
                e -> addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET, registrationEntityId, typeDesignationTypeCooser));
425

    
426
        VerticalLayout layout = new VerticalLayout(label, newSpecimenTypeDesignationButton, newNameTypeDesignationButton);
427
        layout.setMargin(true);
428
        layout.setSpacing(true);
429
        layout.setComponentAlignment(newSpecimenTypeDesignationButton, Alignment.MIDDLE_CENTER);
430
        layout.setComponentAlignment(newNameTypeDesignationButton, Alignment.MIDDLE_CENTER);
431
        typeDesignationTypeCooser.setContent(layout);
432
        UI.getCurrent().addWindow(typeDesignationTypeCooser);
433
    }
434

    
435
    /**
436
     * @param button
437
     *
438
     */
439
    protected void addNewTypeDesignationWorkingset(TypeDesignationWorkingSetType newWorkingsetType, Integer registrationEntityId, Window typeDesignationTypeCooser) {
440
        UI.getCurrent().removeWindow(typeDesignationTypeCooser);
441
        getViewEventBus().publish(this, new TypeDesignationWorkingsetEditorAction(
442
                EditorActionType.ADD,
443
                newWorkingsetType,
444
                registrationEntityId,
445
                null,
446
                this
447
                ));
448
    }
449

    
450
    /**
451
     * {@inheritDoc}
452
     */
453
    @Override
454
    public void openReferenceEditor(UUID referenceUuid) {
455
        // TODO Auto-generated method stub
456

    
457
    }
458

    
459
    /**
460
     * {@inheritDoc}
461
     */
462
    @Override
463
    public void openNameEditor(UUID nameUuid) {
464
        // TODO Auto-generated method stub
465

    
466
    }
467

    
468
    /**
469
     * {@inheritDoc}
470
     */
471
    @Override
472
    protected String getHeaderText() {
473
        return headerText;
474
    }
475

    
476
    /**
477
     * {@inheritDoc}
478
     */
479
    @Override
480
    public void setHeaderText(String text) {
481
        this.headerText = text;
482
        updateHeader();
483

    
484
    }
485

    
486
    /**
487
     * @return the subheaderText
488
     */
489
    public String getSubheaderText() {
490
        return subheaderText;
491
    }
492

    
493
    /**
494
     * {@inheritDoc}
495
     */
496
    @Override
497
    public void setSubheaderText(String text) {
498
        subheaderText = text;
499
        updateHeader();
500
    }
501

    
502
    /**
503
     * {@inheritDoc}
504
     */
505
    @Override
506
    protected String getSubHeaderText() {
507
        return subheaderText;
508
    }
509

    
510
    /**
511
     * {@inheritDoc}
512
     */
513
    @Override
514
    public void openDetailsPopup(String caption, List<String> messages) {
515
        StringBuffer sb = new StringBuffer();
516
        sb.append("<div class=\"details-popup-content\">");
517
        messages.forEach(s -> sb.append(s).append("</br>"));
518
        sb.append("</div>");
519
        new Notification(caption, sb.toString(), Notification.Type.HUMANIZED_MESSAGE, true).show(Page.getCurrent());
520
    }
521

    
522
    /**
523
     * {@inheritDoc}
524
     */
525
    @Override
526
    public boolean allowAnonymousAccess() {
527
        return false;
528
    }
529

    
530
    /**
531
     * {@inheritDoc}
532
     */
533
    @Override
534
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
535
        return null;
536
    }
537

    
538
    /**
539
     * @return the addNewNameRegistrationButton
540
     */
541
    @Override
542
    public Button getAddNewNameRegistrationButton() {
543
        return addNewNameRegistrationButton;
544
    }
545

    
546
    @Override
547
    public Button getAddExistingNameRegistrationButton() {
548
        return addExistingNameButton;
549
    }
550

    
551
    @Override
552
    public LazyComboBox<TaxonName> getAddExistingNameCombobox() {
553
        return existingNameCombobox;
554
    }
555

    
556
    /**
557
     * @return the citationID
558
     */
559
    @Override
560
    public Integer getCitationID() {
561
        return citationID;
562
    }
563

    
564
    @Override
565
    public Map<Integer, RegistrationDetailsItem> getRegistrationItemMap(){
566
        return Collections.unmodifiableMap(registrationItemMap);
567
    }
568

    
569

    
570
}
(18-18/23)