Compoments and resusable classes for subclasses of ContactableEntity, base structure for asset picker component
parent
1bdddb5243
commit
ca081f94df
|
|
@ -161,25 +161,23 @@ public class PersonFormController
|
||||||
final String suffix = (String) data.get(SUFFIX);
|
final String suffix = (String) data.get(SUFFIX);
|
||||||
|
|
||||||
if (asset.getPersonName() == null) {
|
if (asset.getPersonName() == null) {
|
||||||
personManager.addPersonName(asset);
|
final PersonName personName = new PersonName();
|
||||||
|
personName.setGivenName(givenName);
|
||||||
|
personName.setSuffix(suffix);
|
||||||
|
personName.setPrefix(prefix);
|
||||||
|
personName.setSurname(surname);
|
||||||
|
personManager.addPersonName(asset, personName);
|
||||||
}
|
}
|
||||||
|
|
||||||
asset.getPersonName().setSurname(surname);
|
|
||||||
asset.getPersonName().setGivenName(givenName);
|
|
||||||
asset.getPersonName().setPrefix(prefix);
|
|
||||||
asset.getPersonName().setSuffix(suffix);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void addPersonName(final long personId) {
|
public void addPersonName(final long personId) {
|
||||||
|
|
||||||
final Person person = personRepository
|
final Person person = personRepository
|
||||||
.findById(personId)
|
.findById(personId)
|
||||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||||
"No Person with ID %d found.", personId)));
|
"No Person with ID %d found.", personId)));
|
||||||
|
|
||||||
personManager.addPersonName(person);
|
personManager.addPersonName(person, new PersonName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,12 @@ public class ContactEntryKey
|
||||||
@Embedded
|
@Embedded
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "CONTACT_ENTRY_KEY_LABELS",
|
joinTable = @JoinTable(
|
||||||
schema = DB_SCHEMA,
|
name = "CONTACT_ENTRY_KEY_LABELS",
|
||||||
joinColumns = {
|
schema = DB_SCHEMA,
|
||||||
@JoinColumn(name = "KEY_ID")
|
joinColumns = {
|
||||||
}
|
@JoinColumn(name = "KEY_ID")
|
||||||
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private LocalizedString label;
|
private LocalizedString label;
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ public class ContactableEntityManager {
|
||||||
|
|
||||||
contactableEntity.setPostalAddress(postalAddress);
|
contactableEntity.setPostalAddress(postalAddress);
|
||||||
assetRepository.save(postalAddress);
|
assetRepository.save(postalAddress);
|
||||||
|
assetRepository.save(contactableEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removePostalAddressFromContactableEntity(
|
public void removePostalAddressFromContactableEntity(
|
||||||
|
|
@ -73,6 +74,7 @@ public class ContactableEntityManager {
|
||||||
|
|
||||||
contactableEntity.setPostalAddress(null);
|
contactableEntity.setPostalAddress(null);
|
||||||
assetRepository.save(postalAddress);
|
assetRepository.save(postalAddress);
|
||||||
|
assetRepository.save(contactableEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@ package org.librecms.assets;
|
||||||
import com.arsdigita.cms.ui.assets.forms.PersonForm;
|
import com.arsdigita.cms.ui.assets.forms.PersonForm;
|
||||||
|
|
||||||
import org.hibernate.envers.Audited;
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.librecms.ui.contentsections.assets.MvcAssetEditKit;
|
||||||
|
import org.librecms.ui.contentsections.assets.PersonCreateStep;
|
||||||
|
import org.librecms.ui.contentsections.assets.PersonEditStep;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -46,11 +49,17 @@ import static org.librecms.assets.AssetConstants.*;
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "PERSONS", schema = DB_SCHEMA)
|
@Table(name = "PERSONS", schema = DB_SCHEMA)
|
||||||
@Audited
|
@Audited
|
||||||
@AssetType(assetForm = PersonForm.class,
|
@AssetType(
|
||||||
|
assetForm = PersonForm.class,
|
||||||
labelBundle = ASSETS_BUNDLE,
|
labelBundle = ASSETS_BUNDLE,
|
||||||
labelKey = "person.label",
|
labelKey = "person.label",
|
||||||
descriptionBundle = ASSETS_BUNDLE,
|
descriptionBundle = ASSETS_BUNDLE,
|
||||||
descriptionKey = "person.description")
|
descriptionKey = "person.description"
|
||||||
|
)
|
||||||
|
@MvcAssetEditKit(
|
||||||
|
createStep = PersonCreateStep.class,
|
||||||
|
editStep = PersonEditStep.class
|
||||||
|
)
|
||||||
public class Person extends ContactableEntity {
|
public class Person extends ContactableEntity {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.assets;
|
package org.librecms.assets;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
@ -35,17 +34,19 @@ public class PersonManager {
|
||||||
private PersonRepository personRepository;
|
private PersonRepository personRepository;
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void addPersonName(final Person toPerson) {
|
public void addPersonName(
|
||||||
|
final Person toPerson, final PersonName personName
|
||||||
final PersonName current = Objects
|
) {
|
||||||
.requireNonNull(toPerson, "Can't add a name to Person null.")
|
// final PersonName current = Objects
|
||||||
.getPersonName();
|
// .requireNonNull(toPerson, "Can't add a name to Person null.")
|
||||||
|
// .getPersonName();
|
||||||
if (current == null) {
|
//
|
||||||
toPerson.addPersonName(new PersonName());
|
// if (current == null) {
|
||||||
} else {
|
// toPerson.addPersonName(new PersonName());
|
||||||
toPerson.addPersonName(current);
|
// } else {
|
||||||
}
|
// toPerson.addPersonName(current);
|
||||||
|
// }
|
||||||
|
toPerson.addPersonName(personName);
|
||||||
|
|
||||||
personRepository.save(toPerson);
|
personRepository.save(toPerson);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -262,9 +262,10 @@ public class AssetRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds an {@link Asset} by its UUID <strong>and</strong> type. This method
|
* Finds an {@link Asset} by its UUID <strong>and</strong> type.This method
|
||||||
* does not distinguish between shared and non shared assets.
|
does not distinguish between shared and non shared assets.
|
||||||
*
|
*
|
||||||
|
* @param <T> Type of the asset
|
||||||
* @param uuid The UUID of the asset to retrieve.
|
* @param uuid The UUID of the asset to retrieve.
|
||||||
* @param type The type of the asset to retrieve.
|
* @param type The type of the asset to retrieve.
|
||||||
*
|
*
|
||||||
|
|
@ -274,8 +275,9 @@ public class AssetRepository
|
||||||
* {@link Optional} is returned.
|
* {@link Optional} is returned.
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public Optional<Asset> findByUuidAndType(
|
@SuppressWarnings("unchecked")
|
||||||
final String uuid, final Class<? extends Asset> type) {
|
public <T extends Asset> Optional<T> findByUuidAndType(
|
||||||
|
final String uuid, final Class<T> type) {
|
||||||
|
|
||||||
final TypedQuery<Asset> query = entityManager.createNamedQuery(
|
final TypedQuery<Asset> query = entityManager.createNamedQuery(
|
||||||
"Asset.findByUuidAndType", Asset.class);
|
"Asset.findByUuidAndType", Asset.class);
|
||||||
|
|
@ -284,7 +286,11 @@ public class AssetRepository
|
||||||
setAuthorizationParameters(query);
|
setAuthorizationParameters(query);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Optional.of(query.getSingleResult());
|
final Asset result = query.getSingleResult();
|
||||||
|
if (result.getClass().isAssignableFrom(type)) {
|
||||||
|
return Optional.of((T) result);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
} catch (NoResultException ex) {
|
} catch (NoResultException ex) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ import javax.json.JsonObject;
|
||||||
import javax.json.JsonObjectBuilder;
|
import javax.json.JsonObjectBuilder;
|
||||||
import javax.json.JsonWriter;
|
import javax.json.JsonWriter;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
@ -115,7 +116,7 @@ public class Assets {
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String findAssets(
|
public String findAssets(
|
||||||
@PathParam("content-section") final String section,
|
@PathParam("content-section") final String section,
|
||||||
@QueryParam("query") final String query,
|
@QueryParam("query") @DefaultValue("") final String query,
|
||||||
@QueryParam("type") final String type) {
|
@QueryParam("type") final String type) {
|
||||||
|
|
||||||
final ContentSection contentSection = sectionRepo
|
final ContentSection contentSection = sectionRepo
|
||||||
|
|
|
||||||
|
|
@ -76,21 +76,11 @@ public class Images {
|
||||||
@DefaultValue("-1")
|
@DefaultValue("-1")
|
||||||
final String heightParam) {
|
final String heightParam) {
|
||||||
|
|
||||||
final Optional<Asset> asset = assetRepo
|
final Optional<Image> asset = assetRepo
|
||||||
.findByUuidAndType(uuid, Image.class);
|
.findByUuidAndType(uuid, Image.class);
|
||||||
|
|
||||||
if (asset.isPresent()) {
|
if (asset.isPresent()) {
|
||||||
if (asset.get() instanceof Image) {
|
return loadImage(asset.get(), widthParam, heightParam);
|
||||||
return loadImage((Image) asset.get(), widthParam, heightParam);
|
|
||||||
} else {
|
|
||||||
return Response
|
|
||||||
.status(Response.Status.NOT_FOUND)
|
|
||||||
.entity(String
|
|
||||||
.format("The asset with the requested UUID \"%s\" "
|
|
||||||
+ "is not an image.",
|
|
||||||
uuid))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return Response
|
return Response
|
||||||
.status(Response.Status.NOT_FOUND)
|
.status(Response.Status.NOT_FOUND)
|
||||||
|
|
@ -107,21 +97,12 @@ public class Images {
|
||||||
@PathParam("content-section") final String sectionName,
|
@PathParam("content-section") final String sectionName,
|
||||||
@PathParam("uuid") final String uuid) {
|
@PathParam("uuid") final String uuid) {
|
||||||
|
|
||||||
final Optional<Asset> asset = assetRepo.findByUuidAndType(uuid,
|
final Optional<Image> asset = assetRepo.findByUuidAndType(
|
||||||
Image.class);
|
uuid, Image.class
|
||||||
|
);
|
||||||
|
|
||||||
if (asset.isPresent()) {
|
if (asset.isPresent()) {
|
||||||
if (asset.get() instanceof Image) {
|
return readImageProperties(asset.get());
|
||||||
return readImageProperties((Image) asset.get());
|
|
||||||
} else {
|
|
||||||
return Response
|
|
||||||
.status(Response.Status.NOT_FOUND)
|
|
||||||
.entity(String
|
|
||||||
.format("The asset with the requested UUID \"%s\" "
|
|
||||||
+ "is not an image.",
|
|
||||||
uuid))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return Response
|
return Response
|
||||||
.status(Response.Status.NOT_FOUND)
|
.status(Response.Status.NOT_FOUND)
|
||||||
|
|
@ -319,7 +300,7 @@ public class Images {
|
||||||
height);
|
height);
|
||||||
|
|
||||||
final ByteArrayOutputStream outputStream
|
final ByteArrayOutputStream outputStream
|
||||||
= new ByteArrayOutputStream();
|
= new ByteArrayOutputStream();
|
||||||
final BufferedImage bufferedScaledImage = new BufferedImage(
|
final BufferedImage bufferedScaledImage = new BufferedImage(
|
||||||
scaledImage.getWidth(null),
|
scaledImage.getWidth(null),
|
||||||
scaledImage.getHeight(null),
|
scaledImage.getHeight(null),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,305 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import org.libreccm.api.Identifier;
|
||||||
|
import org.libreccm.api.IdentifierParser;
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.libreccm.security.AuthorizationRequired;
|
||||||
|
import org.librecms.assets.ContactEntry;
|
||||||
|
import org.librecms.assets.ContactEntryKey;
|
||||||
|
import org.librecms.assets.ContactEntryKeyRepository;
|
||||||
|
import org.librecms.assets.ContactEntryRepository;
|
||||||
|
import org.librecms.assets.ContactableEntity;
|
||||||
|
import org.librecms.assets.ContactableEntityManager;
|
||||||
|
import org.librecms.assets.PostalAddress;
|
||||||
|
import org.librecms.contentsection.Asset;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.mvc.Models;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import javax.ws.rs.FormParam;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractContactableEntityEditStep
|
||||||
|
extends AbstractMvcAssetEditStep {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetRepository assetRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetUi assetUi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContactEntryRepository entryRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContactEntryKeyRepository entryKeyRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContactableEntityManager contactableManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContactableEntityEditStepModel editStepModel;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IdentifierParser identifierParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Models models;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected void init() throws ContentSectionNotFoundException,
|
||||||
|
AssetNotFoundException {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
if (getAsset() instanceof ContactableEntity) {
|
||||||
|
editStepModel
|
||||||
|
.setAvailableContactEntryKeys(
|
||||||
|
entryKeyRepo
|
||||||
|
.findAll()
|
||||||
|
.stream()
|
||||||
|
.map(this::buildContactEntryKeyListItemModel)
|
||||||
|
.collect(
|
||||||
|
Collectors.toMap(
|
||||||
|
item -> item.getEntryKey(),
|
||||||
|
item -> item.getLabel()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
editStepModel
|
||||||
|
.setContactEntries(
|
||||||
|
getContactableEntity()
|
||||||
|
.getContactEntries()
|
||||||
|
.stream()
|
||||||
|
.map(this::buildContactEntryListItemModel)
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
editStepModel.setPostalAddress(
|
||||||
|
getContactableEntity().getPostalAddress()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new AssetNotFoundException(
|
||||||
|
assetUi.showAssetNotFound(
|
||||||
|
getContentSection(), getAssetPath()
|
||||||
|
),
|
||||||
|
String.format(
|
||||||
|
"No ContactableEntity for path %s found in section %s.",
|
||||||
|
getAssetPath(),
|
||||||
|
getContentSection().getLabel()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ContactableEntity getContactableEntity() {
|
||||||
|
return (ContactableEntity) getAsset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/contactentries")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String addContactEntry(
|
||||||
|
@FormParam("entryKey") final String entryKeyParam,
|
||||||
|
@FormParam("entryValue") final String entryValue
|
||||||
|
) {
|
||||||
|
final Optional<ContactEntryKey> entryKeyResult = entryKeyRepo
|
||||||
|
.findByEntryKey(entryKeyParam);
|
||||||
|
if (!entryKeyResult.isPresent()) {
|
||||||
|
return showContactEntryKeyNoFound(entryKeyParam);
|
||||||
|
}
|
||||||
|
final ContactEntryKey entryKey = entryKeyResult.get();
|
||||||
|
|
||||||
|
final ContactableEntity contactable = getContactableEntity();
|
||||||
|
final ContactEntry contactEntry = new ContactEntry();
|
||||||
|
contactEntry.setKey(entryKey);
|
||||||
|
contactEntry.setValue(entryValue);
|
||||||
|
contactableManager.addContactEntryToContactableEntity(
|
||||||
|
contactEntry, contactable
|
||||||
|
);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/contactentries/{index}")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String updateContactEntry(
|
||||||
|
@PathParam("index") final int index,
|
||||||
|
@FormParam("entryValue") final String entryValue
|
||||||
|
) {
|
||||||
|
final List<ContactEntry> entries = getContactableEntity()
|
||||||
|
.getContactEntries();
|
||||||
|
if (index >= entries.size()) {
|
||||||
|
return showContactEntryNotFound(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ContactEntry entry = entries.get(index);
|
||||||
|
entry.setValue(entryValue);
|
||||||
|
|
||||||
|
entryRepo.save(entry);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/contactentries/{index}/@remove")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String removeContactEntry(
|
||||||
|
@PathParam("index") final int index
|
||||||
|
) {
|
||||||
|
final List<ContactEntry> entries = getContactableEntity()
|
||||||
|
.getContactEntries();
|
||||||
|
if (index >= entries.size()) {
|
||||||
|
return showContactEntryNotFound(index);
|
||||||
|
}
|
||||||
|
final ContactEntry entry = entries.get(index);
|
||||||
|
|
||||||
|
contactableManager.removeContactEntryFromContactableEntity(
|
||||||
|
entry, getContactableEntity()
|
||||||
|
);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/postaladdress")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String setPostalAddress(
|
||||||
|
final String postalAddressIdentifier
|
||||||
|
) {
|
||||||
|
final Identifier identifier = identifierParser
|
||||||
|
.parseIdentifier(postalAddressIdentifier);
|
||||||
|
final Optional<PostalAddress> postalAddressResult;
|
||||||
|
switch (identifier.getType()) {
|
||||||
|
case ID:
|
||||||
|
postalAddressResult = assetRepo.findById(
|
||||||
|
Long.parseLong(identifier.getIdentifier()),
|
||||||
|
PostalAddress.class
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case UUID:
|
||||||
|
postalAddressResult = assetRepo.findByUuidAndType(
|
||||||
|
identifier.getIdentifier(),
|
||||||
|
PostalAddress.class
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
postalAddressResult = assetRepo
|
||||||
|
.findByPath(identifier.getIdentifier())
|
||||||
|
.map(result -> (PostalAddress) result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!postalAddressResult.isPresent()) {
|
||||||
|
return showPostalAddressNotFound(postalAddressIdentifier);
|
||||||
|
}
|
||||||
|
final PostalAddress postalAddress = postalAddressResult.get();
|
||||||
|
|
||||||
|
contactableManager.addPostalAddressToContactableEntity(
|
||||||
|
postalAddress, getContactableEntity()
|
||||||
|
);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/postaladdress/@remove")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String removePostalAddress() {
|
||||||
|
contactableManager.removePostalAddressFromContactableEntity(
|
||||||
|
getContactableEntity().getPostalAddress(), getContactableEntity()
|
||||||
|
);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String showContactEntryNotFound(
|
||||||
|
final int index
|
||||||
|
) {
|
||||||
|
models.put("entryIndex", index);
|
||||||
|
return "org/librecms/ui/contentsection/assets/contactable/entry-not-found.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String showContactEntryKeyNoFound(final String entryKeyParam) {
|
||||||
|
models.put("entryKeyParam", entryKeyParam);
|
||||||
|
return "org/librecms/ui/contentsection/assets/contactable/entry-key-not-found.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String showPostalAddressNotFound(
|
||||||
|
final String postalAddressIdentifier
|
||||||
|
) {
|
||||||
|
models.put("postalAddressIdentifier", postalAddressIdentifier);
|
||||||
|
return "org/librecms/ui/contentsection/assets/contactable/postal-address-not-found.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContactEntryKeyListItemModel buildContactEntryKeyListItemModel(
|
||||||
|
final ContactEntryKey entryKey
|
||||||
|
) {
|
||||||
|
final ContactEntryKeyListItemModel model
|
||||||
|
= new ContactEntryKeyListItemModel();
|
||||||
|
model.setKeyId(entryKey.getKeyId());
|
||||||
|
model.setEntryKey(entryKey.getEntryKey());
|
||||||
|
model.setLabel(
|
||||||
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
entryKey.getLabel())
|
||||||
|
);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContactEntryListItemModel buildContactEntryListItemModel(
|
||||||
|
final ContactEntry entry
|
||||||
|
) {
|
||||||
|
final ContactEntryListItemModel model = new ContactEntryListItemModel();
|
||||||
|
model.setContactEntryId(entry.getContactEntryId());
|
||||||
|
model.setEntryKey(entry.getKey().getEntryKey());
|
||||||
|
model.setEntryKeyId(entry.getKey().getKeyId());
|
||||||
|
model.setEntryKeyLabel(
|
||||||
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
entry.getKey().getLabel()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
model.setOrder(entry.getOrder());
|
||||||
|
model.setValue(entry.getValue());
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ContactEntryKeyListItemModel {
|
||||||
|
|
||||||
|
private long keyId;
|
||||||
|
|
||||||
|
private String entryKey;
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
public long getKeyId() {
|
||||||
|
return keyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setKeyId(final long keyId) {
|
||||||
|
this.keyId = keyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntryKey() {
|
||||||
|
return entryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setEntryKey(final String entryKey) {
|
||||||
|
this.entryKey = entryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setLabel(final String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ContactEntryListItemModel {
|
||||||
|
|
||||||
|
private long contactEntryId;
|
||||||
|
|
||||||
|
private long order;
|
||||||
|
|
||||||
|
private long entryKeyId;
|
||||||
|
|
||||||
|
private String entryKey;
|
||||||
|
|
||||||
|
private String entryKeyLabel;
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public long getContactEntryId() {
|
||||||
|
return contactEntryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setContactEntryId(final long contactEntryId) {
|
||||||
|
this.contactEntryId = contactEntryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setOrder(final long order) {
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getEntryKeyId() {
|
||||||
|
return entryKeyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setEntryKeyId(final long entryKeyId) {
|
||||||
|
this.entryKeyId = entryKeyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntryKey() {
|
||||||
|
return entryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setEntryKey(final String entryKey) {
|
||||||
|
this.entryKey = entryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntryKeyLabel() {
|
||||||
|
return entryKeyLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setEntryKeyLabel(final String entryKeyLabel) {
|
||||||
|
this.entryKeyLabel = entryKeyLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setValue(final String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import org.librecms.assets.PostalAddress;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsContactableEditStepModel")
|
||||||
|
public class ContactableEntityEditStepModel {
|
||||||
|
|
||||||
|
private Map<String, String> availableContactEntryKeys;
|
||||||
|
|
||||||
|
private List<ContactEntryListItemModel> contactEntries;
|
||||||
|
|
||||||
|
private PostalAddress postalAddress;
|
||||||
|
|
||||||
|
public Map<String, String> getAvailableContactEntryKeys() {
|
||||||
|
return Collections.unmodifiableMap(availableContactEntryKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailableContactEntryKeys(
|
||||||
|
final Map<String, String> availableContactEntryKeys
|
||||||
|
) {
|
||||||
|
this.availableContactEntryKeys = new HashMap<>(
|
||||||
|
availableContactEntryKeys
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ContactEntryListItemModel> getContactEntries() {
|
||||||
|
return Collections.unmodifiableList(contactEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setContactEntries(
|
||||||
|
final List<ContactEntryListItemModel> contactEntries
|
||||||
|
) {
|
||||||
|
this.contactEntries = new ArrayList<>(contactEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostalAddress getPostalAddress() {
|
||||||
|
return postalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPostalAddress(final PostalAddress postalAddress) {
|
||||||
|
this.postalAddress = postalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -29,18 +29,14 @@ import org.librecms.contentsection.AssetRepository;
|
||||||
import org.librecms.ui.contentsections.AssetPermissionsChecker;
|
import org.librecms.ui.contentsections.AssetPermissionsChecker;
|
||||||
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.activation.MimeType;
|
import javax.activation.MimeType;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.librecms.assets.Person;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsPersonCreateStep")
|
||||||
|
public class PersonCreateStep extends AbstractMvcAssetCreateStep<Person> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetRepository assetRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String showCreateStep() {
|
||||||
|
return "org/librecms/ui/contentsection/assets/person/create-person.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return globalizationHelper
|
||||||
|
.getLocalizedTextsUtil(getBundle())
|
||||||
|
.getText("person.label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return globalizationHelper
|
||||||
|
.getLocalizedTextsUtil(getBundle())
|
||||||
|
.getText("person.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBundle() {
|
||||||
|
return MvcAssetStepsConstants.BUNDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<Person> getAssetClass() {
|
||||||
|
return Person.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String setAssetProperties(
|
||||||
|
final Person person, final Map<String, String[]> formParams
|
||||||
|
) {
|
||||||
|
return String.format(
|
||||||
|
"redirect:/%s/assets/%s/%s/@person-edit",
|
||||||
|
getContentSectionLabel(),
|
||||||
|
getFolderPath(),
|
||||||
|
getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,265 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.libreccm.security.AuthorizationRequired;
|
||||||
|
import org.librecms.assets.Person;
|
||||||
|
import org.librecms.assets.PersonManager;
|
||||||
|
import org.librecms.assets.PersonName;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
import org.librecms.ui.contentsections.AssetPermissionsChecker;
|
||||||
|
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||||
|
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.FormatStyle;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.mvc.Controller;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Path(MvcAssetEditSteps.PATH_PREFIX + "person-edit")
|
||||||
|
@Controller
|
||||||
|
@MvcAssetEditStepDef(
|
||||||
|
bundle = MvcAssetStepsConstants.BUNDLE,
|
||||||
|
descriptionKey = "person.editstep.description",
|
||||||
|
labelKey = "person.editstep.lable",
|
||||||
|
supportedAssetType = Person.class
|
||||||
|
)
|
||||||
|
public class PersonEditStep extends AbstractContactableEntityEditStep {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetStepsDefaultMessagesBundle messageBundle;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetPermissionsChecker assetPermissionsChecker;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetRepository assetRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetUi assetUi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PersonEditStepModel editStepModel;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PersonManager personManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends MvcAssetEditStep> getStepClass() {
|
||||||
|
return PersonEditStep.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Person getPerson() {
|
||||||
|
return (Person) getAsset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() throws ContentSectionNotFoundException,
|
||||||
|
AssetNotFoundException {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
if (getAsset() instanceof Person) {
|
||||||
|
editStepModel.setBirthdate(
|
||||||
|
DateTimeFormatter
|
||||||
|
.ofLocalizedDate(FormatStyle.SHORT)
|
||||||
|
.withLocale(globalizationHelper.getNegotiatedLocale())
|
||||||
|
.format(getPerson().getBirthdate())
|
||||||
|
);
|
||||||
|
editStepModel.setPersonNames(getPerson().getPersonNames());
|
||||||
|
} else {
|
||||||
|
throw new AssetNotFoundException(
|
||||||
|
assetUi.showAssetNotFound(
|
||||||
|
getContentSection(), getAssetPath()
|
||||||
|
),
|
||||||
|
String.format(
|
||||||
|
"No Person for path %s found in section %s.",
|
||||||
|
getAssetPath(),
|
||||||
|
getContentSection().getLabel()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public String showStep(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
return "org/librecms/ui/contentsection/assets/person/edit-person.xhtml";
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/personnames/@add")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String addPersonName(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath,
|
||||||
|
@FormParam("surname") final String surname,
|
||||||
|
@FormParam("givenName") final String givenName,
|
||||||
|
@FormParam("prefix") final String prefix,
|
||||||
|
@FormParam("suffix") final String suffix
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
final PersonName personName = new PersonName();
|
||||||
|
personName.setGivenName(givenName);
|
||||||
|
personName.setPrefix(prefix);
|
||||||
|
personName.setSuffix(suffix);
|
||||||
|
personName.setSurname(surname);
|
||||||
|
personManager.addPersonName(getPerson(), personName);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/personnames/{index}/@edit")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String updatePersonName(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath,
|
||||||
|
@PathParam("index") final int index,
|
||||||
|
@FormParam("surname") final String surname,
|
||||||
|
@FormParam("givenName") final String givenName,
|
||||||
|
@FormParam("prefix") final String prefix,
|
||||||
|
@FormParam("suffix") final String suffix
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
if (index < getPerson().getPersonNames().size()) {
|
||||||
|
final PersonName personName = getPerson()
|
||||||
|
.getPersonNames()
|
||||||
|
.get(index);
|
||||||
|
|
||||||
|
personName.setGivenName(givenName);
|
||||||
|
personName.setPrefix(prefix);
|
||||||
|
personName.setSuffix(suffix);
|
||||||
|
personName.setSurname(surname);
|
||||||
|
|
||||||
|
assetRepo.save(getPerson());
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/personnames/{index}/@remove")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String removePersonName(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath,
|
||||||
|
@PathParam("index") final int index
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
if (index < getPerson().getPersonNames().size()) {
|
||||||
|
final PersonName personName = getPerson()
|
||||||
|
.getPersonNames()
|
||||||
|
.get(index);
|
||||||
|
personManager.removePersonName(getPerson(), personName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import org.librecms.assets.PersonName;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsPersonEditStepModel")
|
||||||
|
public class PersonEditStepModel {
|
||||||
|
|
||||||
|
private List<PersonName> personName;
|
||||||
|
|
||||||
|
private String birthdate;
|
||||||
|
|
||||||
|
public List<PersonName> getPersonNames() {
|
||||||
|
return Collections.unmodifiableList(personName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPersonNames(final List<PersonName> personNames) {
|
||||||
|
this.personName = new ArrayList<>(personNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBirthdate() {
|
||||||
|
return birthdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setBirthdate(final String birthdate) {
|
||||||
|
this.birthdate = birthdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
|
||||||
|
<cc:interface shortDescription="An component for selecting assets.">
|
||||||
|
<cc:attribute name="action"
|
||||||
|
required="true"
|
||||||
|
shortDescription="Action to trigger when an asset has been selected."
|
||||||
|
type="String" />
|
||||||
|
<cc:attribute name="assetType"
|
||||||
|
required="false"
|
||||||
|
shortDescription="Type of assets to show."
|
||||||
|
type="String"
|
||||||
|
default="org.librecms.assets.Asset" />
|
||||||
|
<cc:attribute name="assetPickerId"
|
||||||
|
required="true"
|
||||||
|
shortDescription="ID of the asset picker"
|
||||||
|
type="String" />
|
||||||
|
<cc:attribute name="contentSection"
|
||||||
|
required="true"
|
||||||
|
shortDescription="The current content section."
|
||||||
|
type="String" />
|
||||||
|
<cc:attribute name="dialogTitle"
|
||||||
|
required="false"
|
||||||
|
shortDescription="Title of the asset picker dialog"
|
||||||
|
default="#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.title']}"
|
||||||
|
type="String"
|
||||||
|
/>
|
||||||
|
<cc:attribute name="formParamName"
|
||||||
|
required="true"
|
||||||
|
shortDescription="The name of the form parameter that will contain the UUID of the selected asset."
|
||||||
|
type="String"
|
||||||
|
/>
|
||||||
|
<cc:attribute name="headingLevel"
|
||||||
|
required="false"
|
||||||
|
shortDescription="The level of the heading used as title of the asset picker dialog."
|
||||||
|
default="3"
|
||||||
|
type="int" />
|
||||||
|
</cc:interface>
|
||||||
|
|
||||||
|
<cc:implementation>
|
||||||
|
<div class="ccm-cms-asset-picker"
|
||||||
|
data-assettype="#{cc.attrs.assetType}"
|
||||||
|
data-contentsection="#{cc.attrs.contentSection}">
|
||||||
|
<div aria-hidden="true"
|
||||||
|
aria-labelledby="#{cc.attrs.assetPickerId}-dialog-title"
|
||||||
|
class="modal fade"
|
||||||
|
id="#{cc.attrs.assetPickerId}-dialog"
|
||||||
|
tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<c:choose>
|
||||||
|
<c:when test="#{cc.attrs.headingLevel == 1}">
|
||||||
|
<h1 class="modal-title"
|
||||||
|
id="#{cc.attrs.assetPickerId}-dialog-title">#{cc.attrs.dialogTitle}</h1>
|
||||||
|
</c:when>
|
||||||
|
<c:when test="#{cc.attrs.headingLevel == 2}">
|
||||||
|
<h2 class="modal-title"
|
||||||
|
id="#{cc.attrs.assetPickerId}-dialog-title">#{cc.attrs.dialogTitle}</h2>
|
||||||
|
</c:when>
|
||||||
|
<c:when test="#{cc.attrs.headingLevel == 3}">
|
||||||
|
<h3 class="modal-title"
|
||||||
|
id="#{cc.attrs.assetPickerId}-dialog-title">#{cc.attrs.dialogTitle}</h3>
|
||||||
|
</c:when>
|
||||||
|
<c:when test="#{cc.attrs.headingLevel == 4}">
|
||||||
|
<h4 class="modal-title"
|
||||||
|
id="#{cc.attrs.assetPickerId}-dialog-title">#{cc.attrs.dialogTitle}</h4>
|
||||||
|
</c:when>
|
||||||
|
<c:when test="#{cc.attrs.headingLevel == 5}">
|
||||||
|
<h5 class="modal-title"
|
||||||
|
id="#{cc.attrs.assetPickerId}-dialog-title">#{cc.attrs.dialogTitle}</h5>
|
||||||
|
</c:when>
|
||||||
|
<c:when test="#{cc.attrs.headingLevel == 6}">
|
||||||
|
<h6 class="modal-title"
|
||||||
|
id="#{cc.attrs.assetPickerId}-dialog-title">#{cc.attrs.dialogTitle}</h6>
|
||||||
|
</c:when>
|
||||||
|
<c:otherwise>
|
||||||
|
<div><strong>#{cc.attrs.dialogTitle}</strong></div>
|
||||||
|
</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
|
<button
|
||||||
|
aria-label="#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.close']}"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form action="#{cc.attrs.action}"
|
||||||
|
class="modal-content"
|
||||||
|
method="post">
|
||||||
|
<input class="assetpicker-param"
|
||||||
|
id="#{cc.attrs.assetPickerId}-param-input"
|
||||||
|
name="#{cc.attrs.formParamName}"
|
||||||
|
type="hidden" />
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
class="assetpicker-filter"
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.filter.help']}"
|
||||||
|
inputId="#{cc.attrs.assetPickerId}-filter"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.filter.label']}"
|
||||||
|
name="" />
|
||||||
|
<template id="#{cc.attrs.assetPickerId}-row">
|
||||||
|
<tr>
|
||||||
|
<td class="col-name"></td>
|
||||||
|
<td class="col-type"></td>
|
||||||
|
<td class="col-action">
|
||||||
|
<button class="btn btn-primary"
|
||||||
|
data-assetuuid=""
|
||||||
|
type="button">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.select']}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.name']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.type']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.action']}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-warning"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['assetpicker.close']}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</cc:implementation>
|
||||||
|
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
|
||||||
|
|
||||||
|
<cc:interface shortDescription="An component for selecting assets.">
|
||||||
|
|
||||||
|
<cc:attribute name="assetPickerId"
|
||||||
|
required="true"
|
||||||
|
shortDescription="ID of the asset picker"
|
||||||
|
type="String" />
|
||||||
|
</cc:interface>
|
||||||
|
<cc:implementation>
|
||||||
|
<button class="btn btn-primary"
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="##{cc.attrs.assetPickerId}-dialog"
|
||||||
|
type="button" />
|
||||||
|
</cc:implementation>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>#{CmsAssetsStepsDefaultMessagesBundle["bookmark.createform.title"]}</h1>
|
<h1>#{CmsAssetsStepsDefaultMessagesBundle["bookmark.createform.title"]}</h1>
|
||||||
|
|
||||||
<c:forEach items="#{CmsBookmarkCreateStep.messages.entrySet()}"
|
<c:forEach items="#{CmsBookmarkCreateStep.messages.entrySet()}"
|
||||||
var="message">
|
var="message">
|
||||||
<div class="alert alert-#{message.key}" role="alert">
|
<div class="alert alert-#{message.key}" role="alert">
|
||||||
#{message.value}
|
#{message.value}
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
<form action="#{mvc.basePath}/#{CmsBookmarkCreateStep.contentSectionLabel}/assets/#{CmsBookmarkCreateStep.folderPath}@create/#{CmsBookmarkCreateStep.assetType}"
|
<form action="#{mvc.basePath}/#{CmsBookmarkCreateStep.contentSectionLabel}/assets/#{CmsBookmarkCreateStep.folderPath}@create/#{CmsBookmarkCreateStep.assetType}"
|
||||||
method="post">
|
method="post">
|
||||||
<bootstrap:formGroupText
|
<bootstrap:formGroupText
|
||||||
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.help']}"
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.help']}"
|
||||||
inputId="name"
|
inputId="name"
|
||||||
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.label']}"
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.label']}"
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
name="description"
|
name="description"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<a class="btn btn-warning"
|
<a class="btn btn-warning"
|
||||||
href="#{mvc.basePath}/#{CmsBookmarkCreateStep.contentSectionLabel}/assetfolders/#{CmsBookmarkCreateStep.folderPath}">
|
href="#{mvc.basePath}/#{CmsBookmarkCreateStep.contentSectionLabel}/assetfolders/#{CmsBookmarkCreateStep.folderPath}">
|
||||||
#{CmsAssetsStepsDefaultMessagesBundle['createform.cancel']}
|
#{CmsAssetsStepsDefaultMessagesBundle['createform.cancel']}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||||
|
<ui:composition>
|
||||||
|
|
||||||
|
<h3>#{CmsAssetsStepsDefaultMessagesBundle['contactable.contactentries.title']}</h3>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['contactable.contactentries.cols.key']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['contactable.contactentries.cols.value']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['contactable.contactentries.cols.actions']}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<c:forEach items="#{CmsContactableEditStepModel.contactEntries}"
|
||||||
|
var="entry">
|
||||||
|
<tr data-entrykey="#{entry.entryKey}">
|
||||||
|
<td>#{entry.entryKeyLabel}</td>
|
||||||
|
<td>#{entry.value}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-primary"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="pen" />
|
||||||
|
<span class="sr-only">#{CmsAssetsStepsDefaultMessagesBundle['contactable.contactentries.edit']}</span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x-circle" />
|
||||||
|
<span class="sr-only">#{CmsAssetsStepsDefaultMessagesBundle['contactable.contactentries.remove']}</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</c:forEach>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||||
|
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/contentsection.xhtml">
|
||||||
|
|
||||||
|
<ui:define name="main">
|
||||||
|
<div class="container">
|
||||||
|
<h1>#{CmsAssetsStepsDefaultMessagesBundle["person.createform.title"]}</h1>
|
||||||
|
|
||||||
|
<c:forEach items="#{CmsBookmarkCreateStep.messages.entrySet()}"
|
||||||
|
var="message">
|
||||||
|
<div class="alert alert-#{message.key}" role="alert">
|
||||||
|
#{message.value}
|
||||||
|
</div>
|
||||||
|
</c:forEach>
|
||||||
|
|
||||||
|
<form action="#{mvc.basePath}/#{CmsPersonCreateStep.contentSectionLabel}/assets/#{CmsPersonCreateStep.folderPath}@create/#{CmsPersonCreateStep.assetType}"
|
||||||
|
method="post">
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.help']}"
|
||||||
|
inputId="name"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.label']}"
|
||||||
|
name="name"
|
||||||
|
pattern="^([a-zA-Z0-9_-]*)$"
|
||||||
|
required="true"
|
||||||
|
value="#{CmsBookmarkCreateStep.name}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<bootstrap:formGroupSelect
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.initial_locale.help']}"
|
||||||
|
inputId="locale"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.initial_locale.label']}"
|
||||||
|
name="locale"
|
||||||
|
options="#{CmsBookmarkCreateStep.availableLocales}"
|
||||||
|
required="true"
|
||||||
|
selectedOptions="#{[CmsBookmarkCreateStep.initialLocale]}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.title.help']}"
|
||||||
|
inputId="title"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.title.label']}"
|
||||||
|
name="title"
|
||||||
|
required="true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<a class="btn btn-warning"
|
||||||
|
href="#{mvc.basePath}/#{CmsBookmarkCreateStep.contentSectionLabel}/assetfolders/#{CmsBookmarkCreateStep.folderPath}">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['createform.cancel']}
|
||||||
|
</a>
|
||||||
|
<button class="btn btn-success"
|
||||||
|
type="submit">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['createform.submit']}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ui:define>
|
||||||
|
</ui:composition>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,255 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||||
|
|
||||||
|
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/assets/editstep.xhtml">
|
||||||
|
|
||||||
|
<ui:param name="stepControllerUrl"
|
||||||
|
value="@person-edit"
|
||||||
|
/>
|
||||||
|
<ui:param name="title"
|
||||||
|
value="#{CmsAssetsStepsDefaultMessagesBundle.getMessage('person.editstep.header', [MvcAssetEditStepModel.name])}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ui:define name="editStep">
|
||||||
|
|
||||||
|
<h3>#{CmsAssetsStepsDefaultMessagesBundle['person.personnames']}</h3>
|
||||||
|
<div class="text-right">
|
||||||
|
<button class="btn btn-primary"
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="#add-personname-dialog"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="plus-circle" />
|
||||||
|
<span class="sr-only">#{CmsAssetsStepsDefaultMessagesBundle['person.personname.add']}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div aria-hidden="true"
|
||||||
|
aria-labelledby="add-personname-dialog-title"
|
||||||
|
class="modal fade"
|
||||||
|
id="add-personname-dialog"
|
||||||
|
tab accesskey="-1"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/asset/#{CmsSelectedAssetModel.assetPath}/@person-edit/personnames/@add"
|
||||||
|
class="modal-content"
|
||||||
|
method="post">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 id="add-personname-dialog-title">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.add.dialog.title']}
|
||||||
|
</h4>
|
||||||
|
<button
|
||||||
|
aria-label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.add.dialog.close']}"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.prefix.help']}"
|
||||||
|
inputId="prefix"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.prefix.label']}"
|
||||||
|
name="prefix" />
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.surname.help']}"
|
||||||
|
inputId="surname"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.surname.label']}"
|
||||||
|
name="surname" />
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.givenname.help']}"
|
||||||
|
inputId="givenName"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.givenname.label']}"
|
||||||
|
name="givenName" />
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.suffix.help']}"
|
||||||
|
inputId="suffix"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.suffix.label']}"
|
||||||
|
name="suffix" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-warning"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.add.dialog.close']}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-success"
|
||||||
|
type="submit">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.add.dialog.submit']}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['person.personnames.col.prefix']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['person.personnames.col.surname']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['person.personnames.col.givenname']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['person.personnames.col.suffix']}</th>
|
||||||
|
<th>#{CmsAssetsStepsDefaultMessagesBundle['person.personnames.col.actions']}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<c:forEach items="#{CmsPersonEditStepModel.personNames}"
|
||||||
|
var="personName">
|
||||||
|
<tr>
|
||||||
|
<td>#{personName.prefix}</td>
|
||||||
|
<td>#{personName.surname}</td>
|
||||||
|
<td>#{personName.givenName}</td>
|
||||||
|
<td>#{personName.suffix}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-primary"
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="#personname-edit-dialog-#{personName.hashCode()}"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="pen" />
|
||||||
|
<span class="sr-only">#{CmsAssetsStepsDefaultMessagesBundle['person.personname.edit']}</span>
|
||||||
|
</button>
|
||||||
|
<div aria-hidden="true"
|
||||||
|
aria-lablledby="personname-edit-dialog-#{personName.hashCode()}-title"
|
||||||
|
class="modal fade"
|
||||||
|
id="personname-edit-dialog-#{personName.hashCode()}"
|
||||||
|
tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/asset/#{CmsSelectedAssetModel.assetPath}/@person-edit/personnames/@edit"
|
||||||
|
class="modal-content"
|
||||||
|
method="post">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 id="personname-edit-dialog-#{personName.hashCode()}-title">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.edit.dialog.title']}
|
||||||
|
</h4>
|
||||||
|
<button
|
||||||
|
aria-label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.edit.dialog.close']}"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.prefix.help']}"
|
||||||
|
inputId="prefix"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.prefix.label']}"
|
||||||
|
name="prefix"
|
||||||
|
value="#{personName.prefix}" />
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.surname.help']}"
|
||||||
|
inputId="surname"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.surname.label']}"
|
||||||
|
name="surname"
|
||||||
|
value="#{personName.surname}" />
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.givenname.help']}"
|
||||||
|
inputId="givenName"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.givenname.label']}"
|
||||||
|
name="givenName"
|
||||||
|
value="#{personName.givenName}" />
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.suffix.help']}"
|
||||||
|
inputId="suffix"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.suffix.label']}"
|
||||||
|
name="suffix"
|
||||||
|
value="#{personName.suffix}" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-warning"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.edit.dialog.close']}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-success"
|
||||||
|
type="submit">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.edit.dialog.submit']}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-danger"
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="#personname-remove-dialog-#{personName.hashCode()}"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x-circle" />
|
||||||
|
<span class="sr-only">#{CmsAssetsStepsDefaultMessagesBundle['person.personname.remove']}</span>
|
||||||
|
</button>
|
||||||
|
<div aria-hidden="true"
|
||||||
|
aria-lablledby="personname-remove-dialog-#{personName.hashCode()}-title"
|
||||||
|
class="modal fade"
|
||||||
|
id="personname-remove-dialog-#{personName.hashCode()}"
|
||||||
|
tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/asset/#{CmsSelectedAssetModel.assetPath}/@person-edit/personnames/@remove"
|
||||||
|
class="modal-content"
|
||||||
|
method="post">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 id="personname-edit-dialog-#{personName.hashCode()}-title">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.remove.dialog.title']}
|
||||||
|
</h4>
|
||||||
|
<button
|
||||||
|
aria-label="#{CmsAssetsStepsDefaultMessagesBundle['person.personname.remove.dialog.close']}"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<input name="confirmed"
|
||||||
|
type="hidden"
|
||||||
|
value="true"/>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.remove.dialog.message']}
|
||||||
|
</p>
|
||||||
|
<dl>
|
||||||
|
<div>
|
||||||
|
<dt>person.personname.prefix.label</dt>
|
||||||
|
<dd>#{personName.prefix}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>person.personname.surname.label</dt>
|
||||||
|
<dd>#{personName.surname}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>person.personname.givename.label</dt>
|
||||||
|
<dd>#{personName.givenName}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>person.personname.suffix.label</dt>
|
||||||
|
<dd>#{personName.suffix}</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-warning"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.remove.dialog.close']}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-success"
|
||||||
|
type="submit">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['person.personname.remove.dialog.submit']}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</c:forEach>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<ui:include src="../edit-contactable.xhtml" />
|
||||||
|
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -88,3 +88,10 @@ relatedinfo.attachmentlists.attachment.remove.cancel=Cancel
|
||||||
relatedinfo.attachmentlists.attachment.remove.confirm=Remove attachment from list
|
relatedinfo.attachmentlists.attachment.remove.confirm=Remove attachment from list
|
||||||
relatedinfo.attachmentlists.attachment.remove.title=Remove Attachment from List
|
relatedinfo.attachmentlists.attachment.remove.title=Remove Attachment from List
|
||||||
relatedinfo.attachmentlists.attachment.remove.message=Are you sure to remove the attachment {0} from the list?
|
relatedinfo.attachmentlists.attachment.remove.message=Are you sure to remove the attachment {0} from the list?
|
||||||
|
assetpicker.title=Select asset to use
|
||||||
|
assetpicker.close=Cancel
|
||||||
|
assetpicker.select=Use this asset
|
||||||
|
assetpicker.column.name=Name
|
||||||
|
assetpicker.column.type=Typ
|
||||||
|
assetpicker.column.action=Action
|
||||||
|
person.createform.title=Create new Person
|
||||||
|
|
|
||||||
|
|
@ -88,3 +88,10 @@ relatedinfo.attachmentlists.attachment.remove.cancel=Abbrechen
|
||||||
relatedinfo.attachmentlists.attachment.remove.confirm=Anhang aus Liste entfernen
|
relatedinfo.attachmentlists.attachment.remove.confirm=Anhang aus Liste entfernen
|
||||||
relatedinfo.attachmentlists.attachment.remove.title=Anhang aus Liste entfernen
|
relatedinfo.attachmentlists.attachment.remove.title=Anhang aus Liste entfernen
|
||||||
relatedinfo.attachmentlists.attachment.remove.message=Sind Sie sicher, dass Sie den Anhang {0} aus der Listen entfernen wollen?
|
relatedinfo.attachmentlists.attachment.remove.message=Sind Sie sicher, dass Sie den Anhang {0} aus der Listen entfernen wollen?
|
||||||
|
assetpicker.title=Asset ausw\u00e4hlen
|
||||||
|
assetpicker.close=Abbrechen
|
||||||
|
assetpicker.select=Dieses Asset verwenden
|
||||||
|
assetpicker.column.name=Name
|
||||||
|
assetpicker.column.type=Typ
|
||||||
|
assetpicker.column.action=Aktion
|
||||||
|
person.createform.title=Neue Person erstellen
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
import "bootstrap";
|
import "bootstrap";
|
||||||
|
|
||||||
|
import "./cms-assetpicker";
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import * as $ from "jquery";
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function (event) {
|
||||||
|
const assetPickers = document.querySelectorAll("ccm-cms-asset-picker");
|
||||||
|
|
||||||
|
for (let i = 0; i < assetPickers.length; i++) {
|
||||||
|
initAssetPicker(assetPickers[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function initAssetPicker(assetPickerElem: Element) {
|
||||||
|
const assetPickerId = assetPickerElem.getAttribute("id");
|
||||||
|
const assetType = getAssetType(assetPickerElem);
|
||||||
|
const contentSection = assetPickerElem.getAttribute("data-contentsection");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`/content-sections/${contentSection}/assets/?type=${assetType}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const assets = (await response.json()) as [];
|
||||||
|
|
||||||
|
const rowTemplate = assetPickerElem.querySelector(
|
||||||
|
`#${assetPickerId}-row`
|
||||||
|
);
|
||||||
|
|
||||||
|
const tbody = assetPickerElem.querySelector("tbody");
|
||||||
|
|
||||||
|
for (const asset of assets) {
|
||||||
|
const row = rowTemplate.cloneNode(true) as Element;
|
||||||
|
const colName = row.querySelector(".col-name");
|
||||||
|
const colType = row.querySelector(".col-type");
|
||||||
|
const selectButton = row.querySelector(".col-action button");
|
||||||
|
|
||||||
|
colName.textContent = asset["name"];
|
||||||
|
colType.textContent = asset["type"];
|
||||||
|
selectButton.setAttribute("data-assetuuid", asset["uuid"]);
|
||||||
|
|
||||||
|
selectButton.addEventListener("click", event =>
|
||||||
|
selectAsset(event, assetPickerElem)
|
||||||
|
);
|
||||||
|
|
||||||
|
tbody.appendChild(row);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAssetType(assetPickerElem: Element) {
|
||||||
|
if (assetPickerElem.hasAttribute("data-assettype")) {
|
||||||
|
return assetPickerElem.getAttribute("data-assettype");
|
||||||
|
} else {
|
||||||
|
return "org.librecms.assets.Asset";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function selectAsset(event: Event, assetPickerElem: Element) {
|
||||||
|
const selectButton = event.currentTarget as Element;
|
||||||
|
const assetUuid = selectButton.getAttribute("data-assetuuid");
|
||||||
|
|
||||||
|
const assetPickerParam = assetPickerElem.querySelector(
|
||||||
|
".assetpicker-param"
|
||||||
|
) as HTMLInputElement;
|
||||||
|
assetPickerParam.value = assetUuid;
|
||||||
|
|
||||||
|
const form = assetPickerElem.querySelector("form") as HTMLFormElement;
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue