Bugfixes for editing publications

pull/1/head
Jens Pelzetter 2022-06-29 20:27:37 +02:00
parent 30a01f2df3
commit 8aef004c17
10 changed files with 274 additions and 153 deletions

View File

@ -3,7 +3,6 @@ package org.scientificcms.publications.ui.contenttypes;
import org.libreccm.api.Identifier; import org.libreccm.api.Identifier;
import org.libreccm.api.IdentifierParser; import org.libreccm.api.IdentifierParser;
import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.ui.BaseUrl; import org.libreccm.ui.BaseUrl;
import org.librecms.assets.Person; import org.librecms.assets.Person;
import org.librecms.assets.PersonRepository; import org.librecms.assets.PersonRepository;
@ -36,9 +35,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import javax.ws.rs.DefaultValue; import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam; import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
/** /**

View File

@ -2,7 +2,6 @@ package org.scientificcms.publications.ui.contenttypes;
import org.libreccm.api.Identifier; import org.libreccm.api.Identifier;
import org.libreccm.api.IdentifierParser; import org.libreccm.api.IdentifierParser;
import org.libreccm.security.AuthorizationRequired;
import org.librecms.contentsection.Asset; import org.librecms.contentsection.Asset;
import org.librecms.contentsection.AssetRepository; import org.librecms.contentsection.AssetRepository;
import org.librecms.ui.contentsections.ContentSectionNotFoundException; import org.librecms.ui.contentsections.ContentSectionNotFoundException;
@ -22,8 +21,6 @@ import javax.inject.Inject;
import javax.mvc.Models; import javax.mvc.Models;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import javax.ws.rs.FormParam; import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
/** /**

View File

@ -7,7 +7,6 @@ import org.librecms.ui.contentsections.documents.DocumentNotFoundException;
import org.librecms.ui.contentsections.documents.DocumentUi; import org.librecms.ui.contentsections.documents.DocumentUi;
import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef; import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps; import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import org.librecms.ui.contenttypes.event.EventStepsConstants;
import org.scientificcms.publications.Monograph; import org.scientificcms.publications.Monograph;
import org.scientificcms.publications.contenttypes.MonographItem; import org.scientificcms.publications.contenttypes.MonographItem;
import org.scientificcms.publications.ui.SciPublicationsUiConstants; import org.scientificcms.publications.ui.SciPublicationsUiConstants;

View File

@ -26,6 +26,7 @@ public class PublicationAuthoringSteps implements MvcAuthoringSteps {
@Override @Override
public Set<Class<?>> getResourceClasses() { public Set<Class<?>> getResourceClasses() {
return Set.of( return Set.of(
PublicationItemAuthors.class,
PublicationAbstractStepResources.class, PublicationAbstractStepResources.class,
PublicationMiscStepResources.class PublicationMiscStepResources.class
); );

View File

@ -0,0 +1,108 @@
package org.scientificcms.publications.ui.contenttypes;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.ui.contentsections.ContentSectionsUi;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import org.scientificcms.publications.Authorship;
import org.scientificcms.publications.Publication;
import org.scientificcms.publications.PublicationRepository;
import org.scientificcms.publications.contenttypes.PublicationItem;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.Consumes;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Path(MvcAuthoringSteps.PATH_PREFIX + "publication-authors")
public class PublicationItemAuthors {
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionsUi sectionsUi;
@Inject
private PublicationRepository publicationRepo;
@POST
@Path("/save-order")
@Consumes(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
public Response saveOrder(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
final List<String> order
) {
final ContentSection section = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException(
String.format(
"ContentSection %s not found.",
sectionIdentifier
)
)
);
final ContentItem item = itemRepo
.findByPath(section, documentPath)
.orElseThrow(
() -> new NotFoundException(
String.format(
"ContentItem %s not found.",
documentPath
)
)
);
if (!(item instanceof PublicationItem)) {
throw new NotFoundException(
String.format(
"ContentItem %s is not a publication item.",
documentPath
)
);
}
final Map<Long, Long> orderMap = new HashMap<>();
for (int i = 0; i < order.size(); i++) {
orderMap.put(Long.parseLong(order.get(i)), (long) i);
}
final PublicationItem<?> publicationItem = (PublicationItem<?>) item;
final Publication publication = publicationItem.getPublication();
for(final Authorship authorship : publication.getAuthorships()) {
authorship.setAuthorOrder(
orderMap.get(
authorship.getAuthorshipId()
)
);
}
publicationRepo.save(publication);
return Response.ok().build();
}
}

View File

@ -30,27 +30,34 @@
formParamName="publisherIdentifier" formParamName="publisherIdentifier"
/> />
<p> <c:choose>
<c:choose> <c:when test="#{SciCmsPublicationWithPublisherPropertiesStepModel.publisherName == null}">
<c:when test="#{SciCmsPublicationWithPublisherPropertiesStepModel.publisherPlace != null}"> <p>#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.none']}</p>
#{SciCmsPublicationWithPublisherPropertiesStepModel.publisherName}, #{SciCmsPublicationWithPublisherPropertiesStepModel.publisherPlace} </c:when>
</c:when> <c:otherwise>
<c:otherwise> <p>
#{SciCmsPublicationWithPublisherPropertiesStepModel.publisherName} <c:choose>
</c:otherwise> <c:when test="#{SciCmsPublicationWithPublisherPropertiesStepModel.publisherPlace != null}">
</c:choose> #{SciCmsPublicationWithPublisherPropertiesStepModel.publisherName}, #{SciCmsPublicationWithPublisherPropertiesStepModel.publisherPlace}
<c:if test="#{SciCmsPublicationWithPublisherPropertiesStepModel.publisherUuid != null}"> </c:when>
<libreccm:deleteDialog <c:otherwise>
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assets/#{CmsSelectedAssetModel.assetPath}/@collectedvolume-edit/publisher/@remove" #{SciCmsPublicationWithPublisherPropertiesStepModel.publisherName}
buttonText="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.remove.label']}" </c:otherwise>
cancelLabel="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.cancel']}" </c:choose>
confirmLabel="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.confirm']}" <c:if test="#{SciCmsPublicationWithPublisherPropertiesStepModel.publisherUuid != null}">
dialogId="publisher-remove" <libreccm:deleteDialog
dialogTitle="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.title']}" actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assets/#{CmsSelectedAssetModel.assetPath}/@collectedvolume-edit/publisher/@remove"
message="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.message']}" buttonText="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.remove.label']}"
/> cancelLabel="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.cancel']}"
</c:if> confirmLabel="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.confirm']}"
</p> dialogId="publisher-remove"
dialogTitle="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.title']}"
message="#{SciPublicationsUiMessageBundle['publicationwithpublisher.publisher.message']}"
/>
</c:if>
</p>
</c:otherwise>
</c:choose>
<ui:insert name="publicationWithPublisherProperties" /> <ui:insert name="publicationWithPublisherProperties" />

View File

@ -247,7 +247,7 @@
</div> </div>
</div> </div>
<librecms:assetPicker <librecms:assetPicker
actionUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/#{SciCmsPublicationPropertiesStepModel.editStepUrlFragment}/authors" actionUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@#{SciCmsPublicationPropertiesStepModel.editStepUrlFragment}/authors"
assetType="#{SciCmsCollectedVolumeAssetEditStepModel.authorType}" assetType="#{SciCmsCollectedVolumeAssetEditStepModel.authorType}"
assetPickerId="authors-picker" assetPickerId="authors-picker"
baseUrl="#{SciCmsPublicationPropertiesStepModel.baseUrl}" baseUrl="#{SciCmsPublicationPropertiesStepModel.baseUrl}"
@ -261,127 +261,134 @@
name="editor" name="editor"
/> />
</librecms:assetPicker> </librecms:assetPicker>
<button class="btn btn-secondary authors-save-order-button" <c:choose>
disabled="disabled" <c:when test="#{SciCmsPublicationPropertiesStepModel.authors.isEmpty()}">
type="button"> <p>#{SciPublicationsUiMessageBundle['basicproperties.authors.none']}</p>
<span class="save-icon"> </c:when>
<bootstrap:svgIcon icon="save" /> <c:otherwise>
</span> <button class="btn btn-secondary authors-save-order-button"
<span class="save-spinner d-none"> disabled="disabled"
<span aria-hidden="true" type="button">
class="spinner-border spinner-border-sm" <span class="save-icon">
role="status"></span> <bootstrap:svgIcon icon="save" />
<span class="sr-only">#{SciPublicationsUiMessageBundle['authors.order.save.inprogress']}</span> </span>
</span> <span class="save-spinner d-none">
<span>#{SciPublicationsUiMessageBundle['authors.order.save']}</span> <span aria-hidden="true"
</button> class="spinner-border spinner-border-sm"
<table id="authors-table" role="status"></span>
data-saveUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@#{SciCmsPublicationPropertiesStepModel.editStepUrlFragment}-authors/save-order"> <span class="sr-only">#{SciPublicationsUiMessageBundle['authors.order.save.inprogress']}</span>
<thead> </span>
<tr> <span>#{SciPublicationsUiMessageBundle['authors.order.save']}</span>
<th>#{SciPublicationsUiMessageBundle['basicproperties.authors.table.name']}</th> </button>
<th> <table id="authors-table"
#{SciPublicationsUiMessageBundle['basicproperties.authors.table.editor']} data-saveUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@publication-authors/save-order">
</th> <thead>
<th colspan="2"> <tr>
#{SciPublicationsUiMessageBundle['basicproperties.authors.table.actions']} <th>#{SciPublicationsUiMessageBundle['basicproperties.authors.table.name']}</th>
</th> <th>
</tr> #{SciPublicationsUiMessageBundle['basicproperties.authors.table.editor']}
</thead> </th>
<tbody> <th colspan="2">
<c:forEach items="#{SciCmsPublicationPropertiesStepModel.authors}" #{SciPublicationsUiMessageBundle['basicproperties.authors.table.actions']}
var="author"> </th>
<tr class="publication-author" </tr>
id="#{author.authorshipId}" </thead>
data-id="#{author.authorshipId}"> <tbody>
<td> <c:forEach items="#{SciCmsPublicationPropertiesStepModel.authors}"
<button class="btn btn-secondary cms-sort-handle mr-2" var="author">
type="button"> <tr class="publication-author"
<bootstrap:svgIcon icon="arrows-move" /> id="#{author.authorshipId}"
<span class="sr-only">#{SciPublicationsUiMessageBundle['basicproperties.authors.move']}</span> data-id="#{author.authorshipId}">
</button> <td>
#{author.authorName} <button class="btn btn-secondary cms-sort-handle mr-2"
</td> type="button">
<td> <bootstrap:svgIcon icon="arrows-move" />
<c:choose> <span class="sr-only">#{SciPublicationsUiMessageBundle['basicproperties.authors.move']}</span>
<c:when test="#{author.editor}"> </button>
#{SciPublicationsUiMessageBundle['basicproperties.authors.table.editor.yes']} #{author.authorName}
</c:when> </td>
<c:otherwise> <td>
#{SciPublicationsUiMessageBundle['basicproperties.authors.table.editor.no']} <c:choose>
</c:otherwise> <c:when test="#{author.editor}">
</c:choose> #{SciPublicationsUiMessageBundle['basicproperties.authors.table.editor.yes']}
</td> </c:when>
<td> <c:otherwise>
<button class="btn btn-secondary" #{SciPublicationsUiMessageBundle['basicproperties.authors.table.editor.no']}
data-toggle="modal" </c:otherwise>
data-target="#authorship-edit-#{author.authorshipUuid}" </c:choose>
type="button"> </td>
<bootstrap:svgIcon icon="pen" /> <td>
<span class="sr-only"> <button class="btn btn-secondary"
#{SciPublicationsUiMessageBundle['basicproperties.authors.edit.label']} data-toggle="modal"
</span> data-target="#authorship-edit-#{author.authorshipUuid}"
</button> type="button">
<div aria-hidden="true" <bootstrap:svgIcon icon="pen" />
aria-labelledby="authorship-edit-#{author.authorshipUuid}-title" <span class="sr-only">
class="modal fade" #{SciPublicationsUiMessageBundle['basicproperties.authors.edit.label']}
id="authorship-edit-#{author.authorshipUuid}" </span>
tabindex="-1"> </button>
<div class="modal-dialog"> <div aria-hidden="true"
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@#{SciCmsPublicationPropertiesStepModel.editStepUrlFragment}/authors/#{author.authorshipUuid}" aria-labelledby="authorship-edit-#{author.authorshipUuid}-title"
class="modal-content" class="modal fade"
method="post"> id="authorship-edit-#{author.authorshipUuid}"
<div class="modal-header"> tabindex="-1">
<h4 class="modal-title" <div class="modal-dialog">
id="authorship-edit-#{author.authorshipUuid}-title"> <form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@#{SciCmsPublicationPropertiesStepModel.editStepUrlFragment}/authors/#{author.authorshipUuid}"
#{SciPublicationsUiMessageBundle.getMessage('basicproperties.authors.editdialog.title', [author.authorName])} class="modal-content"
</h4> method="post">
<button aria-label="{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.cancel']}" <div class="modal-header">
class="close" <h4 class="modal-title"
data-dismiss="modal" id="authorship-edit-#{author.authorshipUuid}-title">
type="button"> #{SciPublicationsUiMessageBundle.getMessage('basicproperties.authors.editdialog.title', [author.authorName])}
<bootstrap:svgIcon icon="x" /> </h4>
</button> <button aria-label="{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.cancel']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</div>
<div class="modal-body">
<bootstrap:formCheck
checked="#{author.editor}"
inputId="#{author.authorshipUuid}-editor"
label="#{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.editor.label']}"
name="editor"
value="true"
/>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.cancel']}
</button>
<button class="btn btn-success"
type="submit">
#{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.submit']}
</button>
</div>
</form>
</div> </div>
<div class="modal-body"> </div>
<bootstrap:formCheck </td>
checked="#{author.editor}" <td>
inputId="#{author.authorshipUuid}-editor" <libreccm:deleteDialog
label="#{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.editor.label']}" actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@#{SciCmsPublicationPropertiesStepModel.editStepUrlFragment}/authors/#{author.authorshipUuid}/remove"
name="editor" buttonText="#{SciPublicationsUiMessageBundle['basicproperties.authors.remove.label']}"
value="true" cancelLabel="#{SciPublicationsUiMessageBundle['basicproperties.authors.remove.cancel']}"
/> confirmLabel="#{SciPublicationsUiMessageBundle['basicproperties.authors.remove.confirm']}"
</div> dialogId="remove-author-#{author.authorshipUuid}"
<div class="modal-footer"> dialogTitle="#{SciPublicationsUiMessageBundle.getMessage('basicproperties.authors.remove.title', [author.authorName])}"
<button class="btn btn-warning" message="#{SciPublicationsUiMessageBundle.getMessage('basicproperties.authors.remove.text', [author.authorName])}"
data-dismiss="modal" />
type="button"> </td>
#{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.cancel']} </tr>
</button> </c:forEach>
<button class="btn btn-success" </tbody>
type="submit"> </table>
#{SciPublicationsUiMessageBundle['basicproperties.authors.editdialog.submit']} </c:otherwise>
</button> </c:choose>
</div>
</form>
</div>
</div>
</td>
<td>
<libreccm:deleteDialog
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@#{SciCmsPublicationPropertiesStepModel.editStepUrlFragment}/authors/#{author.authorshipUuid}/remove"
buttonText="#{SciPublicationsUiMessageBundle['basicproperties.authors.remove.label']}"
cancelLabel="#{SciPublicationsUiMessageBundle['basicproperties.authors.remove.cancel']}"
confirmLabel="#{SciPublicationsUiMessageBundle['basicproperties.authors.remove.confirm']}"
dialogId="remove-author-#{author.authorshipUuid}"
dialogTitle="#{SciPublicationsUiMessageBundle.getMessage('basicproperties.authors.remove.title', [author.authorName])}"
message="#{SciPublicationsUiMessageBundle.getMessage('basicproperties.authors.remove.text', [author.authorName])}"
/>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</c:if> </c:if>
<ui:insert name="publicationProperties" /> <ui:insert name="publicationProperties" />

View File

@ -377,3 +377,6 @@ editsteps.misc.step_back=Back
editsteps.misc.header_view=Miscellaneous information editsteps.misc.header_view=Miscellaneous information
editsteps.misc.edit=Edit editsteps.misc.edit=Edit
editsteps.misc.header_edit=Edit miscellaneous information editsteps.misc.header_edit=Edit miscellaneous information
basicproperties.authors.none=No authors assigned yet.
publicationwithpublisher.publisher.none=No publisher assigned yet.
basicproperties.authors.remove.confirm=Remove

View File

@ -335,7 +335,7 @@ basicproperties.authors.table.name=Name
basicproperties.authors.table.editor=Herausgeber:in basicproperties.authors.table.editor=Herausgeber:in
basicproperties.authors.table.actions=Aktionen basicproperties.authors.table.actions=Aktionen
basicproperties.authors.move=Verschieben basicproperties.authors.move=Verschieben
basicproperties.authors.table.editor.yes=No basicproperties.authors.table.editor.yes=Ja
basicproperties.authors.table.editor.no=Nein basicproperties.authors.table.editor.no=Nein
basicproperties.authors.edit.label=Autorenschaft bearbeiten basicproperties.authors.edit.label=Autorenschaft bearbeiten
basicproperties.authors.editdialog.title=Autorenschaft von {0} bearbeiten basicproperties.authors.editdialog.title=Autorenschaft von {0} bearbeiten
@ -377,3 +377,6 @@ editsteps.misc.step_back=Zur\u00fcck
editsteps.misc.header_view=Weitere Informationen editsteps.misc.header_view=Weitere Informationen
editsteps.misc.edit=Bearbeiten editsteps.misc.edit=Bearbeiten
editsteps.misc.header_edit=Weitere Informationen bearbeiten editsteps.misc.header_edit=Weitere Informationen bearbeiten
basicproperties.authors.none=Es wurden noch keine Autoren eingetragen.
publicationwithpublisher.publisher.none=Es wurde noch kein Verlag zugewiesen.
basicproperties.authors.remove.confirm=Entfernen

View File

@ -7,7 +7,7 @@ module.exports = {
entry: { entry: {
"collectedvolume-asset-authors": "./src/main/typescript/collectedvolume-asset-authors.ts", "collectedvolume-asset-authors": "./src/main/typescript/collectedvolume-asset-authors.ts",
"proceedings-asset-authors": "./src/main/typescript/proceedings-asset-authors", "proceedings-asset-authors": "./src/main/typescript/proceedings-asset-authors",
"publications-authors.ts": "./src/main/typescript/publication-authors.ts" "publication-authors": "./src/main/typescript/publication-authors.ts"
}, },
output: { output: {
filename: "[name].js", filename: "[name].js",