diff --git a/inception/inception-workload-matrix/src/main/java/de/tudarmstadt/ukp/inception/workload/matrix/annotation/MatrixWorkflowActionBarItemGroup.java b/inception/inception-workload-matrix/src/main/java/de/tudarmstadt/ukp/inception/workload/matrix/annotation/MatrixWorkflowActionBarItemGroup.java index f9a02cd179c..8dda5bde142 100644 --- a/inception/inception-workload-matrix/src/main/java/de/tudarmstadt/ukp/inception/workload/matrix/annotation/MatrixWorkflowActionBarItemGroup.java +++ b/inception/inception-workload-matrix/src/main/java/de/tudarmstadt/ukp/inception/workload/matrix/annotation/MatrixWorkflowActionBarItemGroup.java @@ -20,6 +20,7 @@ import static de.tudarmstadt.ukp.clarin.webanno.model.AnnotationDocumentState.FINISHED; import static de.tudarmstadt.ukp.clarin.webanno.model.AnnotationDocumentState.IN_PROGRESS; import static de.tudarmstadt.ukp.clarin.webanno.model.AnnotationDocumentStateChangeFlag.EXPLICIT_ANNOTATOR_USER_ACTION; +import static de.tudarmstadt.ukp.clarin.webanno.model.PermissionLevel.CURATOR; import static de.tudarmstadt.ukp.clarin.webanno.model.SourceDocumentState.CURATION_FINISHED; import static de.tudarmstadt.ukp.clarin.webanno.model.SourceDocumentState.CURATION_IN_PROGRESS; import static de.tudarmstadt.ukp.clarin.webanno.support.WebAnnoConst.CURATION_USER; @@ -43,6 +44,7 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.behavior.CssClassNameModifier; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; import de.tudarmstadt.ukp.clarin.webanno.api.DocumentService; +import de.tudarmstadt.ukp.clarin.webanno.api.ProjectService; import de.tudarmstadt.ukp.clarin.webanno.api.annotation.actionbar.finish.FinishDocumentDialogContent; import de.tudarmstadt.ukp.clarin.webanno.api.annotation.actionbar.finish.FinishDocumentDialogModel; import de.tudarmstadt.ukp.clarin.webanno.api.annotation.exception.ValidationException; @@ -50,6 +52,7 @@ import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationDocument; import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationDocumentState; import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument; +import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocumentState; import de.tudarmstadt.ukp.clarin.webanno.security.UserDao; import de.tudarmstadt.ukp.clarin.webanno.support.bootstrap.BootstrapModalDialog; import de.tudarmstadt.ukp.clarin.webanno.support.dialog.ChallengeResponseDialog; @@ -66,6 +69,7 @@ public class MatrixWorkflowActionBarItemGroup private static final long serialVersionUID = 4139817495914347777L; private @SpringBean DocumentService documentService; + private @SpringBean ProjectService projectService; private @SpringBean UserDao userRepository; private @SpringBean WorkloadManagementService workloadManagementService; private @SpringBean MatrixWorkloadExtension matrixWorkloadExtension; @@ -106,23 +110,35 @@ public MatrixWorkflowActionBarItemGroup(String aId, AnnotationPageBase aPage) private LambdaAjaxLink createToggleDocumentStateLink(String aId) { - MatrixWorkloadTraits traits = matrixWorkloadExtension.readTraits(workloadManagementService - .loadOrCreateWorkloadManagerConfiguration(page.getModelObject().getProject())); - LambdaAjaxLink link; - if (traits.isReopenableByAnnotator()) { + if (isReopenableByUser()) { link = new LambdaAjaxLink(aId, this::actionToggleDocumentState); } else { link = new LambdaAjaxLink(aId, this::actionRequestFinishDocumentConfirmation); } link.setOutputMarkupId(true); - link.add(enabledWhen(() -> page.isEditable() || traits.isReopenableByAnnotator())); + link.add(enabledWhen(() -> page.isEditable() || isReopenableByUser())); link.add(new Label("state") .add(new CssClassNameModifier(LambdaModel.of(this::getStateClass)))); return link; } + private boolean isReopenableByUser() + { + // Curators can re-open documents anyway via the monitoring page, so we can always allow + // the re-open documents here as well + AnnotatorState state = page.getModelObject(); + if (projectService.hasRole(userRepository.getCurrentUsername(), state.getProject(), + CURATOR)) { + return true; + } + + MatrixWorkloadTraits traits = matrixWorkloadExtension.readTraits(workloadManagementService + .loadOrCreateWorkloadManagerConfiguration(page.getModelObject().getProject())); + return traits.isReopenableByAnnotator(); + } + protected AnnotationPageBase getAnnotationPage() { return page; @@ -132,10 +148,24 @@ public String getStateClass() { AnnotatorState state = page.getModelObject(); + // Curation sidebar: when writing to the curation document, we need to update the document + if (state.getUser().getUsername().equals(CURATION_USER)) { + if (state.getDocument().getState() == SourceDocumentState.CURATION_FINISHED) { + // SourceDocumentState.CURATION_FINISHED.symbol() + return FontAwesome5IconType.clipboard_check_s.cssClassName(); + } + else { + // SourceDocumentState.CURATION_IN_PROGRESS.symbol() + return FontAwesome5IconType.clipboard_s.cssClassName(); + } + } + if (documentService.isAnnotationFinished(state.getDocument(), state.getUser())) { + // AnnotationDocumentState.FINISHED.symbol(); return FontAwesome5IconType.lock_s.cssClassName(); } else { + // AnnotationDocumentState.IN_PROGRESS.symbol(); return FontAwesome5IconType.lock_open_s.cssClassName(); } } @@ -178,10 +208,26 @@ private void actionFinishDocumentDialogSubmitted(AjaxRequestTarget aTarget, private void actionToggleDocumentState(AjaxRequestTarget aTarget) { + // state instead AnnotatorState state = page.getModelObject(); SourceDocument document = state.getDocument(); - var annDoc = documentService.getAnnotationDocument(document, state.getUser()); + // Curation sidebar: when writing to the curation document, we need to update the docuement + if (state.getUser().getUsername().equals(CURATION_USER)) { + switch (document.getState()) { + case CURATION_FINISHED: + documentService.setSourceDocumentState(document, CURATION_IN_PROGRESS); + aTarget.add(page); + break; + default: + documentService.setSourceDocumentState(document, CURATION_FINISHED); + aTarget.add(page); + break; + } + return; + } + + var annDoc = documentService.getAnnotationDocument(document, state.getUser()); if (annDoc.getAnnotatorState() != annDoc.getState()) { error("Annotation state has been overridden by a project manager or curator. " + "You cannot change it."); @@ -194,25 +240,13 @@ private void actionToggleDocumentState(AjaxRequestTarget aTarget) var annState = annDoc.getAnnotatorState(); switch (annState) { case IN_PROGRESS: - // curation sidebar: need to update source doc state as well to finished - if (state.getUser().getUsername().equals(CURATION_USER)) { - documentService.setSourceDocumentState(document, CURATION_FINISHED); - } - else { - documentService.setAnnotationDocumentState(annDoc, FINISHED, - EXPLICIT_ANNOTATOR_USER_ACTION); - } + documentService.setAnnotationDocumentState(annDoc, FINISHED, + EXPLICIT_ANNOTATOR_USER_ACTION); aTarget.add(page); break; case FINISHED: - // curation sidebar: need to update source doc state as well to finished - if (state.getUser().getUsername().equals(CURATION_USER)) { - documentService.setSourceDocumentState(document, CURATION_IN_PROGRESS); - } - else { - documentService.setAnnotationDocumentState(annDoc, IN_PROGRESS, - EXPLICIT_ANNOTATOR_USER_ACTION); - } + documentService.setAnnotationDocumentState(annDoc, IN_PROGRESS, + EXPLICIT_ANNOTATOR_USER_ACTION); aTarget.add(page); break; default: