CCM NG/ccm-cms:
- AssetSearchWidget - Form für ExternalVideoAsset git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4675 8810af33-2d31-482b-a856-94f89814c4df
parent
7a691b184a
commit
41a937882e
|
|
@ -42,6 +42,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.shiro.authz.AuthorizationException;
|
import org.apache.shiro.authz.AuthorizationException;
|
||||||
import org.libreccm.cdi.utils.CdiUtil;
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.core.UnexpectedErrorException;
|
||||||
import org.libreccm.security.PermissionChecker;
|
import org.libreccm.security.PermissionChecker;
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.security.User;
|
import org.libreccm.security.User;
|
||||||
|
|
@ -456,10 +457,15 @@ public class CMSDispatcher implements Dispatcher, ChainedDispatcher {
|
||||||
url = url.substring(debugXSLString.length());
|
url = url.substring(debugXSLString.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String sectionLabel = url;
|
||||||
|
|
||||||
// Fetch the current site node from the URL.
|
// Fetch the current site node from the URL.
|
||||||
final ContentSectionRepository sectionRepo = CdiUtil.createCdiUtil()
|
final ContentSectionRepository sectionRepo = CdiUtil.createCdiUtil()
|
||||||
.findBean(ContentSectionRepository.class);
|
.findBean(ContentSectionRepository.class);
|
||||||
ContentSection section = sectionRepo.findByLabel(url);
|
final ContentSection section = sectionRepo
|
||||||
|
.findByLabel(url)
|
||||||
|
.orElseThrow(() -> new UnexpectedErrorException(
|
||||||
|
String.format("No ContentSection '%s' found.", sectionLabel)));
|
||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ import com.arsdigita.cms.ui.folder.FolderTreeModelController;
|
||||||
import com.arsdigita.globalization.GlobalizedMessage;
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
import com.arsdigita.toolbox.ui.ActionGroup;
|
import com.arsdigita.toolbox.ui.ActionGroup;
|
||||||
import com.arsdigita.toolbox.ui.LayoutPanel;
|
import com.arsdigita.toolbox.ui.LayoutPanel;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
@ -100,7 +101,6 @@ import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.TooManyListenersException;
|
import java.util.TooManyListenersException;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import static org.librecms.CmsConstants.*;
|
import static org.librecms.CmsConstants.*;
|
||||||
|
|
||||||
|
|
@ -137,7 +137,7 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
||||||
private TargetSelector targetSelector;
|
private TargetSelector targetSelector;
|
||||||
|
|
||||||
private SegmentedPanel.Segment browseSegment;
|
private SegmentedPanel.Segment browseSegment;
|
||||||
private SegmentedPanel.Segment currentFolderSegment;
|
// private SegmentedPanel.Segment currentFolderSegment;
|
||||||
private SegmentedPanel.Segment actionsSegment;
|
private SegmentedPanel.Segment actionsSegment;
|
||||||
private SegmentedPanel.Segment newFolderSegment;
|
private SegmentedPanel.Segment newFolderSegment;
|
||||||
private SegmentedPanel.Segment editFolderSegment;
|
private SegmentedPanel.Segment editFolderSegment;
|
||||||
|
|
@ -315,28 +315,28 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
||||||
// browseSegment.add(folderBrowser);
|
// browseSegment.add(folderBrowser);
|
||||||
browseSegment.add(browserForm);
|
browseSegment.add(browserForm);
|
||||||
|
|
||||||
currentFolderSegment = panel.addSegment();
|
// currentFolderSegment = panel.addSegment();
|
||||||
currentFolderSegment.addHeader(new Text("Current folder"));
|
// currentFolderSegment.addHeader(new Text("Current folder"));
|
||||||
final Label currentFolderLabel = new Label();
|
// final Label currentFolderLabel = new Label();
|
||||||
currentFolderLabel.addPrintListener(new PrintListener() {
|
// currentFolderLabel.addPrintListener(new PrintListener() {
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void prepare(final PrintEvent event) {
|
// public void prepare(final PrintEvent event) {
|
||||||
final PageState state = event.getPageState();
|
// final PageState state = event.getPageState();
|
||||||
final Label target = (Label) event.getTarget();
|
// final Label target = (Label) event.getTarget();
|
||||||
|
//
|
||||||
final long selectedId = Long.parseLong(selectionModel
|
// final long selectedId = Long.parseLong(selectionModel
|
||||||
.getSelectedKey(state).toString());
|
// .getSelectedKey(state).toString());
|
||||||
final long currentFolderId = folderSelectionModel
|
// final long currentFolderId = folderSelectionModel
|
||||||
.getSelectedObject(state).getObjectId();
|
// .getSelectedObject(state).getObjectId();
|
||||||
target.setLabel(String.format(
|
// target.setLabel(String.format(
|
||||||
"selectedId = %d; currentFolderId = %d",
|
// "selectedId = %d; currentFolderId = %d",
|
||||||
selectedId,
|
// selectedId,
|
||||||
currentFolderId));
|
// currentFolderId));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
});
|
// });
|
||||||
currentFolderSegment.add(currentFolderLabel);
|
// currentFolderSegment.add(currentFolderLabel);
|
||||||
|
|
||||||
actionsSegment = panel.addSegment();
|
actionsSegment = panel.addSegment();
|
||||||
actionsSegment.setIdAttr("folder-browse");
|
actionsSegment.setIdAttr("folder-browse");
|
||||||
|
|
@ -455,6 +455,7 @@ public class AssetPane extends LayoutPanel implements Resettable {
|
||||||
|
|
||||||
final Form newAssetForm = new Form("new-asset-form",
|
final Form newAssetForm = new Form("new-asset-form",
|
||||||
new BoxPanel(BoxPanel.HORIZONTAL));
|
new BoxPanel(BoxPanel.HORIZONTAL));
|
||||||
|
newAssetForm.setMethod("GET");
|
||||||
newAssetForm.add(new Label(new GlobalizedMessage(
|
newAssetForm.add(new Label(new GlobalizedMessage(
|
||||||
"cms.ui.assets.new", CmsConstants.CMS_BUNDLE)));
|
"cms.ui.assets.new", CmsConstants.CMS_BUNDLE)));
|
||||||
final SingleSelect newAssetTypeSelect = new SingleSelect(
|
final SingleSelect newAssetTypeSelect = new SingleSelect(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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 com.arsdigita.cms.ui.assets;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.form.Widget;
|
||||||
|
import com.arsdigita.bebop.parameters.LongParameter;
|
||||||
|
import com.arsdigita.cms.CMS;
|
||||||
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.librecms.assets.AssetTypeInfo;
|
||||||
|
import org.librecms.assets.AssetTypesManager;
|
||||||
|
import org.librecms.contentsection.Asset;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A widget for selecting an asset. The widget does not contain any other
|
||||||
|
* widgets, only the information required to create an HTML/JavaScript dialog
|
||||||
|
* for selecting an asset. To get the dialog the
|
||||||
|
* {@link org.librecms.contentsection.rs.Assets} class can be used which
|
||||||
|
* provides several methods for getting the assets of an content section.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class AssetSearchWidget extends Widget {
|
||||||
|
|
||||||
|
private Class<? extends Asset> type;
|
||||||
|
|
||||||
|
public AssetSearchWidget(final String name) {
|
||||||
|
super(new LongParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssetSearchWidget(final String name,
|
||||||
|
final Class<? extends Asset> type) {
|
||||||
|
this(name);
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCompound() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return "asset-search-widget";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getElementTag() {
|
||||||
|
return "cms:asset-search-widget";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateWidget(final PageState state,
|
||||||
|
final Element parent) {
|
||||||
|
|
||||||
|
final Element widget = parent.newChildElement(getElementTag(),
|
||||||
|
CMS.CMS_XML_NS);
|
||||||
|
|
||||||
|
widget.addAttribute("name", getName());
|
||||||
|
|
||||||
|
if (type != null) {
|
||||||
|
widget.addAttribute("asset-type", type.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
final ContentSection section = CMS.getContext().getContentSection();
|
||||||
|
widget.addAttribute("content-section", section.getLabel());
|
||||||
|
|
||||||
|
final Long value = (Long) getValue(state);
|
||||||
|
if (value != null) {
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final AssetRepository assetRepo = cdiUtil
|
||||||
|
.findBean(AssetRepository.class);
|
||||||
|
final AssetTypesManager typesManager = cdiUtil
|
||||||
|
.findBean(AssetTypesManager.class);
|
||||||
|
final GlobalizationHelper globalizationHelper = cdiUtil
|
||||||
|
.findBean(GlobalizationHelper.class);
|
||||||
|
|
||||||
|
final Asset asset = assetRepo
|
||||||
|
.findById(value)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||||
|
"No asset with ID %d in the database.", value)));
|
||||||
|
|
||||||
|
final Element selected = widget.newChildElement(
|
||||||
|
"cms:selected-asset", CMS.CMS_XML_NS);
|
||||||
|
selected.addAttribute("assetId",
|
||||||
|
Long.toString(asset.getObjectId()));
|
||||||
|
selected.addAttribute(
|
||||||
|
"title",
|
||||||
|
globalizationHelper
|
||||||
|
.getValueFromLocalizedString(asset.getTitle()));
|
||||||
|
final AssetTypeInfo typeInfo = typesManager
|
||||||
|
.getAssetTypeInfo(asset.getClass().getName());
|
||||||
|
final ResourceBundle bundle = ResourceBundle
|
||||||
|
.getBundle(typeInfo.getLabelBundle(),
|
||||||
|
globalizationHelper.getNegotiatedLocale());
|
||||||
|
final String typeLabel = bundle.getString(typeInfo.getLabelKey());
|
||||||
|
selected.addAttribute("type", typeLabel);
|
||||||
|
|
||||||
|
exportAttributes(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -19,12 +19,23 @@
|
||||||
package com.arsdigita.cms.ui.assets.forms;
|
package com.arsdigita.cms.ui.assets.forms;
|
||||||
|
|
||||||
import com.arsdigita.bebop.FormProcessException;
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
|
import com.arsdigita.bebop.Label;
|
||||||
import com.arsdigita.bebop.PageState;
|
import com.arsdigita.bebop.PageState;
|
||||||
import com.arsdigita.cms.ui.assets.AssetPane;
|
import com.arsdigita.cms.ui.assets.AssetPane;
|
||||||
|
import com.arsdigita.cms.ui.assets.AssetSearchWidget;
|
||||||
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
|
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.librecms.CmsConstants;
|
||||||
|
import org.librecms.assets.Bookmark;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.librecms.assets.ExternalVideoAsset;
|
import org.librecms.assets.ExternalVideoAsset;
|
||||||
|
import org.librecms.assets.LegalMetadata;
|
||||||
import org.librecms.contentsection.Asset;
|
import org.librecms.contentsection.Asset;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -32,6 +43,8 @@ import org.librecms.contentsection.Asset;
|
||||||
*/
|
*/
|
||||||
public class ExternalVideoAssetForm extends BookmarkForm {
|
public class ExternalVideoAssetForm extends BookmarkForm {
|
||||||
|
|
||||||
|
private AssetSearchWidget assetSearchWidget;
|
||||||
|
|
||||||
public ExternalVideoAssetForm(final AssetPane assetPane) {
|
public ExternalVideoAssetForm(final AssetPane assetPane) {
|
||||||
super(assetPane);
|
super(assetPane);
|
||||||
}
|
}
|
||||||
|
|
@ -40,24 +53,32 @@ public class ExternalVideoAssetForm extends BookmarkForm {
|
||||||
public void addWidgets() {
|
public void addWidgets() {
|
||||||
super.addWidgets();
|
super.addWidgets();
|
||||||
|
|
||||||
|
add(new Label(new GlobalizedMessage(
|
||||||
|
"cms.ui.assets.external_video_asset.legal_metadata.label",
|
||||||
|
CmsConstants.CMS_BUNDLE)));
|
||||||
|
assetSearchWidget = new AssetSearchWidget("legal-metadata",
|
||||||
|
LegalMetadata.class);
|
||||||
|
add(assetSearchWidget);
|
||||||
|
|
||||||
//ToDo
|
//ToDo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initForm(final PageState state,
|
protected void initForm(final PageState state,
|
||||||
final Optional<Asset> selectedAsset) {
|
final Optional<Asset> selectedAsset) {
|
||||||
super.initForm(state, selectedAsset);
|
super.initForm(state, selectedAsset);
|
||||||
|
|
||||||
// ToDo
|
if (selectedAsset.isPresent()) {
|
||||||
|
final ExternalVideoAsset externalVideoAsset
|
||||||
|
= (ExternalVideoAsset) selectedAsset
|
||||||
|
.get();
|
||||||
|
|
||||||
|
final LegalMetadata legalMetadata = externalVideoAsset
|
||||||
|
.getLegalMetadata();
|
||||||
|
if (legalMetadata != null) {
|
||||||
|
assetSearchWidget.setValue(state, legalMetadata.getObjectId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void showLocale(final PageState state) {
|
|
||||||
|
|
||||||
super.showLocale(state);
|
|
||||||
|
|
||||||
//ToDo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -68,13 +89,30 @@ public class ExternalVideoAssetForm extends BookmarkForm {
|
||||||
|
|
||||||
final ExternalVideoAsset externalVideoAsset = new ExternalVideoAsset();
|
final ExternalVideoAsset externalVideoAsset = new ExternalVideoAsset();
|
||||||
|
|
||||||
|
updateData((Bookmark) externalVideoAsset, state);
|
||||||
updateData(externalVideoAsset, state);
|
updateData(externalVideoAsset, state);
|
||||||
|
|
||||||
// ToDo
|
|
||||||
|
|
||||||
return externalVideoAsset;
|
return externalVideoAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateData(final ExternalVideoAsset externalVideoAsset,
|
||||||
|
final PageState state) {
|
||||||
|
|
||||||
|
final Long legalMetadataId = (Long) assetSearchWidget.getValue(state);
|
||||||
|
if (legalMetadataId != null) {
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final AssetRepository assetRepo = cdiUtil.findBean(
|
||||||
|
AssetRepository.class);
|
||||||
|
final LegalMetadata legalMetadata = (LegalMetadata) assetRepo
|
||||||
|
.findById(legalMetadataId)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||||
|
"No LegalMetadata asset with ID %d in the database.",
|
||||||
|
legalMetadataId)));
|
||||||
|
|
||||||
|
externalVideoAsset.setLegalMetadata(legalMetadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateAsset(final Asset asset, final PageState state) {
|
protected void updateAsset(final Asset asset, final PageState state) {
|
||||||
|
|
||||||
|
|
@ -91,8 +129,8 @@ public class ExternalVideoAssetForm extends BookmarkForm {
|
||||||
|
|
||||||
final ExternalVideoAsset externalVideoAsset = (ExternalVideoAsset) asset;
|
final ExternalVideoAsset externalVideoAsset = (ExternalVideoAsset) asset;
|
||||||
|
|
||||||
|
updateData((Bookmark) externalVideoAsset, state);
|
||||||
updateData(externalVideoAsset, state);
|
updateData(externalVideoAsset, state);
|
||||||
|
}
|
||||||
|
|
||||||
// ToDo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import org.libreccm.web.ApplicationType;
|
||||||
import org.libreccm.web.CcmApplication;
|
import org.libreccm.web.CcmApplication;
|
||||||
import org.librecms.assets.AssetTypes;
|
import org.librecms.assets.AssetTypes;
|
||||||
import org.librecms.assets.Bookmark;
|
import org.librecms.assets.Bookmark;
|
||||||
|
import org.librecms.assets.ExternalVideoAsset;
|
||||||
import org.librecms.assets.LegalMetadata;
|
import org.librecms.assets.LegalMetadata;
|
||||||
import org.librecms.contentsection.ContentSection;
|
import org.librecms.contentsection.ContentSection;
|
||||||
import org.librecms.contentsection.ContentSectionCreator;
|
import org.librecms.contentsection.ContentSectionCreator;
|
||||||
|
|
@ -35,6 +36,7 @@ import org.librecms.contenttypes.News;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.librecms.assets.SideNote;
|
import org.librecms.assets.SideNote;
|
||||||
|
|
||||||
@Module(//packageName = "org.librecms.cms",
|
@Module(//packageName = "org.librecms.cms",
|
||||||
|
|
@ -61,7 +63,10 @@ import org.librecms.assets.SideNote;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ContentTypes({Article.class, Event.class, MultiPartArticle.class, News.class})
|
@ContentTypes({Article.class, Event.class, MultiPartArticle.class, News.class})
|
||||||
@AssetTypes({Bookmark.class, LegalMetadata.class, SideNote.class})
|
@AssetTypes({Bookmark.class,
|
||||||
|
ExternalVideoAsset.class,
|
||||||
|
LegalMetadata.class,
|
||||||
|
SideNote.class})
|
||||||
public class Cms implements CcmModule {
|
public class Cms implements CcmModule {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(Cms.class);
|
private static final Logger LOGGER = LogManager.getLogger(Cms.class);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.assets;
|
package org.librecms.assets;
|
||||||
|
|
||||||
|
import com.arsdigita.cms.ui.assets.forms.ExternalVideoAssetForm;
|
||||||
|
|
||||||
import org.hibernate.envers.Audited;
|
import org.hibernate.envers.Audited;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
@ -29,6 +31,7 @@ import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import static org.librecms.CmsConstants.*;
|
import static org.librecms.CmsConstants.*;
|
||||||
|
import static org.librecms.assets.AssetConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An asset for external videos, like videos from YouTube.
|
* An asset for external videos, like videos from YouTube.
|
||||||
|
|
@ -38,6 +41,11 @@ import static org.librecms.CmsConstants.*;
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "EXTERNAL_VIDEO_ASSETS", schema = DB_SCHEMA)
|
@Table(name = "EXTERNAL_VIDEO_ASSETS", schema = DB_SCHEMA)
|
||||||
@Audited
|
@Audited
|
||||||
|
@AssetType(assetForm = ExternalVideoAssetForm.class,
|
||||||
|
labelKey = "external_video_asset.label",
|
||||||
|
labelBundle = ASSETS_BUNDLE,
|
||||||
|
descriptionKey = "external_video_asset.description",
|
||||||
|
descriptionBundle = ASSETS_BUNDLE)
|
||||||
public class ExternalVideoAsset extends Bookmark implements Serializable {
|
public class ExternalVideoAsset extends Bookmark implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -2927375812188779049L;
|
private static final long serialVersionUID = -2927375812188779049L;
|
||||||
|
|
|
||||||
|
|
@ -61,22 +61,52 @@ import static org.librecms.CmsConstants.*;
|
||||||
,
|
,
|
||||||
@NamedQuery(name = "Asset.findByType",
|
@NamedQuery(name = "Asset.findByType",
|
||||||
query = "SELECT a FROM Asset a "
|
query = "SELECT a FROM Asset a "
|
||||||
+ "WHERE TYPE(a) = :type")
|
+ "WHERE TYPE(a) = :type "
|
||||||
|
+ "AND a.categories IS NOT EMPTY")
|
||||||
|
,
|
||||||
|
@NamedQuery(name = "Asset.findByTypeAndContentSection",
|
||||||
|
query = "SELECT a FROM Asset a "
|
||||||
|
+ "JOIN a.categories c "
|
||||||
|
+ "WHERE TYPE(a) = :type "
|
||||||
|
+ "AND c.category.section = :section")
|
||||||
,
|
,
|
||||||
@NamedQuery(name = "Asset.findByUuidAndType",
|
@NamedQuery(name = "Asset.findByUuidAndType",
|
||||||
query = "SELECT a FROM Asset a "
|
query = "SELECT a FROM Asset a "
|
||||||
+ "WHERE a.uuid = :uuid "
|
+ "WHERE a.uuid = :uuid "
|
||||||
+ "AND TYPE(a) = :type")
|
+ "AND TYPE(a) = :type")
|
||||||
,
|
,
|
||||||
|
@NamedQuery(name = "Asset.findByContentSection",
|
||||||
|
query = "SELECT a FROM Asset a "
|
||||||
|
+ "JOIN a.categories c "
|
||||||
|
+ "WHERE c.category.section = :section")
|
||||||
|
,
|
||||||
@NamedQuery(name = "Asset.findByTitle'",
|
@NamedQuery(name = "Asset.findByTitle'",
|
||||||
query = "SELECT a FROM Asset a JOIN a.title.values t "
|
query = "SELECT a FROM Asset a "
|
||||||
+ "WHERE LOWER(t) LIKE CONCAT('%', :title, '%')")
|
+ "JOIN a.title.values t "
|
||||||
|
+ "WHERE LOWER(t) LIKE CONCAT('%', :title, '%') "
|
||||||
|
+ "AND a.categories IS NOT EMPTY")
|
||||||
|
,
|
||||||
|
@NamedQuery(name = "Asset.findByTitleAndContentSection",
|
||||||
|
query = "SELECT a FROM Asset a "
|
||||||
|
+ "JOIN a.title.values t "
|
||||||
|
+ "JOIN a.categories c "
|
||||||
|
+ "WHERE LOWER(t) LIKE CONCAT('%s', :title, '%s') "
|
||||||
|
+ "AND c.category.section = :section")
|
||||||
,
|
,
|
||||||
@NamedQuery(name = "Asset.findByTitleAndType",
|
@NamedQuery(name = "Asset.findByTitleAndType",
|
||||||
query = "SELECT a FROM Asset a JOIN a.title.values t "
|
query = "SELECT a FROM Asset a "
|
||||||
|
+ "JOIN a.title.values t "
|
||||||
+ "WHERE LOWER(t) LIKE CONCAT('%', :title, '%') "
|
+ "WHERE LOWER(t) LIKE CONCAT('%', :title, '%') "
|
||||||
+ "AND TYPE(a) = :type")
|
+ "AND TYPE(a) = :type")
|
||||||
,
|
,
|
||||||
|
@NamedQuery(name = "Asset.findByTitleAndTypeAndContentSection",
|
||||||
|
query = "SELECT a FROM Asset a "
|
||||||
|
+ "JOIN a.title.values t "
|
||||||
|
+ "JOIN a.categories c "
|
||||||
|
+ "WHERE LOWER(t) LIKE CONCAT('%', :title, '%') "
|
||||||
|
+ "AND TYPE(a) = :type "
|
||||||
|
+ "AND c.category.section = :section")
|
||||||
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "Asset.findByFolder",
|
name = "Asset.findByFolder",
|
||||||
query = "SELECT a FROM Asset a "
|
query = "SELECT a FROM Asset a "
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.contentsection;
|
package org.librecms.contentsection;
|
||||||
|
|
||||||
|
|
||||||
import org.libreccm.auditing.AbstractAuditedEntityRepository;
|
import org.libreccm.auditing.AbstractAuditedEntityRepository;
|
||||||
import org.libreccm.categorization.Category;
|
import org.libreccm.categorization.Category;
|
||||||
import org.libreccm.categorization.CategoryManager;
|
import org.libreccm.categorization.CategoryManager;
|
||||||
|
|
@ -140,8 +139,8 @@ public class AssetRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an {@link Asset} by its UUID. This method does distinguish between
|
* Find an {@link Asset} by its UUID. This method does not distinguish
|
||||||
* shared and non shared assets.
|
* between shared and non shared assets.
|
||||||
*
|
*
|
||||||
* @param uuid The UUID of the {@link Asset}.
|
* @param uuid The UUID of the {@link Asset}.
|
||||||
*
|
*
|
||||||
|
|
@ -164,7 +163,7 @@ 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 distinguish between shared and non shared assets.
|
* does not distinguish between shared and non shared assets.
|
||||||
*
|
*
|
||||||
* @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.
|
||||||
|
|
@ -191,22 +190,56 @@ public class AssetRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<Asset> findByTitle(final String title) {
|
public List<Asset> findByContentSection(final ContentSection section) {
|
||||||
|
|
||||||
final TypedQuery<Asset> query = entityManager.createNamedQuery(
|
final TypedQuery<Asset> query = entityManager
|
||||||
"Asset.findByTitle", Asset.class);
|
.createNamedQuery("Asset.findByContentSection", Asset.class);
|
||||||
query.setParameter("title", title);
|
query.setParameter("section", section);
|
||||||
|
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all shared {@link Asset}s of the specified type.
|
* Finds all sharable {@link Asset}s where the title is like the provided
|
||||||
|
* one. This method does a {@code LIKE} query. Therefore it will find all
|
||||||
|
* assets where the title contains the string provided using the
|
||||||
|
* {@code title} parameter.
|
||||||
|
*
|
||||||
|
* @param title The title to search for.
|
||||||
|
*
|
||||||
|
* @return A list of all sharable assets (from all content sections) where
|
||||||
|
* the title contains the string provided by the {@code title}
|
||||||
|
* parameter.
|
||||||
|
*/
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public List<Asset> findByTitle(final String title) {
|
||||||
|
|
||||||
|
final TypedQuery<Asset> query = entityManager
|
||||||
|
.createNamedQuery("Asset.findByTitle", Asset.class);
|
||||||
|
query.setParameter("title", title);
|
||||||
|
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Asset> findByTitleAndContentSection(
|
||||||
|
final String title, final ContentSection section) {
|
||||||
|
|
||||||
|
final TypedQuery<Asset> query = entityManager.createNamedQuery(
|
||||||
|
"Asset.findByTitleAndContentSection", Asset.class);
|
||||||
|
query.setParameter("title", title);
|
||||||
|
query.setParameter("section", section);
|
||||||
|
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all sharable {@link Asset}s of the specified type from all content
|
||||||
|
* sections..
|
||||||
*
|
*
|
||||||
* @param type The type of the assets to find.
|
* @param type The type of the assets to find.
|
||||||
*
|
*
|
||||||
* @return A list containing all shared assets of the specified
|
* @return A list containing all sharable assets of the specified
|
||||||
* {@code type}.
|
* {@code type} from all content sections.
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<Asset> findByType(final Class<? extends Asset> type) {
|
public List<Asset> findByType(final Class<? extends Asset> type) {
|
||||||
|
|
@ -218,18 +251,66 @@ public class AssetRepository
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all sharable {@link Asset}s of the specified type in the specified
|
||||||
|
* content section.
|
||||||
|
*
|
||||||
|
* @param type The type of the assets to find.
|
||||||
|
* @param section The section.
|
||||||
|
*
|
||||||
|
* @return A list containing all sharable assets of the specified
|
||||||
|
* {@code type} in the specified content section.
|
||||||
|
*/
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public List<Asset> findByTypeAndContentSection(
|
||||||
|
final Class<? extends Asset> type,
|
||||||
|
final ContentSection section) {
|
||||||
|
|
||||||
|
final TypedQuery<Asset> query = entityManager.createNamedQuery(
|
||||||
|
"Asset.findByTypeAndContentSection", Asset.class);
|
||||||
|
query.setParameter("type", type);
|
||||||
|
query.setParameter("section", section);
|
||||||
|
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all assets of the provided type which contain the provided string
|
||||||
|
* in their title.
|
||||||
|
*
|
||||||
|
* @param title The title fragment used to filter the assets.
|
||||||
|
* @param type The type of the assets.
|
||||||
|
*
|
||||||
|
* @return A list of all assets from all content sections which are the
|
||||||
|
* specified type and which title matches the provided title.
|
||||||
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<Asset> findByTitleAndType(final String title,
|
public List<Asset> findByTitleAndType(final String title,
|
||||||
final Class<? extends Asset> type) {
|
final Class<? extends Asset> type) {
|
||||||
|
|
||||||
final TypedQuery<Asset> query = entityManager.createNamedQuery(
|
final TypedQuery<Asset> query = entityManager
|
||||||
"Asset.findByTitle", Asset.class);
|
.createNamedQuery("Asset.findByTitle", Asset.class);
|
||||||
query.setParameter("title", title);
|
query.setParameter("title", title);
|
||||||
query.setParameter("type", type);
|
query.setParameter("type", type);
|
||||||
|
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Asset> findByTitleAndTypeAndContentSection(
|
||||||
|
final String title,
|
||||||
|
final Class<? extends Asset> type,
|
||||||
|
final ContentSection section) {
|
||||||
|
|
||||||
|
final TypedQuery<Asset> query = entityManager
|
||||||
|
.createNamedQuery("Asset.findByTitleAndTypeAndContentSection",
|
||||||
|
Asset.class);
|
||||||
|
query.setParameter("title", title);
|
||||||
|
query.setParameter("type", type);
|
||||||
|
query.setParameter("section", section);
|
||||||
|
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all shared {@link Asset}s in a specific {@link Folder}.
|
* Finds all shared {@link Asset}s in a specific {@link Folder}.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import javax.transaction.Transactional;
|
||||||
public class ContentSectionRepository
|
public class ContentSectionRepository
|
||||||
extends AbstractEntityRepository<Long, ContentSection> {
|
extends AbstractEntityRepository<Long, ContentSection> {
|
||||||
|
|
||||||
public ContentSection findByLabel(final String label) {
|
public Optional<ContentSection> findByLabel(final String label) {
|
||||||
if (label == null || label.isEmpty()) {
|
if (label == null || label.isEmpty()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"The label of a ContentSection can't be empty.");
|
"The label of a ContentSection can't be empty.");
|
||||||
|
|
@ -50,7 +50,11 @@ public class ContentSectionRepository
|
||||||
ContentSection.class);
|
ContentSection.class);
|
||||||
query.setParameter("label", label);
|
query.setParameter("label", label);
|
||||||
|
|
||||||
return query.getSingleResult();
|
try {
|
||||||
|
return Optional.of(query.getSingleResult());
|
||||||
|
} catch(NoResultException ex) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -104,12 +104,11 @@ public class FolderRepository extends AbstractEntityRepository<Long, Folder> {
|
||||||
+ "Valid path format: contentSection:path");
|
+ "Valid path format: contentSection:path");
|
||||||
}
|
}
|
||||||
|
|
||||||
final ContentSection section = sectionRepo.findByLabel(tokens[0]);
|
final ContentSection section = sectionRepo
|
||||||
if (section == null) {
|
.findByLabel(tokens[0])
|
||||||
throw new InvalidFolderPathException(String.format(
|
.orElseThrow(() -> new InvalidFolderPathException(String.format(
|
||||||
"No content section identified by label \"%s\" found.",
|
"No content section identified by label \"%s\" found.",
|
||||||
tokens[0]));
|
tokens[0])));
|
||||||
}
|
|
||||||
|
|
||||||
return findByPath(section, tokens[1], type);
|
return findByPath(section, tokens[1], type);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,278 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.contentsection.rs;
|
||||||
|
|
||||||
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.librecms.assets.AssetTypeInfo;
|
||||||
|
import org.librecms.assets.AssetTypesManager;
|
||||||
|
import org.librecms.contentsection.Asset;
|
||||||
|
import org.librecms.contentsection.AssetManager;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
import org.librecms.contentsection.ContentSectionRepository;
|
||||||
|
import org.librecms.contentsection.Folder;
|
||||||
|
import org.librecms.contentsection.FolderManager;
|
||||||
|
import org.librecms.contentsection.FolderRepository;
|
||||||
|
import org.librecms.contentsection.FolderType;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Path("/{content-section}/assets/")
|
||||||
|
public class Assets {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentSectionRepository sectionRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FolderRepository folderRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FolderManager folderManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetRepository assetRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetManager assetManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetTypesManager assetTypesManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
private Class<? extends Asset> toAssetTypeClass(final String type) {
|
||||||
|
final Class<?> clazz;
|
||||||
|
try {
|
||||||
|
clazz = Class.forName(type);
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Type '%s' is not a valid class.",
|
||||||
|
type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Asset.class.isAssignableFrom(clazz)) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Class<? extends Asset> typeClass
|
||||||
|
= (Class<? extends Asset>) clazz;
|
||||||
|
return typeClass;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Type '%s is not a subclass of '%s'.",
|
||||||
|
type,
|
||||||
|
Asset.class.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> createAssetMapEntry(final Folder folder) {
|
||||||
|
final Map<String, String> result = new HashMap<>();
|
||||||
|
|
||||||
|
result.put("title",
|
||||||
|
folder
|
||||||
|
.getTitle()
|
||||||
|
.getValue(KernelConfig.getConfig().getDefaultLocale()));
|
||||||
|
result.put("type",
|
||||||
|
Folder.class.getName());
|
||||||
|
result.put("place", "");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> createAssetMapEntry(final Asset asset) {
|
||||||
|
final Map<String, String> result = new HashMap<>();
|
||||||
|
|
||||||
|
result.put("assetId",
|
||||||
|
Long.toString(asset.getObjectId()));
|
||||||
|
|
||||||
|
result.put("title",
|
||||||
|
asset.getTitle().getValue(globalizationHelper
|
||||||
|
.getNegotiatedLocale()));
|
||||||
|
|
||||||
|
result.put("type",
|
||||||
|
asset.getClass().getName());
|
||||||
|
|
||||||
|
final AssetTypeInfo typeInfo = assetTypesManager
|
||||||
|
.getAssetTypeInfo(asset.getClass());
|
||||||
|
final ResourceBundle bundle = ResourceBundle
|
||||||
|
.getBundle(typeInfo.getLabelBundle(),
|
||||||
|
globalizationHelper.getNegotiatedLocale());
|
||||||
|
result.put("typeLabel", bundle.getString(typeInfo.getLabelKey()));
|
||||||
|
|
||||||
|
final Optional<Folder> assetFolder = assetManager.getAssetFolder(asset);
|
||||||
|
if (assetFolder.isPresent()) {
|
||||||
|
result.put("place",
|
||||||
|
folderManager.getFolderPath(assetFolder.get()));
|
||||||
|
} else {
|
||||||
|
result.put("place", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/")
|
||||||
|
@Produces("text/json; charset=utf-8")
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public List<Map<String, String>> findAssets(
|
||||||
|
@PathParam("content-section") final String section,
|
||||||
|
@QueryParam("query") final String query,
|
||||||
|
@QueryParam("type") final String type) {
|
||||||
|
|
||||||
|
final ContentSection contentSection = sectionRepo
|
||||||
|
.findByLabel(section)
|
||||||
|
.orElseThrow(() -> new NotFoundException(
|
||||||
|
String.format("No content section '%s' found.", section)));
|
||||||
|
|
||||||
|
final List<Asset> assets;
|
||||||
|
if ((query == null || query.trim().isEmpty())
|
||||||
|
&& (type == null || type.trim().isEmpty())) {
|
||||||
|
assets = assetRepo.findByContentSection(contentSection);
|
||||||
|
} else if ((query != null && !query.trim().isEmpty())
|
||||||
|
&& (type == null || type.trim().isEmpty())) {
|
||||||
|
assets = assetRepo.findByTitleAndContentSection(query,
|
||||||
|
contentSection);
|
||||||
|
} else if ((query == null || query.trim().isEmpty())
|
||||||
|
&& (type != null && !type.trim().isEmpty())) {
|
||||||
|
final Class<? extends Asset> assetType = toAssetTypeClass(type);
|
||||||
|
assets = assetRepo.findByTypeAndContentSection(assetType,
|
||||||
|
contentSection);
|
||||||
|
} else {
|
||||||
|
final Class<? extends Asset> assetType = toAssetTypeClass(type);
|
||||||
|
assets = assetRepo.findByTitleAndTypeAndContentSection(
|
||||||
|
type,
|
||||||
|
assetType,
|
||||||
|
contentSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
return assets
|
||||||
|
.stream()
|
||||||
|
.map(asset -> createAssetMapEntry(asset))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/folders/")
|
||||||
|
@Produces("text/json; charset=utf-8")
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public List<Map<String, String>> findAssetsInRootFolder(
|
||||||
|
@PathParam("content-section") final String section,
|
||||||
|
@QueryParam("query") final String query,
|
||||||
|
@QueryParam("type") final String type) {
|
||||||
|
|
||||||
|
final ContentSection contentSection = sectionRepo
|
||||||
|
.findByLabel(section)
|
||||||
|
.orElseThrow(() -> new NotFoundException(
|
||||||
|
String.format("No content section '%s' found.", section)));
|
||||||
|
|
||||||
|
final Folder folder = contentSection.getRootAssetsFolder();
|
||||||
|
|
||||||
|
return findAssetsInFolder(folder, query, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/folders/{folder}/")
|
||||||
|
@Produces("text/json; charset=utf-8")
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public List<Map<String, String>> findAssetsInFolder(
|
||||||
|
@PathParam("content-section") final String section,
|
||||||
|
@PathParam("folder") final String folderPath,
|
||||||
|
@QueryParam("query") final String query,
|
||||||
|
@QueryParam("type") final String type) {
|
||||||
|
|
||||||
|
final ContentSection contentSection = sectionRepo
|
||||||
|
.findByLabel(section)
|
||||||
|
.orElseThrow(() -> new NotFoundException(
|
||||||
|
String.format("No content section '%s' found.", section)));
|
||||||
|
|
||||||
|
final Folder folder = folderRepo.findByPath(contentSection,
|
||||||
|
folderPath,
|
||||||
|
FolderType.ASSETS_FOLDER)
|
||||||
|
.orElseThrow(() -> new NotFoundException(String.format(
|
||||||
|
"No assets folder with path '%s' in content section '%s'",
|
||||||
|
folderPath,
|
||||||
|
section)));
|
||||||
|
|
||||||
|
return findAssetsInFolder(folder, query, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Map<String, String>> findAssetsInFolder(final Folder folder,
|
||||||
|
final String query,
|
||||||
|
final String type) {
|
||||||
|
|
||||||
|
final List<Map<String, String>> subFolderEntries = folder
|
||||||
|
.getSubFolders()
|
||||||
|
.stream()
|
||||||
|
.map(subFolder -> createAssetMapEntry(subFolder))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final List<Asset> assets;
|
||||||
|
if ((query == null || query.trim().isEmpty())
|
||||||
|
&& ((type == null) || type.trim().isEmpty())) {
|
||||||
|
assets = assetRepo.findByFolder(folder);
|
||||||
|
} else if ((query != null && !query.trim().isEmpty())
|
||||||
|
&& (type == null || type.trim().isEmpty())) {
|
||||||
|
|
||||||
|
assets = assetRepo.filterByFolderAndTitle(folder, query);
|
||||||
|
} else if ((query == null || query.trim().isEmpty())
|
||||||
|
&& (type != null && !type.trim().isEmpty())) {
|
||||||
|
final Class<? extends Asset> assetType = toAssetTypeClass(type);
|
||||||
|
assets = assetRepo.filterByFolderAndType(folder, assetType);
|
||||||
|
} else {
|
||||||
|
final Class<? extends Asset> assetType = toAssetTypeClass(type);
|
||||||
|
assets = assetRepo.filterByFolderAndTypeAndTitle(folder,
|
||||||
|
assetType,
|
||||||
|
query);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Map<String, String>> assetEntries = assets
|
||||||
|
.stream()
|
||||||
|
.map(asset -> createAssetMapEntry(asset))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
result.addAll(subFolderEntries);
|
||||||
|
result.addAll(assetEntries);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms.assets;
|
package org.librecms.contentsection.rs;
|
||||||
|
|
||||||
import com.arsdigita.kernel.KernelConfig;
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
|
|
@ -48,13 +48,18 @@ import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
|
|
||||||
|
import org.librecms.assets.AssetTypeInfo;
|
||||||
|
import org.librecms.assets.AssetTypesManager;
|
||||||
|
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/{content-section}/assets")
|
@Path("/{content-section}/assets")
|
||||||
public class AssetSearchService {
|
public class AssetsOld {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AssetRepository assetRepo;
|
private AssetRepository assetRepo;
|
||||||
|
|
@ -94,52 +99,19 @@ public class AssetSearchService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Asset> findAssetsByQuery(final String query) {
|
|
||||||
return assetRepo.findByTitle(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Asset> findAssetsByType(final String type) {
|
|
||||||
return AssetSearchService.this.findAssets(toAssetClass(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Asset> findAssets(final Class<? extends Asset> type) {
|
|
||||||
return assetRepo.findByType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Asset> findAssets(final String query, final String type) {
|
|
||||||
|
|
||||||
final Class<?> clazz;
|
|
||||||
try {
|
|
||||||
clazz = Class.forName(type);
|
|
||||||
} catch (ClassNotFoundException ex) {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"Type '%s' is not a valid class.",
|
|
||||||
type));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clazz.isAssignableFrom(Asset.class)) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final Class<? extends Asset> typeClass
|
|
||||||
= (Class<? extends Asset>) clazz;
|
|
||||||
return AssetSearchService.this.findAssets(query, typeClass);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"Type '%s is not a subclass of '%s'.",
|
|
||||||
type,
|
|
||||||
Asset.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Asset> findAssets(final ContentSection section,
|
public List<Asset> findAssets(final ContentSection section,
|
||||||
final String path) {
|
final String path) {
|
||||||
|
|
||||||
final Optional<Folder> folder = folderRepo
|
final Optional<Folder> folder = folderRepo
|
||||||
.findByPath(section,
|
.findByPath(section,
|
||||||
path,
|
path,
|
||||||
FolderType.ASSETS_FOLDER);
|
FolderType.ASSETS_FOLDER);
|
||||||
|
|
||||||
if (!folder.isPresent()) {
|
if (!folder.isPresent()) {
|
||||||
return Collections.emptyList();
|
throw new NotFoundException(String.format(
|
||||||
|
"No asset folder with path '%s' found in content section '%s'.",
|
||||||
|
path,
|
||||||
|
section.getLabel()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return assetRepo.findByFolder(folder.get());
|
return assetRepo.findByFolder(folder.get());
|
||||||
|
|
@ -229,7 +201,10 @@ public class AssetSearchService {
|
||||||
@QueryParam("query") final String query,
|
@QueryParam("query") final String query,
|
||||||
@QueryParam("type") final String type) {
|
@QueryParam("type") final String type) {
|
||||||
|
|
||||||
final ContentSection contentSection = sectionRepo.findByLabel(section);
|
final ContentSection contentSection = sectionRepo
|
||||||
|
.findByLabel(section)
|
||||||
|
.orElseThrow(() -> new NotFoundException(
|
||||||
|
String.format("No content section '%s' found.", section)));
|
||||||
|
|
||||||
final String folderPath;
|
final String folderPath;
|
||||||
if (path == null || path.trim().isEmpty() || "/".equals(path.trim())) {
|
if (path == null || path.trim().isEmpty() || "/".equals(path.trim())) {
|
||||||
|
|
@ -16,9 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms.contentsection;
|
package org.librecms.contentsection.rs;
|
||||||
|
|
||||||
import org.librecms.assets.AssetSearchService;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -31,13 +30,13 @@ import javax.ws.rs.core.Application;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@ApplicationPath("/content-sections")
|
@ApplicationPath("/content-sections")
|
||||||
public class JaxRsContentSections extends Application{
|
public class ContentSections extends Application{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Class<?>> getClasses() {
|
public Set<Class<?>> getClasses() {
|
||||||
final Set<Class<?>> classes = new HashSet<>();
|
final Set<Class<?>> classes = new HashSet<>();
|
||||||
|
|
||||||
classes.add(AssetSearchService.class);
|
classes.add(Assets.class);
|
||||||
|
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +249,7 @@ cms.ui.folder.no_assets=No assets
|
||||||
cms.ui.assets.new=Create new asset
|
cms.ui.assets.new=Create new asset
|
||||||
cms.ui.assets.new.create=Create asset
|
cms.ui.assets.new.create=Create asset
|
||||||
cms.ui.asset.title=Title
|
cms.ui.asset.title=Title
|
||||||
cms.ui.admin.assets.create=Create new asset of type '{0}'
|
cms.ui.admin.assets.create=Create new asset of type ''{0}''
|
||||||
cms.ui.assets.bookmark.description=Description
|
cms.ui.assets.bookmark.description=Description
|
||||||
cms.ui.assets.bookmark.url=URL
|
cms.ui.assets.bookmark.url=URL
|
||||||
cms.ui.assets.bookmark.url.malformed=The provided URL is malformed.
|
cms.ui.assets.bookmark.url.malformed=The provided URL is malformed.
|
||||||
|
|
@ -265,3 +265,4 @@ cms.ui.assets.sidenote.text=Text
|
||||||
cms.ui.assets.search_page.title=Select an asset
|
cms.ui.assets.search_page.title=Select an asset
|
||||||
cms.ui.assets.search_page.query=Search for
|
cms.ui.assets.search_page.query=Search for
|
||||||
cms.ui.assets.search_page.query.submit=Find
|
cms.ui.assets.search_page.query.submit=Find
|
||||||
|
cms.ui.assets.external_video_asset.legal_metadata.label=Legal metadata
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ cms.ui.folder.no_assets=Keine Medien oder Datens\u00e4tze vorhanden
|
||||||
cms.ui.assets.new=Neues Asset anlegen
|
cms.ui.assets.new=Neues Asset anlegen
|
||||||
cms.ui.assets.new.create=Asset anlegen
|
cms.ui.assets.new.create=Asset anlegen
|
||||||
cms.ui.asset.title=Titel
|
cms.ui.asset.title=Titel
|
||||||
cms.ui.admin.assets.create=Neues Asset vom Typ '{0}' anlegen
|
cms.ui.admin.assets.create=Neues Asset vom Typ ''{0}'' anlegen
|
||||||
cms.ui.assets.bookmark.description=Beschreibung
|
cms.ui.assets.bookmark.description=Beschreibung
|
||||||
cms.ui.assets.bookmark.url=URL
|
cms.ui.assets.bookmark.url=URL
|
||||||
cms.ui.assets.bookmark.url.malformed=Die angegebene URL ist nicht wohlgeformt.
|
cms.ui.assets.bookmark.url.malformed=Die angegebene URL ist nicht wohlgeformt.
|
||||||
|
|
@ -264,3 +264,4 @@ cms.ui.assets.sidenote.text=Text
|
||||||
cms.ui.assets.search_page.title=W\u00e4hlen Sie ein Asset
|
cms.ui.assets.search_page.title=W\u00e4hlen Sie ein Asset
|
||||||
cms.ui.assets.search_page.query=Suche nach
|
cms.ui.assets.search_page.query=Suche nach
|
||||||
cms.ui.assets.search_page.query.submit=Finden
|
cms.ui.assets.search_page.query.submit=Finden
|
||||||
|
cms.ui.assets.external_video_asset.legal_metadata.label=Rechtliche Informationen
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ cms.ui.folder.no_assets=No assets
|
||||||
cms.ui.assets.new=Create new asset
|
cms.ui.assets.new=Create new asset
|
||||||
cms.ui.assets.new.create=Create asset
|
cms.ui.assets.new.create=Create asset
|
||||||
cms.ui.asset.title=Title
|
cms.ui.asset.title=Title
|
||||||
cms.ui.admin.assets.create=Create new asset of type '{0}'
|
cms.ui.admin.assets.create=Create new asset of type ''{0}''
|
||||||
cms.ui.assets.bookmark.description=Description
|
cms.ui.assets.bookmark.description=Description
|
||||||
cms.ui.assets.bookmark.url=URL
|
cms.ui.assets.bookmark.url=URL
|
||||||
cms.ui.assets.bookmark.url.malformed=The provided URL is malformed.
|
cms.ui.assets.bookmark.url.malformed=The provided URL is malformed.
|
||||||
|
|
@ -223,3 +223,4 @@ cms.ui.assets.sidenote.text=Text
|
||||||
cms.ui.assets.search_page.title=Select an asset
|
cms.ui.assets.search_page.title=Select an asset
|
||||||
cms.ui.assets.search_page.query=Search for
|
cms.ui.assets.search_page.query=Search for
|
||||||
cms.ui.assets.search_page.query.submit=Find
|
cms.ui.assets.search_page.query.submit=Find
|
||||||
|
cms.ui.assets.external_video_asset.legal_metadata.label=Legal metadata
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,5 @@ legal_metadata.label=Legal metadata
|
||||||
legal_metadata.description=Stores legal metadata like the informations about the creator of an image etc.
|
legal_metadata.description=Stores legal metadata like the informations about the creator of an image etc.
|
||||||
sidenote.label=Side note
|
sidenote.label=Side note
|
||||||
sidenote.description=Additional information. Usually appears in the right or left column of an webpage.
|
sidenote.description=Additional information. Usually appears in the right or left column of an webpage.
|
||||||
|
external_video_asset.label=External Video
|
||||||
|
external_video_asset.description=An external video e.g. on YouTube. The presentation will either be a link or an embedded video.
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,5 @@ legal_metadata.label=Rechtliche Informationen
|
||||||
legal_metadata.description=Rechtliche Informationen, z.B. die Urheberschaft von Bildern etc.
|
legal_metadata.description=Rechtliche Informationen, z.B. die Urheberschaft von Bildern etc.
|
||||||
sidenote.label=Randbemerkung
|
sidenote.label=Randbemerkung
|
||||||
sidenote.description=Randbemerkung mit zus\u00e4tzlichen Informationen. Erscheint in der Regel in der rechten oder linken Spalte einer Webseite.
|
sidenote.description=Randbemerkung mit zus\u00e4tzlichen Informationen. Erscheint in der Regel in der rechten oder linken Spalte einer Webseite.
|
||||||
|
external_video_asset.label=Externes Video
|
||||||
|
external_video_asset.description=Externes Video z.B. auf YouTube. Wird entweder als Link oder eingebettet angezeigt.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
exclude-result-prefixes="xsl"
|
exclude-result-prefixes="xsl"
|
||||||
version="2.0">
|
version="2.0">
|
||||||
|
|
||||||
|
<xsl:import href="cms/asset-search-widget.xsl" />
|
||||||
<xsl:import href="cms/image.xsl" />
|
<xsl:import href="cms/image.xsl" />
|
||||||
<xsl:import href="cms/item-summary.xsl" />
|
<xsl:import href="cms/item-summary.xsl" />
|
||||||
<xsl:import href="cms/notes.xsl" />
|
<xsl:import href="cms/notes.xsl" />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,489 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
Processes the asset search widget.
|
||||||
|
|
||||||
|
Author: Jens Pelzetter, jens.pelzetter@googlemail.com
|
||||||
|
-->
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
|
||||||
|
xmlns:cms="http://www.arsdigita.com/cms/1.0"
|
||||||
|
xmlns:foundry="http://foundry.libreccm.org"
|
||||||
|
xmlns:nav="http://ccm.redhat.com/navigation"
|
||||||
|
exclude-result-prefixes="xsl bebop cms foundry nav"
|
||||||
|
version="2.0">
|
||||||
|
|
||||||
|
<xsl:template match="cms:asset-search-widget">
|
||||||
|
|
||||||
|
<div class="asset-search-widget">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="./cms:selected-asset">
|
||||||
|
<!--<h3>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/selected-asset')" />
|
||||||
|
</h3>
|
||||||
|
<dl>
|
||||||
|
<dt>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/selected-asset-title')" />
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<xsl:value-of select="./selected-asset/@title" />
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/selected-asset-type')" />
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<xsl:value-of select="./selected-asset/@type" />
|
||||||
|
</dd>
|
||||||
|
</dl>-->
|
||||||
|
<p>
|
||||||
|
<xsl:value-of select="./cms:selected-asset/@title" />
|
||||||
|
</p>
|
||||||
|
<input type="hidden"
|
||||||
|
id="{./@name}"
|
||||||
|
value="{./selected-asset/@assetId}" />
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<p id="{concat(./@name, '-selected')}">
|
||||||
|
<strong>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/no-asset-selected')" />
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
<input type="hidden"
|
||||||
|
id="{./@name}"
|
||||||
|
name="{./@name}" />
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<button id="{concat(./@name, 'select-asset-button')}"
|
||||||
|
type="button"
|
||||||
|
class="select-asset-button"
|
||||||
|
|
||||||
|
data-assettype="{./@asset-type}"
|
||||||
|
data-contentsection="{./@content-section}"
|
||||||
|
data-dialogId="{concat(./@name, '-dialog')}"
|
||||||
|
|
||||||
|
data-target="{./@name}">
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/select-asset-button')" />
|
||||||
|
</button>
|
||||||
|
<dialog id="{concat(./@name, '-dialog')}"
|
||||||
|
class="asset-search-widget-dialog"
|
||||||
|
data-assettype="{./@asset-type}"
|
||||||
|
data-contentsection="{./@content-section}"
|
||||||
|
data-dispatcherPrefix="{$dispatcher-prefix}"
|
||||||
|
data-targetId="{./@name}">
|
||||||
|
<h3 class="titlebar">
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/titlebar')" />
|
||||||
|
<button type="button"
|
||||||
|
class="close-button"
|
||||||
|
data-dialogId="{concat(./@name, '-dialog')}">
|
||||||
|
<span>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/titlebar/close')" />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</h3>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="hidden" id="{concat(./@name, '-last-focus')}" />
|
||||||
|
<label for="{concat(./@name, 'asset-filter')}">
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/filter-list')" />
|
||||||
|
</label>
|
||||||
|
<input type="text" id="{concat(./@name, '-dialog-asset-filter')}" />
|
||||||
|
<button type="button"
|
||||||
|
class="apply-filter"
|
||||||
|
data-dialogId="{concat(./@name, '-dialog')}">
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/filter-list/apply')" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="selectable-assets">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/table/header/title')" />
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/table/header/type')" />
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<xsl:value-of select="foundry:get-internal-static-text('cms', 'asset-search-widget/table/header/place')" />
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$title
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$type
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$place
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
</div>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/*function selectAsset(button) {
|
||||||
|
|
||||||
|
var assetType = button.getAttribute('data-assettype');
|
||||||
|
var contentSection = button.getAttribute('data-contentsection');
|
||||||
|
var target = button.getAttribute('data-target');
|
||||||
|
|
||||||
|
alert("AssetSelection assetType = " + assetType
|
||||||
|
+ "; contentSection = " + contentSection
|
||||||
|
+ "; target = " + target + "; ");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
function getAssetsForSelectAssetDialog(dialogId) {
|
||||||
|
|
||||||
|
var dialog = document.querySelector('#' + dialogId);
|
||||||
|
var type = dialog.getAttribute('data-assettype');
|
||||||
|
var contentSection = dialog.getAttribute('data-contentsection');
|
||||||
|
var targetId = dialog.getAttribute('data-targetId');
|
||||||
|
var filter = document.querySelector('#' + dialogId + '-asset-filter');
|
||||||
|
var query = filter.value;
|
||||||
|
var dispatcherPrefix = dialog.getAttribute('data-dispatcherPrefix');
|
||||||
|
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
var url = dispatcherPrefix.substring(0, dispatcherPrefix.length - "/ccm".length) + "/content-sections/" + contentSection + "/assets/";
|
||||||
|
if (type !== null && type.length > 0) {
|
||||||
|
url = url + "?type=" + type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((type !== null && type.length > 0)
|
||||||
|
&& (query !== null && query.length > 0)) {
|
||||||
|
url = url + "&query=" + query;
|
||||||
|
} else if (query !== null && query.length > 0) {
|
||||||
|
url = url + "?query=" + query;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.open("GET", url);
|
||||||
|
// request.setRequestHeader();
|
||||||
|
request.addEventListener('load', function (event) {
|
||||||
|
if (request.status >= 200 && request.status < 300) {
|
||||||
|
var assets = JSON.parse(request.responseText);
|
||||||
|
var tableRows = "";
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < assets.length; ++i) {
|
||||||
|
var asset = assets[i];
|
||||||
|
tableRows = tableRows
|
||||||
|
+ "<tr>"
|
||||||
|
+ "<td>"
|
||||||
|
+ "<a href=\"#\" onclick=\"setSelectedAsset(" + asset['assetId'] + ", \'" + asset['title'] + "\', \'" + targetId + "\', \'" + dialogId + "\')\">"
|
||||||
|
+ asset['title'] + "</td>"
|
||||||
|
+ "</a>"
|
||||||
|
+ "<td>"
|
||||||
|
+ asset['typeLabel']
|
||||||
|
+ "</td>"
|
||||||
|
+ "<td>" + asset['place'] + "</td>"
|
||||||
|
+ "</tr>";
|
||||||
|
}
|
||||||
|
document
|
||||||
|
.querySelector("#" + dialogId + " tbody")
|
||||||
|
.innerHTML = tableRows;
|
||||||
|
} else {
|
||||||
|
alert("Error while retrieving assets. "
|
||||||
|
+ "Response code: " + request.status + " "
|
||||||
|
+ "Message: " + request.statusText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSelectedAsset(assetId, assetTitle, targetId, dialogId) {
|
||||||
|
var target = document.querySelector("#" + targetId);
|
||||||
|
var targetText = document.querySelector("#" + targetId + "-selected");
|
||||||
|
|
||||||
|
target.value = assetId;
|
||||||
|
targetText.textContent = assetTitle;
|
||||||
|
|
||||||
|
toggleSelectAssetDialog('hide', dialogId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSelectAssetDialog(mode, dialogId) {
|
||||||
|
|
||||||
|
var dialog = document.querySelector("#" + dialogId);
|
||||||
|
|
||||||
|
if ('show' === mode) {
|
||||||
|
dialog.setAttribute('open', 'open');
|
||||||
|
getAssetsForSelectAssetDialog(dialogId)
|
||||||
|
} else {
|
||||||
|
dialog.setAttribute('open', 'false');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
|
var buttons = document.querySelectorAll('.select-asset-button');
|
||||||
|
for (i = 0; i < buttons.length; ++i) {
|
||||||
|
|
||||||
|
buttons[i].addEventListener('click', function (event) {
|
||||||
|
|
||||||
|
var button = event.currentTarget;
|
||||||
|
var dialogId = button.getAttribute('data-dialogId');
|
||||||
|
|
||||||
|
toggleSelectAssetDialog('show', dialogId);
|
||||||
|
|
||||||
|
|
||||||
|
// var assetType = button.getAttribute('data-assettype');
|
||||||
|
// var contentSection = button.getAttribute('data-contentsection');
|
||||||
|
// var target = button.getAttribute('data-target');
|
||||||
|
//
|
||||||
|
// alert("AssetSelection assetType = " + assetType
|
||||||
|
// + "; contentSection = " + contentSection
|
||||||
|
// + "; target = " + target + "; ");
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var closeButtons = document.querySelectorAll('.asset-search-widget-dialog .close-button');
|
||||||
|
for (i = 0; i < closeButtons.length; ++i) {
|
||||||
|
|
||||||
|
closeButtons[i].addEventListener('click', function (event) {
|
||||||
|
|
||||||
|
var button = event.currentTarget;
|
||||||
|
var dialogId = button.getAttribute('data-dialogId');
|
||||||
|
|
||||||
|
toggleSelectAssetDialog('hide', dialogId);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var applyButtons = document.querySelectorAll('.asset-search-widget-dialog .apply-filter');
|
||||||
|
for (i = 0; i < applyButtons.length; ++i) {
|
||||||
|
|
||||||
|
applyButtons[i].addEventListener('click', function (event) {
|
||||||
|
|
||||||
|
var button = event.currentTarget;
|
||||||
|
var dialogId = button.getAttribute('data-dialogId');
|
||||||
|
|
||||||
|
getAssetsForSelectAssetDialog(dialogId);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -1425,13 +1425,120 @@ dl dd a:hover {
|
||||||
.tile div + div {
|
.tile div + div {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
s
|
|
||||||
img.cmsImageDisplay {
|
img.cmsImageDisplay {
|
||||||
float: left;
|
float: left;
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog {
|
||||||
|
background-color: #e6e4f2;
|
||||||
|
|
||||||
|
border: 1px solid #555;
|
||||||
|
border-radius: 0.75em;
|
||||||
|
|
||||||
|
box-shadow: 5px 5px #aaa;
|
||||||
|
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 5%;
|
||||||
|
left: 2%;
|
||||||
|
|
||||||
|
width: 96%;
|
||||||
|
height: 90%;
|
||||||
|
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog[open="open"] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .controls {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .controls label {
|
||||||
|
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .dialogarea controls button {
|
||||||
|
|
||||||
|
margin-left: 0.5em;
|
||||||
|
|
||||||
|
}
|
||||||
|
div .asset-search-widget dialog .selectable-assets {
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 80%;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .dialogarea table {
|
||||||
|
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .selectable-assets table thead tr th {
|
||||||
|
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
color: #000;
|
||||||
|
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .titlebar {
|
||||||
|
|
||||||
|
border-bottom: 1px solid #555;
|
||||||
|
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .titlebar .close-button {
|
||||||
|
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
font-size: 18px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .titlebar .close-button:after {
|
||||||
|
content: '\2715';
|
||||||
|
}
|
||||||
|
|
||||||
|
div.asset-search-widget dialog .titlebar .close-button span {
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: -999px;
|
||||||
|
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
div.cmsImageInfoOverlay {
|
div.cmsImageInfoOverlay {
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: 2em;
|
margin-left: 2em;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<load-css-files/>
|
<load-css-files/>
|
||||||
<load-jquery/>
|
<load-jquery/>
|
||||||
<script src="scripts/category-step.js" origin="internal" />
|
<script src="scripts/category-step.js" origin="internal" />
|
||||||
|
<script src="scripts/cms-admin.js" origin="internal" />
|
||||||
<script src="scripts/dcp.js" origin="internal" />
|
<script src="scripts/dcp.js" origin="internal" />
|
||||||
<script src="scripts/manipulate-input.js" origin="internal" />
|
<script src="scripts/manipulate-input.js" origin="internal" />
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,59 @@
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<foundry:static-texts xmlns:foundry="http://foundry.libreccm.org">
|
<foundry:static-texts xmlns:foundry="http://foundry.libreccm.org">
|
||||||
|
|
||||||
<text id="greeting">
|
<text id="asset-search-widget/filter-list">
|
||||||
<translation lang="de">Willkommen</translation>
|
<translation lang="de">Filtern nach</translation>
|
||||||
<translation lang="en">Welcome</translation>
|
<translation lang="en">Filter using</translation>
|
||||||
</text>
|
</text>
|
||||||
|
<text id="asset-search-widget/filter-list/apply">
|
||||||
|
<translation lang="de">Anwenden</translation>
|
||||||
|
<translation lang="en">Apply</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/no-asset-selected">
|
||||||
|
<translation lang="de">Kein Asset ausgewählt</translation>
|
||||||
|
<translation lang="en">No asset selected</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/selected-asset">
|
||||||
|
<translation lang="de">Ausgewähltes Asset</translation>
|
||||||
|
<translation lang="en">Selected asset</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/selected-asset-title">
|
||||||
|
<translation lang="de">Titel</translation>
|
||||||
|
<translation lang="en">Title</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/selected-asset-type">
|
||||||
|
<translation lang="de">Type</translation>
|
||||||
|
<translation lang="en">Typ</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/select-asset-button">
|
||||||
|
<translation lang="de">Asset auswählen</translation>
|
||||||
|
<translation lang="en">Select asset</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/selected-asset">
|
||||||
|
<translation lang="de">Ausgewähltes Asset</translation>
|
||||||
|
<translation lang="en">Selected asset</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/table/header/place">
|
||||||
|
<translation lang="de">Abgelegt in</translation>
|
||||||
|
<translation lang="en">From</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/table/header/title">
|
||||||
|
<translation lang="de">Titel</translation>
|
||||||
|
<translation lang="en">Title</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/table/header/type">
|
||||||
|
<translation lang="de">Typ</translation>
|
||||||
|
<translation lang="en">Type</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/titlebar">
|
||||||
|
<translation lang="de">Wählen Sie das zu verwendende Asset aus</translation>
|
||||||
|
<translation lang="en">Select the asset to use</translation>
|
||||||
|
</text>
|
||||||
|
<text id="asset-search-widget/titlebar/close">
|
||||||
|
<translation lang="de">Ohne Auswahl schließen</translation>
|
||||||
|
<translation lang="en">Close without selecting an asset</translation>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
|
||||||
<text id="category-step/header">
|
<text id="category-step/header">
|
||||||
<translation lang="de">Zugewiesene Kategorien bearbeiten</translation>
|
<translation lang="de">Zugewiesene Kategorien bearbeiten</translation>
|
||||||
|
|
@ -24,6 +73,11 @@
|
||||||
<translation lang="en">Remove assignment</translation>
|
<translation lang="en">Remove assignment</translation>
|
||||||
</text>
|
</text>
|
||||||
|
|
||||||
|
<text id="greeting">
|
||||||
|
<translation lang="de">Willkommen</translation>
|
||||||
|
<translation lang="en">Welcome</translation>
|
||||||
|
</text>
|
||||||
|
|
||||||
<text id="summary/itemSummary/header">
|
<text id="summary/itemSummary/header">
|
||||||
<translation lang="en">Item Summary</translation>
|
<translation lang="en">Item Summary</translation>
|
||||||
<translation lang="de">Zusammenfassung</translation>
|
<translation lang="de">Zusammenfassung</translation>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue