#2206 improve plugin page
This commit is contained in:
parent
96a5b16954
commit
6bebe4f91d
13 changed files with 255 additions and 46 deletions
|
@ -15,22 +15,25 @@
|
|||
*/
|
||||
package org.codelibs.fess.app.web.admin.plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.codelibs.fess.app.web.base.FessAdminAction;
|
||||
import org.codelibs.fess.helper.PluginHelper;
|
||||
import org.codelibs.fess.helper.PluginHelper.Artifact;
|
||||
import org.codelibs.fess.app.web.base.FessAdminAction;
|
||||
import org.codelibs.fess.util.RenderDataUtil;
|
||||
import org.codelibs.fess.helper.PluginHelper.ArtifactType;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.HtmlResponse;
|
||||
import org.lastaflute.web.ruts.process.ActionRuntime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AdminPluginAction extends FessAdminAction {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AdminPluginAction.class);
|
||||
|
@ -41,8 +44,9 @@ public class AdminPluginAction extends FessAdminAction {
|
|||
@Override
|
||||
protected void setupHtmlData(final ActionRuntime runtime) {
|
||||
super.setupHtmlData(runtime);
|
||||
// runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNamePlugin()));
|
||||
|
||||
runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNamePlugin()));
|
||||
// runtime.registerData("availableArtifactItems", getAllAvailableArtifacts());
|
||||
runtime.registerData("installedArtifactItems", getAllInstalledArtifacts());
|
||||
}
|
||||
|
||||
@Execute
|
||||
|
@ -52,12 +56,20 @@ public class AdminPluginAction extends FessAdminAction {
|
|||
}
|
||||
|
||||
@Execute
|
||||
public HtmlResponse delete(final PluginBean pluginBean) {
|
||||
// TODO
|
||||
public HtmlResponse delete(final DeleteForm form) {
|
||||
validate(form, messages -> {}, () -> {
|
||||
return asHtml(path_AdminPlugin_AdminPluginJsp);
|
||||
});
|
||||
verifyToken(() -> {
|
||||
return asHtml(path_AdminPlugin_AdminPluginJsp);
|
||||
});
|
||||
Artifact artifact = new Artifact(form.name, form.version, null);
|
||||
try {
|
||||
pluginHelper.deleteInstalledArtifact(new Artifact(pluginBean.name, pluginBean.version, null));
|
||||
pluginHelper.deleteInstalledArtifact(artifact);
|
||||
saveInfo(messages -> messages.addSuccessInstallPlugin(GLOBAL, artifact.getFileName()));
|
||||
} catch (Exception e) {
|
||||
|
||||
logger.warn("Failed to delete " + artifact.getFileName(), e);
|
||||
saveError(messages -> messages.addErrorsFailedToDeletePlugin(GLOBAL, artifact.getFileName()));
|
||||
}
|
||||
return redirect(getClass());
|
||||
}
|
||||
|
@ -69,26 +81,32 @@ public class AdminPluginAction extends FessAdminAction {
|
|||
}
|
||||
|
||||
private HtmlResponse asListHtml() {
|
||||
return asHtml(path_AdminPlugin_AdminPluginJsp).renderWith(
|
||||
data ->
|
||||
RenderDataUtil.register(data, "installedArtifactItems", getAllInstalledArtifacts()));
|
||||
return asHtml(path_AdminPlugin_AdminPluginJsp);
|
||||
}
|
||||
|
||||
private List<PluginBean> getAllInstalledArtifacts() {
|
||||
final List<PluginBean> result = new ArrayList<>();
|
||||
for(PluginHelper.ArtifactType artifactType : PluginHelper.ArtifactType.values()) {
|
||||
result.addAll(
|
||||
Arrays.stream(pluginHelper.getInstalledArtifacts(artifactType))
|
||||
.map(artifact -> mappingToBean(PluginHelper.ArtifactType.getType(artifactType.getId()).toString(), artifact)).collect(Collectors.toList()));
|
||||
private List<Map<String, String>> getAllAvailableArtifacts() {
|
||||
final List<Map<String, String>> result = new ArrayList<>();
|
||||
for (PluginHelper.ArtifactType artifactType : PluginHelper.ArtifactType.values()) {
|
||||
result.addAll(Arrays.stream(pluginHelper.getAvailableArtifacts(artifactType)).map(artifact -> beanToMap(artifact))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private PluginBean mappingToBean(final String artifactType, final Artifact artifact) {
|
||||
final PluginBean pluginBean = new PluginBean();
|
||||
pluginBean.artifactType = artifactType;
|
||||
pluginBean.name = artifact.getName();
|
||||
pluginBean.version = artifact.getVersion();
|
||||
return pluginBean;
|
||||
private List<Map<String, String>> getAllInstalledArtifacts() {
|
||||
final List<Map<String, String>> result = new ArrayList<>();
|
||||
for (PluginHelper.ArtifactType artifactType : PluginHelper.ArtifactType.values()) {
|
||||
result.addAll(Arrays.stream(pluginHelper.getInstalledArtifacts(artifactType)).map(artifact -> beanToMap(artifact))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, String> beanToMap(final Artifact artifact) {
|
||||
Map<String, String> item = new HashMap<>();
|
||||
item.put("type", ArtifactType.getType(artifact).getId());
|
||||
item.put("name", artifact.getName());
|
||||
item.put("version", artifact.getVersion());
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2012-2019 CodeLibs Project and the Others.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.codelibs.fess.app.web.admin.plugin;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.lastaflute.web.validation.Required;
|
||||
|
||||
public class DeleteForm {
|
||||
|
||||
@Required
|
||||
@Size(max = 100)
|
||||
public String name;
|
||||
|
||||
@Size(max = 100)
|
||||
public String version;
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2012-2019 CodeLibs Project and the Others.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.codelibs.fess.app.web.admin.plugin;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.lastaflute.web.validation.Required;
|
||||
|
||||
public class InstallForm {
|
||||
|
||||
@Required
|
||||
@Size(max = 100)
|
||||
public String name;
|
||||
|
||||
@Size(max = 100)
|
||||
public String version;
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package org.codelibs.fess.app.web.admin.plugin;
|
||||
|
||||
public class PluginBean {
|
||||
public String artifactType;
|
||||
public String name;
|
||||
public String version;
|
||||
}
|
|
@ -26,6 +26,7 @@ import java.nio.file.Path;
|
|||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -50,16 +51,30 @@ import org.w3c.dom.Node;
|
|||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
// TODO: refactoring, exception handling, improving codes
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
public class PluginHelper {
|
||||
private static final Logger logger = LoggerFactory.getLogger(PluginHelper.class);
|
||||
|
||||
public Artifact[] getArtifacts(final ArtifactType artifactType) {
|
||||
final List<Artifact> list = new ArrayList<>();
|
||||
for (final String url : getRepositories()) {
|
||||
list.addAll(processRepository(artifactType, url));
|
||||
protected LoadingCache<ArtifactType, Artifact[]> availableArtifacts = CacheBuilder.newBuilder().maximumSize(10)
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES).build(new CacheLoader<ArtifactType, Artifact[]>() {
|
||||
public Artifact[] load(ArtifactType key) {
|
||||
final List<Artifact> list = new ArrayList<>();
|
||||
for (final String url : getRepositories()) {
|
||||
list.addAll(processRepository(key, url));
|
||||
}
|
||||
return list.toArray(new Artifact[list.size()]);
|
||||
}
|
||||
});
|
||||
|
||||
public Artifact[] getAvailableArtifacts(final ArtifactType artifactType) {
|
||||
try {
|
||||
return availableArtifacts.get(artifactType);
|
||||
} catch (final Exception e) {
|
||||
throw new PluginException("Failed to access " + artifactType, e);
|
||||
}
|
||||
return list.toArray(new Artifact[list.size()]);
|
||||
}
|
||||
|
||||
protected String[] getRepositories() {
|
||||
|
@ -227,8 +242,8 @@ public class PluginHelper {
|
|||
return id;
|
||||
}
|
||||
|
||||
static public ArtifactType getType(final String name) {
|
||||
if (name.startsWith(DATA_STORE.getId())) {
|
||||
public static ArtifactType getType(final Artifact artifact) {
|
||||
if (artifact.getName().startsWith(DATA_STORE.getId())) {
|
||||
return DATA_STORE;
|
||||
}
|
||||
return UNKNOWN;
|
||||
|
|
|
@ -602,6 +602,9 @@ public class FessLabels extends UserMessages {
|
|||
/** The key of the message: Related Query */
|
||||
public static final String LABELS_menu_related_query = "{labels.menu_related_query}";
|
||||
|
||||
/** The key of the message: Plugin */
|
||||
public static final String LABELS_menu_plugin = "{labels.menu_plugin}";
|
||||
|
||||
/** The key of the message: Search... */
|
||||
public static final String LABELS_SIDEBAR_placeholder_search = "{labels.sidebar.placeholder_search}";
|
||||
|
||||
|
@ -2949,6 +2952,24 @@ public class FessLabels extends UserMessages {
|
|||
/** The key of the message: Reload */
|
||||
public static final String LABELS_reload_doc_index_button = "{labels.reload_doc_index_button}";
|
||||
|
||||
/** The key of the message: Plugin Manager */
|
||||
public static final String LABELS_plugin_management = "{labels.plugin_management}";
|
||||
|
||||
/** The key of the message: Plugin List */
|
||||
public static final String LABELS_plugin_list_name = "{labels.plugin_list_name}";
|
||||
|
||||
/** The key of the message: Type */
|
||||
public static final String LABELS_plugin_type = "{labels.plugin_type}";
|
||||
|
||||
/** The key of the message: Name */
|
||||
public static final String LABELS_plugin_name = "{labels.plugin_name}";
|
||||
|
||||
/** The key of the message: Version */
|
||||
public static final String LABELS_plugin_version = "{labels.plugin_version}";
|
||||
|
||||
/** The key of the message: Delete */
|
||||
public static final String LABELS_plugin_delete = "{labels.plugin_delete}";
|
||||
|
||||
/**
|
||||
* Assert the property is not null.
|
||||
* @param property The value of the property. (NotNull)
|
||||
|
|
|
@ -347,6 +347,12 @@ public class FessMessages extends FessLabels {
|
|||
/** The key of the message: {0} is not supported. */
|
||||
public static final String ERRORS_file_is_not_supported = "{errors.file_is_not_supported}";
|
||||
|
||||
/** The key of the message: Failed to install {0} plugin. */
|
||||
public static final String ERRORS_failed_to_install_plugin = "{errors.failed_to_install_plugin}";
|
||||
|
||||
/** The key of the message: Failed to delete {0} plugin. */
|
||||
public static final String ERRORS_failed_to_delete_plugin = "{errors.failed_to_delete_plugin}";
|
||||
|
||||
/** The key of the message: The given query has unknown condition. */
|
||||
public static final String ERRORS_invalid_query_unknown = "{errors.invalid_query_unknown}";
|
||||
|
||||
|
@ -476,6 +482,12 @@ public class FessMessages extends FessLabels {
|
|||
/** The key of the message: Printed thread dump to log file. */
|
||||
public static final String SUCCESS_print_thread_dump = "{success.print_thread_dump}";
|
||||
|
||||
/** The key of the message: Installing {0} plugin. */
|
||||
public static final String SUCCESS_install_plugin = "{success.install_plugin}";
|
||||
|
||||
/** The key of the message: Deleting {0} plugin. */
|
||||
public static final String SUCCESS_delete_plugin = "{success.delete_plugin}";
|
||||
|
||||
/** The key of the message: Created data. */
|
||||
public static final String SUCCESS_crud_create_crud_table = "{success.crud_create_crud_table}";
|
||||
|
||||
|
@ -2028,6 +2040,36 @@ public class FessMessages extends FessLabels {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.failed_to_install_plugin' with parameters.
|
||||
* <pre>
|
||||
* message: Failed to install {0} plugin.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsFailedToInstallPlugin(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new UserMessage(ERRORS_failed_to_install_plugin, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.failed_to_delete_plugin' with parameters.
|
||||
* <pre>
|
||||
* message: Failed to delete {0} plugin.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsFailedToDeletePlugin(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new UserMessage(ERRORS_failed_to_delete_plugin, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.invalid_query_unknown' with parameters.
|
||||
* <pre>
|
||||
|
@ -2651,6 +2693,36 @@ public class FessMessages extends FessLabels {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'success.install_plugin' with parameters.
|
||||
* <pre>
|
||||
* message: Installing {0} plugin.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addSuccessInstallPlugin(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new UserMessage(SUCCESS_install_plugin, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'success.delete_plugin' with parameters.
|
||||
* <pre>
|
||||
* message: Deleting {0} plugin.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addSuccessDeletePlugin(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new UserMessage(SUCCESS_delete_plugin, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'success.crud_create_crud_table' with parameters.
|
||||
* <pre>
|
||||
|
|
|
@ -1202,6 +1202,9 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
/** The key of the configuration. e.g. maintenance */
|
||||
String ONLINE_HELP_NAME_MAINTENANCE = "online.help.name.maintenance";
|
||||
|
||||
/** The key of the configuration. e.g. plugin */
|
||||
String ONLINE_HELP_NAME_PLUGIN = "online.help.name.plugin";
|
||||
|
||||
/** The key of the configuration. e.g. ja */
|
||||
String ONLINE_HELP_SUPPORTED_LANGS = "online.help.supported.langs";
|
||||
|
||||
|
@ -5218,6 +5221,13 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
*/
|
||||
String getOnlineHelpNameMaintenance();
|
||||
|
||||
/**
|
||||
* Get the value for the key 'online.help.name.plugin'. <br>
|
||||
* The value is, e.g. plugin <br>
|
||||
* @return The value of found property. (NotNull: if not found, exception but basically no way)
|
||||
*/
|
||||
String getOnlineHelpNamePlugin();
|
||||
|
||||
/**
|
||||
* Get the value for the key 'online.help.supported.langs'. <br>
|
||||
* The value is, e.g. ja <br>
|
||||
|
@ -7905,6 +7915,10 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
return get(FessConfig.ONLINE_HELP_NAME_MAINTENANCE);
|
||||
}
|
||||
|
||||
public String getOnlineHelpNamePlugin() {
|
||||
return get(FessConfig.ONLINE_HELP_NAME_PLUGIN);
|
||||
}
|
||||
|
||||
public String getOnlineHelpSupportedLangs() {
|
||||
return get(FessConfig.ONLINE_HELP_SUPPORTED_LANGS);
|
||||
}
|
||||
|
@ -8659,6 +8673,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
defaultMap.put(FessConfig.ONLINE_HELP_NAME_SUGGEST, "suggest");
|
||||
defaultMap.put(FessConfig.ONLINE_HELP_NAME_SEARCHLOG, "searchlog");
|
||||
defaultMap.put(FessConfig.ONLINE_HELP_NAME_MAINTENANCE, "maintenance");
|
||||
defaultMap.put(FessConfig.ONLINE_HELP_NAME_PLUGIN, "plugin");
|
||||
defaultMap.put(FessConfig.ONLINE_HELP_SUPPORTED_LANGS, "ja");
|
||||
defaultMap.put(FessConfig.SUGGEST_POPULAR_WORD_SEED, "0");
|
||||
defaultMap.put(FessConfig.SUGGEST_POPULAR_WORD_TAGS, "");
|
||||
|
|
|
@ -611,6 +611,7 @@ online.help.name.accesstoken=accesstoken
|
|||
online.help.name.suggest=suggest
|
||||
online.help.name.searchlog=searchlog
|
||||
online.help.name.maintenance=maintenance
|
||||
online.help.name.plugin=plugin
|
||||
|
||||
online.help.supported.langs=ja
|
||||
|
||||
|
|
|
@ -192,6 +192,7 @@ labels.menu_access_token=Access Token
|
|||
labels.menu_maintenance=Maintenance
|
||||
labels.menu_related_content=Related Content
|
||||
labels.menu_related_query=Related Query
|
||||
labels.menu_plugin=Plugin
|
||||
labels.sidebar.placeholder_search=Search...
|
||||
labels.sidebar.menu=MENU
|
||||
labels.footer.copyright=©2019 <a href="https://github.com/codelibs">CodeLibs Project</a>.
|
||||
|
|
|
@ -137,12 +137,15 @@ errors.could_not_delete_logged_in_user=Could not delete logged in user.
|
|||
errors.unauthorized_request=Unauthorized request.
|
||||
errors.failed_to_print_thread_dump=Failed to print thread dump.
|
||||
errors.file_is_not_supported={0} is not supported.
|
||||
errors.failed_to_install_plugin=Failed to install {0} plugin.
|
||||
errors.failed_to_delete_plugin=Failed to delete {0} plugin.
|
||||
|
||||
errors.invalid_query_unknown=The given query has unknown condition.
|
||||
errors.invalid_query_parse_error=The given query is invalid.
|
||||
errors.invalid_query_sort_value=The given sort ({0}) is invalid.
|
||||
errors.invalid_query_unsupported_sort_field=The given sort ({0}) is not supported.
|
||||
errors.invalid_query_unsupported_sort_order=The given sort order ({0}) is not supported.
|
||||
errors.invalid_query_unsupported_sort_order=The given sort order ({0}) is not supported.
|
||||
|
||||
errors.crud_invalid_mode=Invalid mode(expected value is {0}, but it's {1}).
|
||||
errors.crud_failed_to_create_instance=Failed to create a new data.
|
||||
|
@ -184,6 +187,8 @@ success.started_data_update=Started data update process.
|
|||
success.reindex_started=Started reindexing.
|
||||
success.bulk_process_started=Bulk process is started.
|
||||
success.print_thread_dump=Printed thread dump to log file.
|
||||
success.install_plugin=Installing {0} plugin.
|
||||
success.delete_plugin=Deleting {0} plugin.
|
||||
|
||||
success.crud_create_crud_table=Created data.
|
||||
success.crud_update_crud_table=Updated data.
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<div class="wrapper">
|
||||
<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
|
||||
<jsp:param name="menuCategoryType" value="log" />
|
||||
<jsp:param name="menuCategoryType" value="system" />
|
||||
<jsp:param name="menuType" value="plugin" />
|
||||
</jsp:include>
|
||||
<div class="content-wrapper">
|
||||
|
@ -49,7 +49,7 @@
|
|||
<c:forEach var="artifact" varStatus="s"
|
||||
items="${installedArtifactItems}">
|
||||
<tr>
|
||||
<td>${f:h(artifact.artifactType)}</td>
|
||||
<td>${f:h(artifact.type)}</td>
|
||||
<td>${f:h(artifact.name)}</td>
|
||||
<td>${f:h(artifact.version)}</td>
|
||||
<td>
|
||||
|
|
|
@ -76,6 +76,12 @@
|
|||
<span><la:message key="labels.menu_access_token" /></span>
|
||||
</la:link></li>
|
||||
|
||||
<li <c:if test="${param.menuType=='plugin'}">class="active"</c:if>><la:link
|
||||
href="/admin/plugin/">
|
||||
<em class='fa fa-genderless'></em>
|
||||
<span><la:message key="labels.menu_plugin" /></span>
|
||||
</la:link></li>
|
||||
|
||||
</ul></li>
|
||||
<li
|
||||
class="treeview <c:if test="${param.menuCategoryType=='crawl'}">active</c:if>"><a
|
||||
|
|
Loading…
Add table
Reference in a new issue