You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/02/17 14:17:09 UTC
[syncope] branch master updated: [SYNCOPE-1658] Tabular Topology (#316)
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new ab1e023 [SYNCOPE-1658] Tabular Topology (#316)
ab1e023 is described below
commit ab1e023e08116b0644a51c0139f6a6fc2fe27c02
Author: SamuelGaro <72...@users.noreply.github.com>
AuthorDate: Thu Feb 17 15:16:57 2022 +0100
[SYNCOPE-1658] Tabular Topology (#316)
---
.../console/commons/ConnectorDataProvider.java | 153 ++++++++
.../console/commons/ResourceDataProvider.java | 153 ++++++++
.../syncope/client/console/pages/Connectors.java | 80 ++++
.../syncope/client/console/pages/Resources.java | 80 ++++
.../console/panels/ConnectorDirectoryPanel.java | 285 ++++++++++++++
.../client/console/panels/ConnidLocations.java | 163 ++++++++
.../console/panels/ResourceDirectoryPanel.java | 432 +++++++++++++++++++++
.../client/console/topology/TabularTopology.java | 116 ++++++
.../wizards/resources/ConnectorDetailsPanel.java | 70 +++-
.../wizards/resources/ConnectorWizardBuilder.java | 10 +-
.../wizards/resources/ResourceConnConfPanel.java | 2 +-
.../wizards/resources/ResourceDetailsPanel.java | 55 ++-
.../wizards/resources/ResourceWizardBuilder.java | 11 +-
.../syncope/client/console/pages/Connectors.html | 35 ++
.../syncope/client/console/pages/Resources.html | 35 ++
.../panels/ConnectorDirectoryPanel.properties | 27 ++
.../ConnectorDirectoryPanel_fr_CA.properties | 27 ++
.../panels/ConnectorDirectoryPanel_it.properties | 27 ++
.../panels/ConnectorDirectoryPanel_ja.properties | 27 ++
.../ConnectorDirectoryPanel_pt_BR.properties | 27 ++
.../panels/ConnectorDirectoryPanel_ru.properties | 27 ++
.../console/panels/ConnidLocations.properties | 18 +
.../panels/ConnidLocations_fr_CA.properties | 18 +
.../console/panels/ConnidLocations_it.properties | 18 +
.../console/panels/ConnidLocations_ja.properties | 18 +
.../panels/ConnidLocations_pt_BR.properties | 18 +
.../console/panels/ConnidLocations_ru.properties | 18 +
.../panels/ResourceDirectoryPanel.properties | 38 ++
.../panels/ResourceDirectoryPanel_fr_CA.properties | 38 ++
.../panels/ResourceDirectoryPanel_it.properties | 38 ++
.../panels/ResourceDirectoryPanel_ja.properties | 38 ++
.../panels/ResourceDirectoryPanel_pt_BR.properties | 38 ++
.../panels/ResourceDirectoryPanel_ru.properties | 38 ++
.../client/console/topology/TabularTopology.html | 29 ++
.../client/console/SyncopeConsoleApplication.java | 5 +-
.../init/ClassPathScanImplementationLookup.java | 12 +-
.../console/tasks/SchedTaskDirectoryPanel.java | 57 +++
.../syncope/client/console/tasks/SchedTasks.java | 21 +
.../client/console/tasks/TaskDirectoryPanel.java | 20 +
.../wicket/markup/html/form/ActionLink.java | 9 +-
.../console/src/main/resources/console.properties | 1 +
.../markup/html/form/ActionsPanel.properties | 23 ++
.../markup/html/form/ActionsPanel_fr_CA.properties | 27 ++
.../markup/html/form/ActionsPanel_it.properties | 24 ++
.../markup/html/form/ActionsPanel_ja.properties | 26 +-
.../markup/html/form/ActionsPanel_pt_BR.properties | 24 ++
.../markup/html/form/ActionsPanel_ru.properties | 26 +-
.../syncope/client/console/AbstractTest.java | 3 +-
.../syncope/fit/console/AbstractConsoleITCase.java | 5 +-
49 files changed, 2458 insertions(+), 32 deletions(-)
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/ConnectorDataProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/ConnectorDataProvider.java
new file mode 100644
index 0000000..f7a3718
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/ConnectorDataProvider.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.commons;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public class ConnectorDataProvider extends DirectoryDataProvider<Serializable> {
+
+ private static final long serialVersionUID = 3122389673525690470L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(ConnectorDataProvider.class);
+
+ private final PageReference pageRef;
+
+ protected int currentPage;
+
+ private String keyword;
+
+ private final ConnectorRestClient restClient = new ConnectorRestClient();
+
+ public ConnectorDataProvider(
+ final int paginatorRows,
+ final PageReference pageRef,
+ final String keyword) {
+ super(paginatorRows);
+ setSort("displayNameSortParam", SortOrder.ASCENDING);
+ this.pageRef = pageRef;
+ this.keyword = keyword;
+ }
+
+ @Override
+ public Iterator<ConnInstanceTO> iterator(final long first, final long count) {
+ List<ConnInstanceTO> result = Collections.emptyList();
+
+ try {
+ currentPage = ((int) first / paginatorRows);
+ if (currentPage < 0) {
+ currentPage = 0;
+ }
+ if (StringUtils.isBlank(keyword)) {
+ result = restClient.getAllConnectors();
+ } else {
+ result = restClient.getAllConnectors().stream().filter(conn ->
+ conn.getDisplayName().toLowerCase().contains(keyword)).collect(Collectors.toList());
+ }
+ } catch (Exception e) {
+ LOG.error("While searching", e);
+ SyncopeConsoleSession.get().onException(e);
+
+ Optional<AjaxRequestTarget> target = RequestCycle.get().find(AjaxRequestTarget.class);
+ target.ifPresent(ajaxRequestTarget ->
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(ajaxRequestTarget));
+ }
+
+ SortParam<String> sortParam = getSort();
+ if (sortParam != null) {
+ result.sort(getComparator(sortParam));
+ }
+
+ return result.subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ private Comparator<ConnInstanceTO> getComparator(final SortParam<String> sortParam) {
+ Comparator<ConnInstanceTO> comparator;
+
+ switch (sortParam.getProperty()) {
+ case "displayNameSortParam":
+ comparator = Comparator.nullsFirst(Comparator.comparing(
+ item -> item.getDisplayName().toLowerCase()));
+ break;
+ case "connectorNameSortParam":
+ comparator = Comparator.nullsFirst(Comparator.comparing(
+ item -> item.getConnectorName().toLowerCase()));
+ break;
+ default:
+ throw new IllegalStateException("The sort param " + sortParam.getProperty() + " is not correct");
+ }
+
+ if (!sortParam.isAscending()) {
+ comparator = comparator.reversed();
+ }
+
+ return comparator;
+ }
+
+ @Override
+ public long size() {
+ long result = 0;
+
+ try {
+ if (StringUtils.isBlank(keyword)) {
+ result = restClient.getAllConnectors().size();
+ } else {
+ result = restClient.getAllConnectors().stream().filter(conn ->
+ conn.getDisplayName().toLowerCase().contains(keyword)).count();
+ }
+ } catch (Exception e) {
+ LOG.error("While requesting for size()", e);
+ SyncopeConsoleSession.get().onException(e);
+
+ RequestCycle.get().find(AjaxRequestTarget.class).
+ ifPresent(target -> ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target));
+ }
+
+ return result;
+ }
+
+ @Override
+ public IModel<Serializable> model(final Serializable object) {
+ return new CompoundPropertyModel<>((ConnInstanceTO) object);
+ }
+
+ public int getCurrentPage() {
+ return currentPage;
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/ResourceDataProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/ResourceDataProvider.java
new file mode 100644
index 0000000..04a2109
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/ResourceDataProvider.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.commons;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public class ResourceDataProvider extends DirectoryDataProvider<Serializable> {
+
+ private static final long serialVersionUID = 3189980210236051840L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(ResourceDataProvider.class);
+
+ private final PageReference pageRef;
+
+ protected int currentPage;
+
+ private String keyword;
+
+ private final ResourceRestClient restClient = new ResourceRestClient();
+
+ public ResourceDataProvider(
+ final int paginatorRows,
+ final PageReference pageRef,
+ final String keyword) {
+ super(paginatorRows);
+ setSort("keySortParam", SortOrder.ASCENDING);
+ this.pageRef = pageRef;
+ this.keyword = keyword;
+ }
+
+ @Override
+ public Iterator<ResourceTO> iterator(final long first, final long count) {
+ List<ResourceTO> result = Collections.emptyList();
+
+ try {
+ currentPage = ((int) first / paginatorRows);
+ if (currentPage < 0) {
+ currentPage = 0;
+ }
+ if (StringUtils.isBlank(keyword)) {
+ result = restClient.list();
+ } else {
+ result = restClient.list().stream().filter(resource ->
+ resource.getKey().toLowerCase().contains(keyword)).collect(Collectors.toList());
+ }
+ } catch (Exception e) {
+ LOG.error("While searching", e);
+ SyncopeConsoleSession.get().onException(e);
+
+ Optional<AjaxRequestTarget> target = RequestCycle.get().find(AjaxRequestTarget.class);
+ target.ifPresent(ajaxRequestTarget ->
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(ajaxRequestTarget));
+ }
+
+ SortParam<String> sortParam = getSort();
+ if (sortParam != null) {
+ result.sort(getComparator(sortParam));
+ }
+
+ return result.subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ private Comparator<ResourceTO> getComparator(final SortParam<String> sortParam) {
+ Comparator<ResourceTO> comparator;
+
+ switch (sortParam.getProperty()) {
+ case "keySortParam":
+ comparator = Comparator.nullsFirst(Comparator.comparing(
+ item -> item.getKey().toLowerCase()));
+ break;
+ case "connectorDisplayNameSortParam":
+ comparator = Comparator.nullsFirst(Comparator.comparing(
+ item -> item.getConnectorDisplayName().toLowerCase()));
+ break;
+ default:
+ throw new IllegalStateException("The sort param " + sortParam.getProperty() + " is not correct");
+ }
+
+ if (!sortParam.isAscending()) {
+ comparator = comparator.reversed();
+ }
+
+ return comparator;
+ }
+
+ @Override
+ public long size() {
+ long result = 0;
+
+ try {
+ if (StringUtils.isBlank(keyword)) {
+ result = restClient.list().size();
+ } else {
+ result = restClient.list().stream().filter(resource ->
+ resource.getKey().toLowerCase().contains(keyword)).count();
+ }
+ } catch (Exception e) {
+ LOG.error("While requesting for size()", e);
+ SyncopeConsoleSession.get().onException(e);
+
+ RequestCycle.get().find(AjaxRequestTarget.class).
+ ifPresent(target -> ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target));
+ }
+
+ return result;
+ }
+
+ @Override
+ public IModel<Serializable> model(final Serializable object) {
+ return new CompoundPropertyModel<>((ResourceTO) object);
+ }
+
+ public int getCurrentPage() {
+ return currentPage;
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/pages/Connectors.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/pages/Connectors.java
new file mode 100644
index 0000000..21441e1
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/pages/Connectors.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.pages;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.panels.ConnectorDirectoryPanel;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.resources.ConnectorWizardBuilder;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+import java.io.Serializable;
+
+public class Connectors extends Panel {
+
+ private static final long serialVersionUID = 305521359617401936L;
+
+ private final WizardMgtPanel<Serializable> connectorDirectoryPanel;
+
+ public Connectors(final String id, final PageReference pageRef) {
+ super(id);
+
+ Model<String> keywordModel = new Model<>(StringUtils.EMPTY);
+
+ WebMarkupContainer searchBoxContainer = new WebMarkupContainer("searchBox");
+ add(searchBoxContainer);
+
+ Form<?> form = new Form<>("form");
+ searchBoxContainer.add(form);
+
+ AjaxTextFieldPanel filter = new AjaxTextFieldPanel("filter", "filter", keywordModel, true);
+ form.add(filter.hideLabel().setOutputMarkupId(true));
+
+ AjaxButton search = new AjaxButton("search") {
+
+ private static final long serialVersionUID = 8390605330558248736L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target) {
+ send(Connectors.this, Broadcast.DEPTH,
+ new ConnectorDirectoryPanel.ConnectorSearchEvent(target, keywordModel.getObject()));
+ }
+ };
+ search.setOutputMarkupId(true);
+ form.add(search);
+ form.setDefaultButton(search);
+
+ connectorDirectoryPanel =
+ new ConnectorDirectoryPanel.Builder(pageRef).
+ addNewItemPanelBuilder(new ConnectorWizardBuilder(
+ new ConnInstanceTO(), pageRef), true).
+ build("connectorDirectoryPanel");
+ connectorDirectoryPanel.setOutputMarkupId(true);
+
+ add(connectorDirectoryPanel);
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/pages/Resources.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/pages/Resources.java
new file mode 100644
index 0000000..37dc5d6
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/pages/Resources.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.pages;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.panels.ResourceDirectoryPanel;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.resources.ResourceWizardBuilder;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+import java.io.Serializable;
+
+public class Resources extends Panel {
+
+ private static final long serialVersionUID = 7240865652350993779L;
+
+ private final WizardMgtPanel<Serializable> resourceDirectoryPanel;
+
+ public Resources(final String id, final PageReference pageRef) {
+ super(id);
+
+ Model<String> keywordModel = new Model<>(StringUtils.EMPTY);
+
+ WebMarkupContainer searchBoxContainer = new WebMarkupContainer("searchBox");
+ add(searchBoxContainer);
+
+ Form<?> form = new Form<>("form");
+ searchBoxContainer.add(form);
+
+ AjaxTextFieldPanel filter = new AjaxTextFieldPanel("filter", "filter", keywordModel, true);
+ form.add(filter.hideLabel().setOutputMarkupId(true));
+
+ AjaxButton search = new AjaxButton("search") {
+
+ private static final long serialVersionUID = 8390605330558248736L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target) {
+ send(Resources.this, Broadcast.DEPTH,
+ new ResourceDirectoryPanel.ResourceSearchEvent(target, keywordModel.getObject()));
+ }
+ };
+ search.setOutputMarkupId(true);
+ form.add(search);
+ form.setDefaultButton(search);
+
+ resourceDirectoryPanel =
+ new ResourceDirectoryPanel.Builder(pageRef).
+ addNewItemPanelBuilder(new ResourceWizardBuilder(
+ new ResourceTO(), pageRef), true).
+ build("resourceDirectoryPanel");
+ resourceDirectoryPanel.setOutputMarkupId(true);
+
+ add(resourceDirectoryPanel);
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.java
new file mode 100644
index 0000000..e446898
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.java
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.audit.AuditHistoryModal;
+import org.apache.syncope.client.console.commons.ConnectorDataProvider;
+import org.apache.syncope.client.console.commons.IdRepoConstants;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.resources.ConnectorWizardBuilder;
+import org.apache.syncope.client.console.wizards.resources.ResourceWizardBuilder;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.IdMEntitlement;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class ConnectorDirectoryPanel extends
+ DirectoryPanel<Serializable, Serializable, ConnectorDataProvider, ConnectorRestClient> {
+
+ private static final long serialVersionUID = 2041468935602350821L;
+
+ private String keyword;
+
+ protected ConnectorDirectoryPanel(final String id, final ConnectorDirectoryPanel.Builder builder) {
+ super(id, builder);
+
+ if (SyncopeConsoleSession.get().owns("CONNECTOR_CREATE")) {
+ MetaDataRoleAuthorizationStrategy.authorizeAll(addAjaxLink, RENDER);
+ } else {
+ MetaDataRoleAuthorizationStrategy.unauthorizeAll(addAjaxLink, RENDER);
+ }
+
+ setShowResultPage(false);
+ modal.size(Modal.Size.Large);
+ initResultTable();
+
+ restClient = builder.restClient;
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof ConnectorSearchEvent) {
+ ConnectorSearchEvent payload = (ConnectorSearchEvent) event.getPayload();
+ AjaxRequestTarget target = payload.getTarget();
+ if (StringUtils.isNotBlank(payload.getKeyword())) {
+ keyword = payload.getKeyword().toLowerCase();
+ }
+ updateResultTable(target);
+ } else {
+ super.onEvent(event);
+ }
+ }
+
+ @Override
+ protected ConnectorDataProvider dataProvider() {
+ dataProvider = new ConnectorDataProvider(rows, pageRef, keyword);
+ return dataProvider;
+ }
+
+ public ConnectorDataProvider getDataProvider() {
+ return dataProvider;
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return IdRepoConstants.PREF_PARAMETERS_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<Serializable, String>> getColumns() {
+ final List<IColumn<Serializable, String>> columns = new ArrayList<>();
+ columns.add(new PropertyColumn<>(
+ new ResourceModel("displayName"), "displayNameSortParam", "displayName"));
+ columns.add(new PropertyColumn<>(
+ new ResourceModel("connectorName"), "connectorNameSortParam", "connectorName"));
+ return columns;
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBatches() {
+ return Collections.singletonList(ActionLink.ActionType.DELETE);
+ }
+
+ @Override
+ public ActionsPanel<Serializable> getActions(final IModel<Serializable> model) {
+ final ActionsPanel<Serializable> panel = super.getActions(model);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 8345646188740279483L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ final ResourceTO modelObject = new ResourceTO();
+ modelObject.setConnector(((ConnInstanceTO) model.getObject()).getKey());
+ modelObject.setConnectorDisplayName(((ConnInstanceTO) model.getObject()).getDisplayName());
+
+ final IModel<ResourceTO> model = new CompoundPropertyModel<>(modelObject);
+ modal.setFormModel(model.getObject());
+
+ target.add(modal.setContent(new ResourceWizardBuilder(modelObject, pageRef).
+ build(BaseModal.CONTENT_ID, AjaxWizard.Mode.CREATE)));
+
+ modal.header(new Model<>(MessageFormat.format(getString("resource.new"),
+ model.getObject().getKey())));
+ modal.show(true);
+
+ target.add(modal);
+ }
+
+ }, ActionLink.ActionType.CREATE_RESOURCE, String.format("%s", IdMEntitlement.RESOURCE_CREATE));
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 8200500789152854321L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ ConnInstanceTO connInstance = ConnectorRestClient.read(((ConnInstanceTO) model.getObject()).getKey());
+
+ final IModel<ConnInstanceTO> model = new CompoundPropertyModel<>(connInstance);
+ modal.setFormModel(model);
+
+ target.add(modal.setContent(new ConnectorWizardBuilder(connInstance, pageRef).
+ build(BaseModal.CONTENT_ID,
+ SyncopeConsoleSession.get().
+ owns(IdMEntitlement.CONNECTOR_UPDATE, connInstance.getAdminRealm())
+ ? AjaxWizard.Mode.EDIT
+ : AjaxWizard.Mode.READONLY)));
+
+ modal.header(
+ new Model<>(MessageFormat.format(getString("connector.edit"), connInstance.getDisplayName())));
+ modal.show(true);
+
+ }
+ }, ActionLink.ActionType.EDIT, String.format("%s,%s", IdMEntitlement.CONNECTOR_READ,
+ IdMEntitlement.CONNECTOR_UPDATE));
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 1085863437941911947L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ ConnInstanceTO modelObject = ConnectorRestClient.read(((ConnInstanceTO) model.getObject()).getKey());
+
+ target.add(altDefaultModal.setContent(new AuditHistoryModal<>(
+ altDefaultModal,
+ AuditElements.EventCategoryType.LOGIC,
+ "ConnectorLogic",
+ modelObject,
+ IdMEntitlement.CONNECTOR_UPDATE,
+ pageRef) {
+
+ private static final long serialVersionUID = -3225348282675513648L;
+
+ @Override
+ protected void restore(final String json, final AjaxRequestTarget target) {
+ try {
+ ConnInstanceTO updated = MAPPER.readValue(json, ConnInstanceTO.class);
+ ConnectorRestClient.update(updated);
+
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ LOG.error("While restoring connector {}",
+ ((ConnInstanceTO) model.getObject()).getKey(), e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }));
+
+ altDefaultModal.header(
+ new Model<>(MessageFormat.format(getString("connector.menu.history"),
+ ((ConnInstanceTO) model.getObject()).getDisplayName())));
+
+ altDefaultModal.show(true);
+ }
+
+ }, ActionLink.ActionType.VIEW_AUDIT_HISTORY,
+ String.format("%s,%s", IdMEntitlement.CONNECTOR_READ, IdRepoEntitlement.AUDIT_LIST));
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -1544718936080799146L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ try {
+ ConnectorRestClient.delete(((ConnInstanceTO) model.getObject()).getKey());
+ target.appendJavaScript(String.format("jsPlumb.remove('%s');",
+ ((ConnInstanceTO) model.getObject()).getKey()));
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (SyncopeClientException e) {
+ LOG.error("While deleting resource {}", ((ConnInstanceTO) model.getObject()).getKey(), e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+
+ }, ActionLink.ActionType.DELETE, IdMEntitlement.CONNECTOR_DELETE, true);
+
+ return panel;
+ }
+
+ public static class ConnectorSearchEvent implements Serializable {
+
+ private static final long serialVersionUID = -282052400565266028L;
+
+ private final AjaxRequestTarget target;
+
+ private final String keyword;
+
+ public ConnectorSearchEvent(final AjaxRequestTarget target, final String keyword) {
+ this.target = target;
+ this.keyword = keyword;
+ }
+
+ public AjaxRequestTarget getTarget() {
+ return target;
+ }
+
+ public String getKeyword() {
+ return keyword;
+ }
+ }
+
+ public static class Builder extends DirectoryPanel.Builder<Serializable, Serializable, ConnectorRestClient> {
+
+ private static final long serialVersionUID = 6128427903964630093L;
+
+ public Builder(final PageReference pageRef) {
+ super(new ConnectorRestClient(), pageRef);
+ setShowResultPage(false);
+ }
+
+ @Override
+ protected WizardMgtPanel<Serializable> newInstance(final String id, final boolean wizardInModal) {
+ return new ConnectorDirectoryPanel(id, this);
+ }
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnidLocations.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnidLocations.java
new file mode 100644
index 0000000..8605c1c
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnidLocations.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.console.commons.IdRepoConstants;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
+import org.apache.syncope.client.ui.commons.rest.RestClient;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.resources.ConnectorWizardBuilder;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.types.IdMEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class ConnidLocations extends
+ DirectoryPanel<Serializable, Serializable, ConnidLocations.ConnidLocationsDataProvider, RestClient> {
+
+ public ConnidLocations(final String id, final Builder builder) {
+ super(id, builder);
+
+ disableCheckBoxes();
+ setShowResultPage(true);
+
+ modal.size(Modal.Size.Large);
+ initResultTable();
+ }
+
+ @Override
+ protected ConnidLocationsDataProvider dataProvider() {
+ return new ConnidLocationsDataProvider(rows);
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return IdRepoConstants.PREF_DYNREALM_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<Serializable, String>> getColumns() {
+ final List<IColumn<Serializable, String>> columns = new ArrayList<>();
+
+ columns.add(new AbstractColumn<>(
+ new ResourceModel(Constants.KEY_FIELD_NAME), Constants.KEY_FIELD_NAME) {
+ @Override
+ public void populateItem(final Item cellItem, final String componentId, final IModel rowModel) {
+ cellItem.add(new Label(componentId, rowModel.getObject().toString()));
+ }
+ });
+
+ return columns;
+ }
+
+ @Override
+ public ActionsPanel<Serializable> getActions(final IModel<Serializable> model) {
+ final ActionsPanel<Serializable> panel = super.getActions(model);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 293293495682202660L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ final ConnInstanceTO modelObject = new ConnInstanceTO();
+ modelObject.setLocation((String) ignore);
+
+ final IModel<ConnInstanceTO> model = new CompoundPropertyModel<>(modelObject);
+ modal.setFormModel(model);
+
+ target.add(modal.setContent(new ConnectorWizardBuilder(modelObject, pageRef).
+ build(BaseModal.CONTENT_ID, AjaxWizard.Mode.CREATE)));
+
+ modal.header(new Model<>(MessageFormat.format(getString("connector.new"), ignore)));
+ modal.show(true);
+ }
+
+ }, ActionLink.ActionType.CREATE, String.format("%s", IdMEntitlement.CONNECTOR_CREATE));
+
+ return panel;
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBatches() {
+ return Collections.emptyList();
+ }
+
+ public abstract static class Builder
+ extends DirectoryPanel.Builder<Serializable, Serializable, RestClient> {
+
+ private static final long serialVersionUID = 4448348557808690524L;
+
+ public Builder(final PageReference pageRef) {
+ super(null, pageRef);
+ }
+
+ @Override
+ protected WizardMgtPanel<Serializable> newInstance(final String id, final boolean wizardInModal) {
+ return new ConnidLocations(id, this);
+ }
+ }
+
+ protected static class ConnidLocationsDataProvider extends DirectoryDataProvider<Serializable> {
+
+ private static final long serialVersionUID = 3161906945317209169L;
+
+ public ConnidLocationsDataProvider(final int paginatorRows) {
+ super(paginatorRows);
+ }
+
+ @Override
+ public Iterator<String> iterator(final long first, final long count) {
+ List<String> result = new ArrayList<>(SyncopeConsoleSession.get().getPlatformInfo().getConnIdLocations());
+ return result.subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ @Override
+ public long size() {
+ return SyncopeConsoleSession.get().getPlatformInfo().getConnIdLocations().size();
+ }
+
+ @Override
+ public IModel<Serializable> model(final Serializable object) {
+ return new CompoundPropertyModel<>(object);
+ }
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
new file mode 100644
index 0000000..481f185
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
@@ -0,0 +1,432 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.audit.AuditHistoryModal;
+import org.apache.syncope.client.console.commons.IdRepoConstants;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.console.commons.ResourceDataProvider;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.client.console.status.ResourceStatusModal;
+import org.apache.syncope.client.console.tasks.PropagationTasks;
+import org.apache.syncope.client.console.tasks.PullTasks;
+import org.apache.syncope.client.console.tasks.PushTasks;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.resources.ResourceProvisionPanel;
+import org.apache.syncope.client.console.wizards.resources.ResourceWizardBuilder;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.IdMEntitlement;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class ResourceDirectoryPanel extends
+ DirectoryPanel<Serializable, Serializable, ResourceDataProvider, ResourceRestClient> {
+
+ private static final long serialVersionUID = -5223129956783782225L;
+
+ private String keyword;
+
+ private final BaseModal<Serializable> propTaskModal;
+
+ private final BaseModal<Serializable> schedTaskModal;
+
+ private final BaseModal<Serializable> provisionModal;
+
+ private final BaseModal<Serializable> historyModal;
+
+ protected ResourceDirectoryPanel(final String id, final ResourceDirectoryPanel.Builder builder) {
+ super(id, builder);
+
+ if (SyncopeConsoleSession.get().owns("RESOURCE_CREATE")) {
+ MetaDataRoleAuthorizationStrategy.authorizeAll(addAjaxLink, RENDER);
+ } else {
+ MetaDataRoleAuthorizationStrategy.unauthorizeAll(addAjaxLink, RENDER);
+ }
+
+ setShowResultPage(false);
+ modal.size(Modal.Size.Large);
+ initResultTable();
+
+ restClient = builder.restClient;
+
+ propTaskModal = new BaseModal<>(Constants.OUTER);
+ propTaskModal.size(Modal.Size.Large);
+ addOuterObject(propTaskModal);
+
+ schedTaskModal = new BaseModal<>(Constants.OUTER) {
+
+ private static final long serialVersionUID = -6165152045136958913L;
+
+ @Override
+ protected void onConfigure() {
+ super.onConfigure();
+ setFooterVisible(false);
+ }
+ };
+ schedTaskModal.size(Modal.Size.Large);
+ addOuterObject(schedTaskModal);
+
+ provisionModal = new BaseModal<>(Constants.OUTER);
+ provisionModal.size(Modal.Size.Large);
+ provisionModal.addSubmitButton();
+ addOuterObject(provisionModal);
+
+ historyModal = new BaseModal<>(Constants.OUTER);
+ historyModal.size(Modal.Size.Large);
+ addOuterObject(historyModal);
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof ResourceSearchEvent) {
+ ResourceSearchEvent payload = (ResourceSearchEvent) event.getPayload();
+ AjaxRequestTarget target = payload.getTarget();
+ if (StringUtils.isNotEmpty(payload.getKeyword())) {
+ keyword = payload.getKeyword().toLowerCase();
+ }
+ updateResultTable(target);
+ } else {
+ super.onEvent(event);
+ }
+ }
+
+ @Override
+ protected ResourceDataProvider dataProvider() {
+ dataProvider = new ResourceDataProvider(rows, pageRef, keyword);
+ return dataProvider;
+ }
+
+ public ResourceDataProvider getDataProvider() {
+ return dataProvider;
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return IdRepoConstants.PREF_PARAMETERS_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<Serializable, String>> getColumns() {
+ final List<IColumn<Serializable, String>> columns = new ArrayList<>();
+ columns.add(new PropertyColumn<>(
+ new ResourceModel("key"), "keySortParam", "key"));
+ columns.add(new PropertyColumn<>(
+ new ResourceModel("connectorDisplayName"), "connectorDisplayNameSortParam", "connectorDisplayName"));
+ return columns;
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBatches() {
+ return Collections.singletonList(ActionLink.ActionType.DELETE);
+ }
+
+ @Override
+ public ActionsPanel<Serializable> getActions(final IModel<Serializable> model) {
+ final ActionsPanel<Serializable> panel = super.getActions(model);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -7220222653598674870L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ ResourceTO resource = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
+ ConnInstanceTO connInstance = ConnectorRestClient.read(resource.getConnector());
+
+ IModel<ResourceTO> model = new CompoundPropertyModel<>(resource);
+ modal.setFormModel(model);
+
+ target.add(modal.setContent(new ResourceWizardBuilder(resource, pageRef).
+ build(BaseModal.CONTENT_ID,
+ SyncopeConsoleSession.get().
+ owns(IdMEntitlement.RESOURCE_UPDATE, connInstance.getAdminRealm())
+ ? AjaxWizard.Mode.EDIT
+ : AjaxWizard.Mode.READONLY)));
+
+ modal.header(new Model<>(MessageFormat.format(getString("resource.edit"), model.getObject().getKey())));
+ modal.show(true);
+ }
+ }, ActionLink.ActionType.EDIT, String.format("%s,%s", IdMEntitlement.RESOURCE_READ,
+ IdMEntitlement.RESOURCE_UPDATE));
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -6467344504797047254L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ ResourceTO resource = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
+ ConnInstanceTO connInstance = ConnectorRestClient.read(resource.getConnector());
+
+ if (SyncopeConsoleSession.get().
+ owns(IdMEntitlement.RESOURCE_UPDATE, connInstance.getAdminRealm())) {
+
+ provisionModal.addSubmitButton();
+ } else {
+ provisionModal.removeSubmitButton();
+ }
+
+ IModel<ResourceTO> model = new CompoundPropertyModel<>(resource);
+ provisionModal.setFormModel(model);
+
+ target.add(provisionModal.setContent(
+ new ResourceProvisionPanel(provisionModal, resource, connInstance.getAdminRealm(), pageRef)));
+
+ provisionModal.header(new Model<>(MessageFormat.format(getString("resource.edit"),
+ model.getObject().getKey())));
+ provisionModal.show(true);
+ }
+ }, ActionLink.ActionType.MAPPING, String.format("%s,%s", IdMEntitlement.RESOURCE_READ,
+ IdMEntitlement.RESOURCE_UPDATE));
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -1448897313753684142L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ ResourceTO resource = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
+
+ target.add(propTaskModal.setContent(new ConnObjects(resource, pageRef)));
+ propTaskModal.header(new StringResourceModel("resource.explore.list", Model.of(model.getObject())));
+ propTaskModal.show(true);
+ }
+ }, ActionLink.ActionType.EXPLORE_RESOURCE, IdMEntitlement.RESOURCE_LIST_CONNOBJECT);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 4800323783814856195L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ target.add(propTaskModal.setContent(
+ new PropagationTasks(propTaskModal, ((ResourceTO) model.getObject()).getKey(), pageRef)));
+ propTaskModal.header(new Model<>(MessageFormat.format(getString("task.propagation.list"),
+ ((ResourceTO) model.getObject()).getKey())));
+ propTaskModal.show(true);
+ }
+ }, ActionLink.ActionType.PROPAGATION_TASKS, IdRepoEntitlement.TASK_LIST);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -4699610013584898667L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ target.add(schedTaskModal.setContent(new PullTasks(schedTaskModal, pageRef,
+ ((ResourceTO) model.getObject()).getKey())));
+ schedTaskModal.header(new Model<>(MessageFormat.format(getString("task.pull.list"),
+ ((ResourceTO) model.getObject()).getKey())));
+ schedTaskModal.show(true);
+ }
+ }, ActionLink.ActionType.PULL_TASKS, IdRepoEntitlement.TASK_LIST);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 2042227976628604686L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ target.add(schedTaskModal.setContent(new PushTasks(schedTaskModal, pageRef,
+ ((ResourceTO) model.getObject()).getKey())));
+ schedTaskModal.header(new Model<>(MessageFormat.format(getString("task.push.list"),
+ ((ResourceTO) model.getObject()).getKey())));
+ schedTaskModal.show(true);
+ }
+ }, ActionLink.ActionType.PUSH_TASKS, IdRepoEntitlement.TASK_LIST);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -5962061673680621813L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ ResourceTO modelObject = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
+ target.add(propTaskModal.setContent(
+ new ResourceStatusModal(propTaskModal, pageRef, modelObject)));
+ propTaskModal.header(new Model<>(MessageFormat.format(getString("resource.reconciliation"),
+ ((ResourceTO) model.getObject()).getKey())));
+ propTaskModal.show(true);
+ }
+ }, ActionLink.ActionType.RECONCILIATION_RESOURCE, IdRepoEntitlement.USER_UPDATE);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -5432034353017728766L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ ResourceTO modelObject = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
+
+ target.add(historyModal.setContent(new AuditHistoryModal<>(
+ historyModal,
+ AuditElements.EventCategoryType.LOGIC,
+ "ResourceLogic",
+ modelObject,
+ IdMEntitlement.RESOURCE_UPDATE,
+ pageRef) {
+
+ private static final long serialVersionUID = -3712506022627033811L;
+
+ @Override
+ protected void restore(final String json, final AjaxRequestTarget target) {
+ try {
+ ResourceTO updated = MAPPER.readValue(json, ResourceTO.class);
+ ResourceRestClient.update(updated);
+
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ LOG.error("While restoring resource {}", ((ResourceTO) model.getObject()).getKey(), e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }));
+
+ historyModal.header(
+ new Model<>(MessageFormat.format(getString("resource.menu.history"),
+ ((ResourceTO) model.getObject()).getKey())));
+
+ historyModal.show(true);
+ }
+ }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, String.format("%s,%s", IdMEntitlement.RESOURCE_READ,
+ IdRepoEntitlement.AUDIT_LIST));
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 7019899256702149874L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ try {
+ ResourceTO resource = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
+ resource.setKey("Copy of " + resource.getKey());
+ // reset some resource objects keys
+ if (resource.getOrgUnit() != null) {
+ resource.getOrgUnit().setKey(null);
+ resource.getOrgUnit().getItems().forEach(item -> item.setKey(null));
+ }
+ resource.getProvisions().forEach(provision -> {
+ provision.setKey(null);
+ if (provision.getMapping() != null) {
+ provision.getMapping().getItems().forEach(item -> item.setKey(null));
+ provision.getMapping().getLinkingItems().clear();
+ }
+ provision.getVirSchemas().clear();
+ });
+ target.add(modal.setContent(new ResourceWizardBuilder(resource, pageRef).
+ build(BaseModal.CONTENT_ID, AjaxWizard.Mode.CREATE)));
+
+ modal.header(new Model<>(MessageFormat.format(getString("resource.clone"), resource.getKey())));
+ modal.show(true);
+ } catch (SyncopeClientException e) {
+ LOG.error("While cloning resource {}", ((ResourceTO) model.getObject()).getKey(), e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }, ActionLink.ActionType.CLONE, IdMEntitlement.RESOURCE_CREATE);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = 4516186028545701573L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ try {
+ ResourceRestClient.delete(((ResourceTO) model.getObject()).getKey());
+ target.appendJavaScript(String.format("jsPlumb.remove('%s');",
+ ((ResourceTO) model.getObject()).getKey()));
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (SyncopeClientException e) {
+ LOG.error("While deleting resource {}", ((ResourceTO) model.getObject()).getKey(), e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }, ActionLink.ActionType.DELETE, IdMEntitlement.RESOURCE_DELETE, true);
+
+ return panel;
+ }
+
+ public static class ResourceSearchEvent implements Serializable {
+
+ private static final long serialVersionUID = 213974502541311941L;
+
+ private final AjaxRequestTarget target;
+
+ private final String keyword;
+
+ public ResourceSearchEvent(final AjaxRequestTarget target, final String keyword) {
+ this.target = target;
+ this.keyword = keyword;
+ }
+
+ public AjaxRequestTarget getTarget() {
+ return target;
+ }
+
+ public String getKeyword() {
+ return keyword;
+ }
+ }
+
+ public static class Builder extends DirectoryPanel.Builder<Serializable, Serializable, ResourceRestClient> {
+
+ private static final long serialVersionUID = -1391308721262593468L;
+
+ public Builder(final PageReference pageRef) {
+ super(new ResourceRestClient(), pageRef);
+ setShowResultPage(false);
+ }
+
+ @Override
+ protected WizardMgtPanel<Serializable> newInstance(final String id, final boolean wizardInModal) {
+ return new ResourceDirectoryPanel(id, this);
+ }
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
new file mode 100644
index 0000000..b39e047
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.syncope.client.console.topology;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
+import org.apache.syncope.client.console.annotations.IdMPage;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.pages.Connectors;
+import org.apache.syncope.client.console.pages.Resources;
+import org.apache.syncope.client.console.panels.ConnidLocations;
+import org.apache.syncope.client.console.tasks.SchedTasks;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.common.lib.types.IdMEntitlement;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@IdMPage(label = "TabularTopology", icon = "fas fa-plug", listEntitlement = IdMEntitlement.RESOURCE_LIST, priority = 1)
+public class TabularTopology extends BasePage {
+
+ private static final long serialVersionUID = -4434385801124981824L;
+
+ public TabularTopology() {
+ TopologyWebSocketBehavior websocket = new TopologyWebSocketBehavior();
+ body.add(websocket);
+
+ WebMarkupContainer content = new WebMarkupContainer("content");
+ content.setOutputMarkupId(true);
+ content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));
+ body.add(content);
+ }
+
+ private List<ITab> buildTabList() {
+ final List<ITab> tabs = new ArrayList<>();
+
+ tabs.add(new AbstractTab(new Model<>("CustomTasks")) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ BaseModal<Serializable> schedTaskModal = new BaseModal<>(Constants.OUTER) {
+
+ private static final long serialVersionUID = -1673561782333149836L;
+
+ @Override
+ protected void onConfigure() {
+ super.onConfigure();
+ setFooterVisible(false);
+ }
+ };
+ schedTaskModal.size(Modal.Size.Large);
+ return new SchedTasks(schedTaskModal, getPageReference(), true, panelId);
+ }
+ });
+
+ tabs.add(new AbstractTab(new Model<>("Resources")) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new Resources(panelId, getPageReference());
+ }
+ });
+
+ tabs.add(new AbstractTab(new Model<>("Connectors")) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new Connectors(panelId, getPageReference());
+ }
+ });
+
+ tabs.add(new AbstractTab(new Model<>("ConnectorServers")) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new ConnidLocations.Builder(getPageReference()) {
+
+ private static final long serialVersionUID = -2555113973787214723L;
+
+ }.build(panelId);
+ }
+ });
+
+ return tabs;
+ }
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
index f9b2a85..32ecfd3 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
@@ -22,8 +22,10 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.RealmsUtils;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.console.rest.RealmRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSearchFieldPanel;
@@ -66,7 +68,7 @@ public class ConnectorDetailsPanel extends WizardStep {
? RealmRestClient.search(RealmsUtils.buildQuery(input)).getResult()
: RealmRestClient.list()).
stream().filter(realm -> SyncopeConsoleSession.get().getAuthRealms().stream().anyMatch(
- authRealm -> realm.getFullPath().startsWith(authRealm))).
+ authRealm -> realm.getFullPath().startsWith(authRealm))).
map(RealmTO::getFullPath).collect(Collectors.toList()).iterator();
}
};
@@ -81,17 +83,52 @@ public class ConnectorDetailsPanel extends WizardStep {
displayName.addRequiredLabel();
add(displayName);
- AjaxTextFieldPanel location = new AjaxTextFieldPanel(
- "location", "location", new PropertyModel<>(connInstanceTO, "location"), false);
- location.addRequiredLabel();
- location.setOutputMarkupId(true);
- location.setEnabled(false);
- add(location);
-
final AjaxDropDownChoicePanel<String> bundleName = new AjaxDropDownChoicePanel<>(
"bundleName",
"bundleName",
new PropertyModel<>(connInstanceTO, "bundleName"), false);
+
+ if (StringUtils.isNotBlank(connInstanceTO.getLocation())) {
+ AjaxTextFieldPanel location = new AjaxTextFieldPanel(
+ "location", "location", new PropertyModel<>(connInstanceTO, "location"), false);
+ location.addRequiredLabel();
+ location.setOutputMarkupId(true);
+ location.setEnabled(false);
+ add(location);
+ } else {
+ final AjaxDropDownChoicePanel<String> location = new AjaxDropDownChoicePanel<>(
+ "location", "location", new PropertyModel<>(connInstanceTO, "location"), false);
+ location.setChoices(new ArrayList<>(SyncopeConsoleSession.get().getPlatformInfo().getConnIdLocations()));
+ location.addRequiredLabel();
+ location.setOutputMarkupId(true);
+ location.getField().setOutputMarkupId(true);
+ add(location);
+
+ location.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -5609231641453245929L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ ((DropDownChoice<String>) location.getField()).setNullValid(false);
+ bundleName.setEnabled(true);
+
+ List<ConnBundleTO> bundles = ConnectorRestClient.getAllBundles().stream().
+ filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
+ collect(Collectors.toList());
+
+ List<String> listBundles = getBundles(connInstanceTO, bundles);
+ if (listBundles.size() == 1) {
+ connInstanceTO.setBundleName(listBundles.get(0));
+ bundleName.getField().setModelObject(listBundles.get(0));
+ }
+ bundleName.setChoices(listBundles);
+
+ target.add(bundleName);
+ }
+ });
+ }
+
((DropDownChoice<String>) bundleName.getField()).setNullValid(true);
List<String> bundleNames = new ArrayList<>();
@@ -124,7 +161,15 @@ public class ConnectorDetailsPanel extends WizardStep {
((DropDownChoice<String>) bundleName.getField()).setNullValid(false);
version.setEnabled(true);
- List<String> versions = getVersions(connInstanceTO, bundles);
+ List<String> versions;
+ if (bundles.isEmpty()) {
+ List<ConnBundleTO> bundles = ConnectorRestClient.getAllBundles().stream().
+ filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
+ collect(Collectors.toList());
+ versions = getVersions(connInstanceTO, bundles);
+ } else {
+ versions = getVersions(connInstanceTO, bundles);
+ }
if (versions.size() == 1) {
connInstanceTO.setVersion(versions.get(0));
version.getField().setModelObject(versions.get(0));
@@ -166,7 +211,12 @@ public class ConnectorDetailsPanel extends WizardStep {
private static List<String> getVersions(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
return bundles.stream().filter(object -> object.getLocation().equals(connInstanceTO.getLocation())
- && object.getBundleName().equals(connInstanceTO.getBundleName())).
+ && object.getBundleName().equals(connInstanceTO.getBundleName())).
map(ConnBundleTO::getVersion).collect(Collectors.toList());
}
+
+ private List<String> getBundles(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
+ return bundles.stream().filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
+ map(ConnBundleTO::getBundleName).collect(Collectors.toList());
+ }
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
index 7a5ae9c..4346106 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
@@ -122,7 +122,15 @@ public class ConnectorWizardBuilder extends AbstractResourceWizardBuilder<ConnIn
}
protected static ConnBundleTO getBundle(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
- return bundles.stream().filter(bundle
+ List<ConnBundleTO> bundlesList;
+ if (bundles.isEmpty()) {
+ bundlesList = ConnectorRestClient.getAllBundles().stream().
+ filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
+ collect(Collectors.toList());
+ } else {
+ bundlesList = bundles;
+ }
+ return bundlesList.stream().filter(bundle
-> bundle.getBundleName().equals(connInstanceTO.getBundleName())
&& bundle.getVersion().equals(connInstanceTO.getVersion())).
findFirst().orElse(null);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
index e86481c..207be00 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
@@ -92,7 +92,7 @@ public abstract class ResourceConnConfPanel extends AbstractConnConfPanel<Resour
filter(ConnConfProperty::isOverridable).
forEachOrdered(props::add);
}
- if (createFlag || resourceTO.getConfOverride().isEmpty()) {
+ if (resourceTO.getConfOverride().isEmpty()) {
resourceTO.getConfOverride().clear();
} else {
Map<String, ConnConfProperty> valuedProps = new HashMap<>();
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java
index 94ae8b0..b4bf9c8 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java
@@ -18,9 +18,13 @@
*/
package org.apache.syncope.client.console.wizards.resources;
+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 org.apache.syncope.client.console.rest.ConnectorRestClient;
import org.apache.syncope.client.console.rest.ImplementationRestClient;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
@@ -34,6 +38,7 @@ import org.apache.syncope.common.lib.types.IdMImplementationType;
import org.apache.syncope.common.lib.types.TraceLevel;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
@@ -52,7 +57,7 @@ public class ResourceDetailsPanel extends WizardStep {
@Override
protected List<String> load() {
return ImplementationRestClient.list(IdMImplementationType.PROPAGATION_ACTIONS).stream().
- map(EntityTO::getKey).sorted().collect(Collectors.toList());
+ map(EntityTO::getKey).sorted().collect(Collectors.toList());
}
};
@@ -63,7 +68,7 @@ public class ResourceDetailsPanel extends WizardStep {
@Override
protected List<String> load() {
return ImplementationRestClient.list(IdMImplementationType.PROVISION_SORTER).stream().
- map(EntityTO::getKey).sorted().collect(Collectors.toList());
+ map(EntityTO::getKey).sorted().collect(Collectors.toList());
}
};
@@ -139,10 +144,46 @@ public class ResourceDetailsPanel extends WizardStep {
false).
setChoices(Arrays.stream(TraceLevel.values()).collect(Collectors.toList())).setNullValid(false));
- container.add(new AjaxTextFieldPanel(
- "connector",
- new ResourceModel("connector", "connector").getObject(),
- new Model<>(resourceTO.getConnectorDisplayName()),
- false).addRequiredLabel().setEnabled(false));
+ if (resourceTO.getConnector() != null) {
+ container.add(new AjaxTextFieldPanel(
+ "connector",
+ new ResourceModel("connector", "connector").getObject(),
+ new Model<>(resourceTO.getConnectorDisplayName()),
+ false).addRequiredLabel().setEnabled(false));
+ } else {
+ final AjaxDropDownChoicePanel<String> connector = new AjaxDropDownChoicePanel<>(
+ "connector",
+ new ResourceModel("connector", "connector").getObject(),
+ new PropertyModel<>(resourceTO, "connector"), false);
+ Map<String, String> connectorsMap = new HashMap<>();
+ ConnectorRestClient.getAllConnectors().forEach(conn -> connectorsMap.put(conn.getKey(),
+ conn.getDisplayName()));
+ connector.setChoices(new ArrayList<>(connectorsMap.keySet()));
+ connector.setChoiceRenderer(new IChoiceRenderer<>() {
+
+ private static final long serialVersionUID = 91313845533448846L;
+
+ private final Map<String, String> valueMap = connectorsMap;
+
+ @Override
+ public String getDisplayValue(final String value) {
+ return valueMap.get(value) == null ? value : valueMap.get(value);
+ }
+
+ @Override
+ public String getIdValue(final String value, final int i) {
+ return value;
+ }
+
+ @Override
+ public String getObject(final String id, final IModel<? extends List<? extends String>> choices) {
+ return id;
+ }
+ });
+ connector.addRequiredLabel();
+ connector.setOutputMarkupId(true);
+ connector.getField().setOutputMarkupId(true);
+ container.add(connector);
+ }
}
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java
index d8c9198..229dd50 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.console.wizards.resources;
import java.io.Serializable;
+import java.util.Collections;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.rest.ConnectorRestClient;
import org.apache.syncope.client.console.rest.ResourceRestClient;
@@ -68,8 +69,12 @@ public class ResourceWizardBuilder extends AbstractResourceWizardBuilder<Resourc
}
});
- wizardModel.add(new ResourceConnCapabilitiesPanel(
- resourceTO, ConnectorRestClient.read(resourceTO.getConnector()).getCapabilities()));
+ if (resourceTO.getConnector() != null) {
+ wizardModel.add(new ResourceConnCapabilitiesPanel(
+ resourceTO, ConnectorRestClient.read(resourceTO.getConnector()).getCapabilities()));
+ } else {
+ wizardModel.add(new ResourceConnCapabilitiesPanel(resourceTO, Collections.emptySet()));
+ }
wizardModel.add(new ResourceSecurityPanel(resourceTO));
return wizardModel;
@@ -77,7 +82,7 @@ public class ResourceWizardBuilder extends AbstractResourceWizardBuilder<Resourc
@Override
protected ResourceTO onApplyInternal(final Serializable modelObject) {
- ResourceTO resourceTO = ResourceTO.class.cast(modelObject);
+ ResourceTO resourceTO = (ResourceTO) modelObject;
if (createFlag) {
resourceTO = ResourceRestClient.create(resourceTO);
} else {
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/pages/Connectors.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/pages/Connectors.html
new file mode 100644
index 0000000..dcb224a
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/pages/Connectors.html
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:panel>
+ <div wicket:id="searchBox">
+ <form wicket:id="form">
+ <div class="input-group mb-3">
+ <span wicket:id="filter">[FILTER]</span>
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default btn-flat" wicket:id="search">
+ <span class="fas fa-search" aria-hidden="true"></span>
+ </button>
+ </span>
+ </div>
+ </form>
+ </div>
+ <div wicket:id="connectorDirectoryPanel"></div>
+ </wicket:panel>
+</html>
\ No newline at end of file
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/pages/Resources.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/pages/Resources.html
new file mode 100644
index 0000000..d56e1ab
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/pages/Resources.html
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:panel>
+ <div wicket:id="searchBox">
+ <form wicket:id="form">
+ <div class="input-group mb-3">
+ <span wicket:id="filter">[FILTER]</span>
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default btn-flat" wicket:id="search">
+ <span class="fas fa-search" aria-hidden="true"></span>
+ </button>
+ </span>
+ </div>
+ </form>
+ </div>
+ <div wicket:id="resourceDirectoryPanel"></div>
+ </wicket:panel>
+</html>
\ No newline at end of file
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.properties
new file mode 100644
index 0000000..feec3b7
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.properties
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+displayName=Connector Name
+connectorName=Connector Type
+
+any.new=New connector
+connector.edit=Edit connector {0}
+connector.menu.add=Add new connector
+connector.menu.remove=Remove connector
+connector.menu.edit=Edit connector
+connector.menu.history=Configuration history
+
+resource.new=New resource
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_fr_CA.properties
new file mode 100644
index 0000000..c739b94
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_fr_CA.properties
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+displayName=Nom du connecteur
+connectorName=Type de connecteur
+
+any.new=Nouveau connecteur
+connector.edit=Modifier le connecteur {0}
+connector.menu.add=Ajouter un nouveau connecteur
+connector.menu.remove=Retirer le connecteur
+connector.menu.edit=Modifier le connecteur
+connector.menu.history=Historique des configurations
+
+resource.new=Nouvelle ressource
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_it.properties
new file mode 100644
index 0000000..9b3d7c0
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_it.properties
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+displayName=Nome Connettore
+connectorName=Tipo Connettore
+
+any.new=Nuovo connettore
+connector.edit=Modifica connettore {0}
+connector.menu.add=Aggiungi nuovo connettore
+connector.menu.remove=Rimuovi connettore
+connector.menu.edit=Modifica connettore
+connector.menu.history=Storico delle configurazioni
+
+resource.new=Nuova risorsa
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_ja.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_ja.properties
new file mode 100644
index 0000000..a2bd6fd
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_ja.properties
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+displayName=\u30b3\u30cd\u30af\u30bf\u540d
+connectorName=\u30b3\u30cd\u30af\u30bf\u30bf\u30a4\u30d7
+
+any.new=\u65b0\u3057\u3044\u30b3\u30cd\u30af\u30bf
+connector.edit=\u30b3\u30cd\u30af\u30bf\u3092\u7de8\u96c6\u3059\u308b {0}
+connector.menu.add=\u65b0\u3057\u3044\u30b3\u30cd\u30af\u30bf\u3092\u8ffd\u52a0\u3057\u307e\u3059
+connector.menu.remove=\u30b3\u30cd\u30af\u30bf\u3092\u53d6\u308a\u5916\u3057\u307e\u3059
+connector.menu.edit=\u30b3\u30cd\u30af\u30bf\u3092\u7de8\u96c6\u3059\u308b
+connector.menu.history=\u69cb\u6210\u5c65\u6b74
+
+resource.new=\u65b0\u3057\u3044\u30ea\u30bd\u30fc\u30b9
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_pt_BR.properties
new file mode 100644
index 0000000..307a0bb
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_pt_BR.properties
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+displayName=Nome do conector
+connectorName=Tipo de conector
+
+any.new=Novo conector
+connector.edit=Editar conector {0}
+connector.menu.add=Adicionar novo conector
+connector.menu.remove=Remova o conector
+connector.menu.edit=Editar conector
+connector.menu.history=Hist\u00f3rico de Configura\u00e7\u00c3o
+
+resource.new=Novo recurso
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_ru.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_ru.properties
new file mode 100644
index 0000000..ec6f84c
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel_ru.properties
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+displayName=\u0418\u043c\u044f\u0020\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0435\u043b\u044f
+connectorName=\u0422\u0438\u043f\u0020\u0440\u0430\u0437\u044a\u0435\u043c\u0430
+
+any.new=\u041d\u043e\u0432\u044b\u0439\u0020\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440
+connector.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0020\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0435\u043b\u044c {0}
+connector.menu.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c\u0020\u043d\u043e\u0432\u044b\u0439\u0020\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440
+connector.menu.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c\u0020\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0435\u043b\u044c
+connector.menu.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0020\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0435\u043b\u044c
+connector.menu.history=\u0418\u0441\u0442\u043e\u0440\u0438\u044f\u0020\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438
+
+resource.new=\u041d\u043e\u0432\u044b\u0439\u0020\u0440\u0435\u0441\u0443\u0440\u0441
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations.properties
new file mode 100644
index 0000000..1fd8e9e
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Connid locations
+connector.new=New connector
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_fr_CA.properties
new file mode 100644
index 0000000..6b31536
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_fr_CA.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Emplacements Connid
+connector.new=Nouveau connecteur
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_it.properties
new file mode 100644
index 0000000..c877b7e
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_it.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Connid locations
+connector.new=Nuovo connettore
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_ja.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_ja.properties
new file mode 100644
index 0000000..26559d2
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_ja.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Connid \u306e\u5834\u6240
+connector.new=\u65b0\u3057\u3044\u30b3\u30cd\u30af\u30bf
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_pt_BR.properties
new file mode 100644
index 0000000..3b78e3f
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_pt_BR.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Locais de Connid
+connector.new=Novo conector
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_ru.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_ru.properties
new file mode 100644
index 0000000..642498c
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ConnidLocations_ru.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Connid \u043b\u043e\u043a\u0430\u0446\u0438\u0438
+connector.new=\u041d\u043e\u0432\u044b\u0439\u0020\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.properties
new file mode 100644
index 0000000..85c330f
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.properties
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Resource Name
+connectorDisplayName=Connector
+
+any.new=New resource
+resource.edit=Edit resource {0}
+resource.menu.add=Add new resource
+resource.menu.remove=Remove resource
+resource.menu.edit=Edit resource
+resource.menu.provision=Edit provision rules
+resource.menu.explore=Explore resource
+resource.menu.history=Configuration history
+resource.menu.clone=Clone resource
+
+task.propagation.list=Propagation tasks {0}
+task.pull.list=Pull tasks {0}
+task.push.list=Push tasks {0}
+resource.explore.list=Explore ${key}
+resource.reconciliation=Reconciliation {0}
+resource.menu.reconciliation=Reconciliation
+resource.menu.push.list=Push tasks
+resource.menu.pull.list=Pull tasks
+resource.menu.propagation.list=Propagation tasks
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_fr_CA.properties
new file mode 100644
index 0000000..ab162bb
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_fr_CA.properties
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Nom de la ressource
+connectorDisplayName=Connecteur
+
+any.new=Nouvelle ressource
+resource.edit=Modifier la ressource {0}
+resource.menu.add=Ajouter une nouvelle ressource
+resource.menu.remove=Supprimer la ressource
+resource.menu.edit=Modifier la ressource
+resource.menu.provision=Modifier les r\u00e8gles de mise \u00e0 disposition
+resource.menu.explore=Explorer la ressource
+resource.menu.history=Historique des configurations
+resource.menu.clone=Cloner la ressource
+
+task.propagation.list=T\u00e2ches de propagation {0}
+task.pull.list=T\u00e2ches d\u0027extraction {0}
+task.push.list=Pousser les t\u00e2ches {0}
+resource.explore.list=Explorer ${key}
+resource.reconciliation=R\u00e9conciliation {0}
+resource.menu.reconciliation=R\u00e9conciliation
+resource.menu.push.list=Pousser les t\u00e2ches
+resource.menu.pull.list=T\u00e2ches d\u0027extraction
+resource.menu.propagation.list=T\u00e2ches de propagation
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_it.properties
new file mode 100644
index 0000000..b5e97bc
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_it.properties
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Nome Risorsa
+connectorDisplayName=Connettore
+
+any.new=Nuova risorsa
+resource.edit=Modifica risorsa {0}
+resource.menu.add=Aggiungi nuova risorsa
+resource.menu.remove=Rimuovi risorsa
+resource.menu.edit=Modifica risorsa
+resource.menu.provision=Modifica regole di provisioning
+resource.menu.explore=Esplora risorsa
+resource.menu.history=Storico delle configurazioni
+resource.menu.clone=Duplica risorsa
+
+task.propagation.list=Task di propagazione {0}
+task.pull.list=Pull task {0}
+task.push.list=Push task {0}
+resource.explore.list=Esplora ${key}
+resource.reconciliation=Riconciliazione {0}
+resource.menu.reconciliation=Riconciliazione
+resource.menu.push.list=Push tasks
+resource.menu.pull.list=Pull tasks
+resource.menu.propagation.list=Task di propagazione
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_ja.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_ja.properties
new file mode 100644
index 0000000..e820162
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_ja.properties
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=\u30ea\u30bd\u30fc\u30b9\u540d
+connectorDisplayName=\u30b3\u30cd\u30af\u30bf
+
+any.new=\u65b0\u3057\u3044\u30ea\u30bd\u30fc\u30b9
+resource.edit=\u30ea\u30bd\u30fc\u30b9\u306e\u7de8\u96c6 {0}
+resource.menu.add=\u65b0\u3057\u3044\u30ea\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3059\u308b
+resource.menu.remove=\u30ea\u30bd\u30fc\u30b9\u3092\u524a\u9664\u3059\u308b
+resource.menu.edit=\u30ea\u30bd\u30fc\u30b9\u306e\u7de8\u96c6
+resource.menu.provision=\u30d7\u30ed\u30d3\u30b8\u30e7\u30cb\u30f3\u30b0\u30eb\u30fc\u30eb\u306e\u7de8\u96c6
+resource.menu.explore=\u30ea\u30bd\u30fc\u30b9\u3092\u63a2\u7d22\u3059\u308b
+resource.menu.history=\u69cb\u6210\u5c65\u6b74
+resource.menu.clone=\u30ea\u30bd\u30fc\u30b9\u306e\u30af\u30ed\u30fc\u30f3
+
+task.propagation.list=\u4f1d\u64ad\u30bf\u30b9\u30af {0}
+task.pull.list=\u30bf\u30b9\u30af\u3092\u30d7\u30eb\u3059\u308b {0}
+task.push.list=\u30d7\u30c3\u30b7\u30e5\u30bf\u30b9\u30af {0}
+resource.explore.list=\u63a2\u691c ${key}
+resource.reconciliation=\u548c\u89e3 {0}
+resource.menu.reconciliation=\u548c\u89e3
+resource.menu.push.list=\u30d7\u30c3\u30b7\u30e5\u30bf\u30b9\u30af
+resource.menu.pull.list=\u30bf\u30b9\u30af\u3092\u30d7\u30eb\u3059\u308b
+resource.menu.propagation.list=\u4f1d\u64ad\u30bf\u30b9\u30af
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_pt_BR.properties
new file mode 100644
index 0000000..1600a2c
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_pt_BR.properties
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=Nome do recurso
+connectorDisplayName=Conector
+
+any.new=Novo recurso
+resource.edit=Editar recurso {0}
+resource.menu.add=Adicionar novo recurso
+resource.menu.remove=Remover recurso
+resource.menu.edit=Editar recurso
+resource.menu.provision=Editar regras de provis\u00e3o
+resource.menu.explore=Explorar recurso
+resource.menu.history=Hist\u00f3rico de Configura\u00e7\u00e3o
+resource.menu.clone=Clonar recurso
+
+task.propagation.list=Tarefas de propaga\u00e7\u00e3o {0}
+task.pull.list=Puxe tarefas {0}
+task.push.list=Tarefas push {0}
+resource.explore.list=Explorar ${key}
+resource.reconciliation=Reconcilia\u00e7\u00e3o {0}
+resource.menu.reconciliation=Reconcilia\u00e7\u00e3o
+resource.menu.push.list=Tarefas push
+resource.menu.pull.list=Puxe tarefas
+resource.menu.propagation.list=Tarefas de propaga\u00e7\u00e3o
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_ru.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_ru.properties
new file mode 100644
index 0000000..b712405
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDirectoryPanel_ru.properties
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+key=\u0418\u043c\u044f\u0020\u0440\u0435\u0441\u0443\u0440\u0441\u0430
+connectorDisplayName=\u0421\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0435\u043b\u044c
+
+any.new=\u041d\u043e\u0432\u044b\u0439\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+resource.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0020\u0440\u0435\u0441\u0443\u0440\u0441 {0}
+resource.menu.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c\u0020\u043d\u043e\u0432\u044b\u0439\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+resource.menu.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+resource.menu.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+resource.menu.provision=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0020\u043f\u0440\u0430\u0432\u0438\u043b\u0430\u0020\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f
+resource.menu.explore=\u0418\u0441\u0441\u043b\u0435\u0434\u0443\u0439\u0442\u0435\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+resource.menu.history=\u0418\u0441\u0442\u043e\u0440\u0438\u044f\u0020\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438
+resource.menu.clone=\u041a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+
+task.propagation.list=\u0417\u0430\u0434\u0430\u0447\u0438\u0020\u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f {0}
+task.pull.list=\u0412\u044b\u0442\u044f\u0433\u0438\u0432\u0430\u0439\u0442\u0435\u0020\u0437\u0430\u0434\u0430\u0447\u0438 {0}
+task.push.list=Push-\u0437\u0430\u0434\u0430\u0447\u0438 {0}
+resource.explore.list=\u041f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c\u0020\u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f ${key}
+resource.reconciliation=\u041f\u0440\u0438\u043c\u0438\u0440\u0435\u043d\u0438\u0435 {0}
+resource.menu.reconciliation=\u041f\u0440\u0438\u043c\u0438\u0440\u0435\u043d\u0438\u0435
+resource.menu.push.list=Push-\u0437\u0430\u0434\u0430\u0447\u0438
+resource.menu.pull.list=\u0412\u044b\u0442\u044f\u0433\u0438\u0432\u0430\u0439\u0442\u0435\u0020\u0437\u0430\u0434\u0430\u0447\u0438
+resource.menu.propagation.list=\u0417\u0430\u0434\u0430\u0447\u0438\u0020\u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TabularTopology.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TabularTopology.html
new file mode 100644
index 0000000..f52d2c3
--- /dev/null
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TabularTopology.html
@@ -0,0 +1,29 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+<wicket:extend>
+ <section class="content" wicket:id="content">
+ <div class="container-fluid">
+ <div class="card card-outline">
+ <div class="card-body" wicket:id="tabbedPanel"/>
+ </div>
+ </div>
+ </section>
+</wicket:extend>
+</html>
\ No newline at end of file
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
index 9ee4764..f1b3630 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
@@ -104,9 +104,10 @@ public class SyncopeConsoleApplication extends SpringBootServletInitializer {
@ConditionalOnMissingBean(name = "classPathScanImplementationLookup")
@Bean
- public ClassPathScanImplementationLookup classPathScanImplementationLookup(final ApplicationContext ctx) {
+ public ClassPathScanImplementationLookup classPathScanImplementationLookup(final ApplicationContext ctx,
+ final ConsoleProperties props) {
ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(
- ctx.getBeansOfType(ClassPathScanImplementationContributor.class).values());
+ ctx.getBeansOfType(ClassPathScanImplementationContributor.class).values(), props);
lookup.load();
return lookup;
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
index 65df3a8..11e6edb 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
@@ -32,6 +32,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.client.console.ConsoleProperties;
import org.apache.syncope.client.console.annotations.AMPage;
import org.apache.syncope.client.ui.commons.annotations.ExtPage;
import org.apache.syncope.client.console.pages.BaseExtPage;
@@ -112,8 +113,12 @@ public class ClassPathScanImplementationLookup {
private List<Class<? extends BasePage>> amPages;
- public ClassPathScanImplementationLookup(final Collection<ClassPathScanImplementationContributor> contributors) {
+ private final ConsoleProperties props;
+
+ public ClassPathScanImplementationLookup(final Collection<ClassPathScanImplementationContributor> contributors,
+ final ConsoleProperties props) {
this.contributors = contributors;
+ this.props = props;
}
protected ClassPathScanningCandidateComponentProvider scanner() {
@@ -180,7 +185,10 @@ public class ClassPathScanImplementationLookup {
}
} else if (BasePage.class.isAssignableFrom(clazz)) {
if (clazz.isAnnotationPresent(IdMPage.class)) {
- idmPages.add((Class<? extends BasePage>) clazz);
+ if (!clazz.getName().endsWith("Topology")
+ || (clazz.getName().equals(props.getPage().get("topology").getName()))) {
+ idmPages.add((Class<? extends BasePage>) clazz);
+ }
} else if (clazz.isAnnotationPresent(AMPage.class)) {
amPages.add((Class<? extends BasePage>) clazz);
} else {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
index 27e2eaf..8d6ec33 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
@@ -145,6 +145,63 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
addInnerObject(templates);
}
+ protected SchedTaskDirectoryPanel(
+ final BaseModal<?> baseModal,
+ final MultilevelPanel multiLevelPanelRef,
+ final TaskType taskType,
+ final Class<T> reference,
+ final PageReference pageRef,
+ final boolean wizardInModal) {
+
+ super(baseModal, multiLevelPanelRef, pageRef, wizardInModal);
+ this.taskType = taskType;
+ this.reference = reference;
+
+ try {
+ schedTaskTO = reference.getDeclaredConstructor().newInstance();
+ } catch (Exception e) {
+ LOG.error("Failure instantiating task", e);
+ }
+
+ this.addNewItemPanelBuilder(new SchedTaskWizardBuilder<>(taskType, schedTaskTO, pageRef), true);
+
+ MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.TASK_CREATE);
+
+ enableUtilityButton();
+ setFooterVisibility(false);
+
+ initResultTable();
+
+ container.add(new IndicatorAjaxTimerBehavior(Duration.of(10, ChronoUnit.SECONDS)) {
+
+ private static final long serialVersionUID = -4661303265651934868L;
+
+ @Override
+ protected void onTimer(final AjaxRequestTarget target) {
+ container.modelChanged();
+ target.add(container);
+ }
+ });
+
+ startAt = new TaskStartAtTogglePanel(container, pageRef);
+ addInnerObject(startAt);
+
+ templates = new TemplatesTogglePanel(getActualId(), this, pageRef) {
+
+ private static final long serialVersionUID = -8765794727538618705L;
+
+ @Override
+ protected Serializable onApplyInternal(
+ final TemplatableTO targetObject, final String type, final AnyTO anyTO) {
+
+ targetObject.getTemplates().put(type, anyTO);
+ TaskRestClient.update(taskType, SchedTaskTO.class.cast(targetObject));
+ return targetObject;
+ }
+ };
+ addInnerObject(templates);
+ }
+
protected List<IColumn<T, String>> getFieldColumns() {
List<IColumn<T, String>> columns = new ArrayList<>();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
index 10eed40..b19b0ef 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
@@ -52,4 +52,25 @@ public class SchedTasks extends AbstractTasks {
}
});
}
+
+ public <T extends AnyTO> SchedTasks(final BaseModal<?> baseModal, final PageReference pageReference,
+ final boolean wizardInModal, final String id) {
+ super(id);
+
+ final MultilevelPanel mlp = new MultilevelPanel("tasks");
+ add(mlp);
+
+ mlp.setFirstLevel(new SchedTaskDirectoryPanel<>(
+ baseModal, mlp, TaskType.SCHEDULED, SchedTaskTO.class, pageReference, wizardInModal) {
+
+ private static final long serialVersionUID = -2195387360323687302L;
+
+ @Override
+ protected void viewTask(final SchedTaskTO taskTO, final AjaxRequestTarget target) {
+ mlp.next(
+ new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
+ new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
+ }
+ });
+ }
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
index 1486ab6..26d20db 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
@@ -59,6 +59,26 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
setShowResultPage(false);
}
+ protected TaskDirectoryPanel(
+ final BaseModal<?> baseModal, final MultilevelPanel multiLevelPanelRef, final PageReference pageRef,
+ final boolean wizardInModal) {
+ super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, wizardInModal);
+ this.baseModal = baseModal;
+ this.multiLevelPanelRef = multiLevelPanelRef;
+ restClient = new TaskRestClient();
+ setShowResultPage(false);
+ }
+
+ protected TaskDirectoryPanel(
+ final BaseModal<?> baseModal, final MultilevelPanel multiLevelPanelRef, final PageReference pageRef,
+ final String id) {
+ super(id, pageRef, false);
+ this.baseModal = baseModal;
+ this.multiLevelPanelRef = multiLevelPanelRef;
+ restClient = new TaskRestClient();
+ setShowResultPage(false);
+ }
+
@Override
protected void resultTableCustomChanges(final AjaxDataTablePanel.Builder<T, String> resultTableBuilder) {
resultTableBuilder.setMultiLevelPanel(baseModal, multiLevelPanelRef);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index 762ffe7..0c15ac9 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -52,6 +52,8 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
REMOVE_SYNC_TOKEN("update"),
CLONE("create"),
CREATE("create"),
+ CREATE_CONNECTOR("create"),
+ CREATE_RESOURCE("create"),
TEMPLATE("read"),
EDIT("read"),
TYPE_EXTENSIONS("read"),
@@ -95,6 +97,7 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
PROVISION_MEMBERS("update"),
RECONCILIATION_PUSH("update"),
RECONCILIATION_PULL("update"),
+ RECONCILIATION_RESOURCE("update"),
MANAGE_RESOURCES("update"),
MANAGE_ACCOUNTS("update"),
MERGE_ACCOUNTS("update"),
@@ -102,6 +105,8 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
MANAGE_GROUPS("update"),
PROPAGATION_TASKS("read"),
NOTIFICATION_TASKS("read"),
+ PULL_TASKS("read"),
+ PUSH_TASKS("read"),
ZOOM_IN("zoomin"),
ZOOM_OUT("zoomout"),
VIEW_EXECUTIONS("read"),
@@ -109,7 +114,8 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
MANAGE_APPROVAL("edit"),
EDIT_APPROVAL("edit"),
VIEW_AUDIT_HISTORY("read"),
- EXTERNAL_EDITOR("externalEditor");
+ EXTERNAL_EDITOR("externalEditor"),
+ EXPLORE_RESOURCE("search");
private final String actionId;
@@ -174,4 +180,3 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
return this;
}
}
-
diff --git a/client/idrepo/console/src/main/resources/console.properties b/client/idrepo/console/src/main/resources/console.properties
index 41407e7..51a37c6 100644
--- a/client/idrepo/console/src/main/resources/console.properties
+++ b/client/idrepo/console/src/main/resources/console.properties
@@ -56,6 +56,7 @@ console.page.types=org.apache.syncope.client.console.pages.Types
console.page.policies=org.apache.syncope.client.console.pages.Policies
console.page.notifications=org.apache.syncope.client.console.pages.Notifications
console.page.parameters=org.apache.syncope.client.console.pages.Parameters
+console.page.topology=org.apache.syncope.client.console.topology.Topology
console.default-any-panel-class=org.apache.syncope.client.console.panels.AnyPanel
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties
index b655b41..80667bb 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties
@@ -38,6 +38,14 @@ create.class=fa fa-plus
create.title=create
create.alt=create icon
+create_connector.class=glyphicon glyphicon-plus
+create_connector.title=create connector
+create_connector.alt=create icon
+
+create_resource.class=glyphicon glyphicon-plus
+create_resource.title=create resource
+create_resource.alt=create icon
+
template.class=fa fa-list-alt
template.title=template
template.alt=template icon
@@ -241,6 +249,10 @@ reconciliation_pull.class=fa fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+reconciliation_resource.class=fa fa-chevron-circle-left
+reconciliation_resource.title=reconciliation
+reconciliation_resource.alt=reconciliation resource icon
+
manage_resources.class=fa fa-sitemap
manage_resources.title=manage resources
manage_resources.alt=manage resources icon
@@ -261,6 +273,14 @@ notification_tasks.class=fas fa-envelope
notification_tasks.title=notification tasks
notification_tasks.alt=notification tasks icon
+pull_tasks.class=fa fa-chevron-circle-left
+pull_tasks.title=pull tasks
+pull_tasks.alt=pull tasks icon
+
+push_tasks.class=fa fa-chevron-circle-right
+push_tasks.title=push tasks
+push_tasks.alt=push tasks icon
+
zoom_in.class=fa fa-search-plus
zoom_in.title=zoom-in
zoom_in.alt=zoom-in icon
@@ -285,3 +305,6 @@ merge_accounts.class=fa fa-compress-alt
merge_accounts.title=merge accounts
merge_accounts.alt=merge accounts icon
+explore_resource.class=fa fa-eye
+explore_resource.title=explore resource
+explore_resource.alt=explore resource icon
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_fr_CA.properties
index 5b4c348..61b6b36 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_fr_CA.properties
@@ -32,6 +32,15 @@ clone.alt=ic\u00f4ne cl\u00f4ner
create.class=fa fa-plus
create.title=cr\u00e9er
create.alt=ic\u00f4ne cr\u00e9er
+
+create_connector.class=glyphicon glyphicon-plus
+create_connector.title=cr\u00e9er un connecteur
+create_connector.alt=ic\u00f4ne cr\u00e9er
+
+create_resource.class=glyphicon glyphicon-plus
+create_resource.title=cr\u00e9er une ressource
+create_resource.alt=ic\u00f4ne cr\u00e9er
+
template.class=fa fa-list-alt
template.title=mod\u00e8le
template.alt=ic\u00f4ne mod\u00e8le
@@ -185,6 +194,11 @@ reconciliation_push.alt=ic\u00f4ne push r\u00e9conciliation
reconciliation_pull.class=fa fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=ic\u00f4ne pull r\u00e9conciliation
+
+reconciliation_resource.class=fa fa-chevron-circle-left
+reconciliation_resource.title=r\u00e9conciliation
+reconciliation_resource.alt=ic\u00f4ne de ressource de r\u00e9conciliation
+
manage_resources.class=fa fa-sitemap
manage_resources.title=g\u00e9rer ressources
manage_resources.alt=ic\u00f4ne g\u00e9rer ressources
@@ -200,6 +214,15 @@ propagation_tasks.alt=ic\u00f4ne t\u00e2ches de propagation
notification_tasks.class=fas fa-envelope
notification_tasks.title=t\u00e2ches de notification
notification_tasks.alt=ic\u00f4ne t\u00e2ches de notification
+
+pull_tasks.class=fa fa-chevron-circle-left
+pull_tasks.title=t\u00c2ches d\u0027extraction
+pull_tasks.alt=ic\u00f4ne t\u00c2ches d\u0027extraction
+
+push_tasks.class=fa fa-chevron-circle-right
+push_tasks.title=pousser des t\u00c2ches
+push_tasks.alt=ic\u00f4ne pousser des t\u00c2ches
+
zoom_in.class=fa fa-search-plus
zoom_in.title=zoom-in
zoom_in.alt=ic\u00f4ne zoom-in
@@ -218,3 +241,7 @@ external_editor.alt=external editor icon
merge_accounts.class=fa fa-compress-alt
merge_accounts.title=merge accounts
merge_accounts.alt=merge accounts icon
+
+explore_resource.class=fa fa-eye
+explore_resource.title=explorer la ressource
+explore_resource.alt=ic\u00f4ne explorer la ressource
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties
index 4800f58..e3f3524 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties
@@ -38,6 +38,14 @@ create.class=fa fa-plus
create.title=crea
create.alt=create icon
+create_connector.class=glyphicon glyphicon-plus
+create_connector.title=crea connettore
+create_connector.alt=create icon
+
+create_resource.class=glyphicon glyphicon-plus
+create_resource.title=crea risorsa
+create_resource.alt=create icon
+
template.class=fa fa-list-alt
template.title=modello
template.alt=template icon
@@ -250,6 +258,14 @@ notification_tasks.class=fas fa-envelope
notification_tasks.title=task di notifica
notification_tasks.alt=notification tasks icon
+pull_tasks.class=fa fa-chevron-circle-left
+pull_tasks.title=pull tasks
+pull_tasks.alt=pull tasks icon
+
+push_tasks.class=fa fa-chevron-circle-right
+push_tasks.title=push tasks
+push_tasks.alt=push tasks icon
+
zoom_in.class=fa fa-search-plus
zoom_in.title=ingrandisci
zoom_in.alt=zoom-in icon
@@ -265,6 +281,10 @@ reconciliation_pull.class=fa fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+reconciliation_resource.class=fa fa-chevron-circle-left
+reconciliation_resource.title=riconciliazione
+reconciliation_resource.alt=reconciliation resource icon
+
manage_accounts.class=fas fa-users
manage_accounts.title=gestisci account
manage_accounts.alt=manage accounts icon
@@ -284,3 +304,7 @@ external_editor.alt=external editor icon
merge_accounts.class=fa fa-compress-alt
merge_accounts.title=merge accounts
merge_accounts.alt=merge accounts icon
+
+explore_resource.class=fa fa-eye
+explore_resource.title=esplora risorsa
+explore_resource.alt=explore resource icon
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties
index e0ec802..3d05e7b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties
@@ -38,6 +38,14 @@ create.class=fa fa-plus
create.title=\u4f5c\u6210
create.alt=\u4f5c\u6210
+create_connector.class=glyphicon glyphicon-plus
+create_connector.title= \u30b3\u30cd\u30af\u30bf\u3092\u4f5c\u6210\u3059\u308b
+create_connector.alt=\u4f5c\u6210
+
+create_resource.class=glyphicon glyphicon-plus
+create_resource.title= \u30ea\u30bd\u30fc\u30b9\u3092\u4f5c\u6210\u3059\u308b
+create_resource.alt=\u4f5c\u6210
+
template.class=fa fa-list-alt
template.title=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8
template.alt=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8
@@ -250,6 +258,14 @@ notification_tasks.class=fas fa-envelope
notification_tasks.title=\u901a\u77e5\u30bf\u30b9\u30af
notification_tasks.alt=\u901a\u77e5\u30bf\u30b9\u30af
+pull_tasks.class=fa fa-chevron-circle-left
+pull_tasks.title=\u30bf\u30b9\u30af\u3092\u30d7\u30eb\u3059\u308b
+pull_tasks.alt=\u30bf\u30b9\u30af\u30a2\u30a4\u30b3\u30f3\u3092\u5f15\u3063\u5f35\u308b
+
+push_tasks.class=fa fa-chevron-circle-right
+push_tasks.title=\u30d7\u30c3\u30b7\u30e5\u30bf\u30b9\u30af
+push_tasks.alt=\u30bf\u30b9\u30af\u30a2\u30a4\u30b3\u30f3\u3092\u62bc\u3059
+
zoom_in.class=fa fa-search-plus
zoom_in.title=\u30ba\u30fc\u30e0\u30a4\u30f3
zoom_in.alt=\u30ba\u30fc\u30e0\u30a4\u30f3
@@ -266,7 +282,11 @@ reconciliation_pull.class=fa fa-chevron-circle-left
reconciliation_pull.title=\u30d7\u30eb
reconciliation_pull.alt=\u7167\u5408\u30d7\u30eb icon
-manage_accounts.class=fas fa-users
+reconciliation_resource.class=fa fa-chevron-circle-left
+reconciliation_resource.title=\u548c\u89e3
+reconciliation_resource.alt=\u8abf\u6574\u30ea\u30bd\u30fc\u30b9\u30a2\u30a4\u30b3\u30f3
+
+manage_accounts.class=fa fa-users
manage_accounts.title=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7ba1\u7406\u3059\u308b
manage_accounts.alt=\u30a2\u30ab\u30a6\u30f3\u30c8\u7ba1\u7406\u30a2\u30a4\u30b3\u30f3
@@ -285,3 +305,7 @@ external_editor.alt=external editor icon
merge_accounts.class=fa fa-compress-alt
merge_accounts.title=merge accounts
merge_accounts.alt=merge accounts icon
+
+explore_resource.class=fa fa-eye
+explore_resource.title=\u30ea\u30bd\u30fc\u30b9\u3092\u63a2\u7d22\u3059\u308b
+explore_resource.alt=\u30ea\u30bd\u30fc\u30b9\u30a2\u30a4\u30b3\u30f3\u3092\u63a2\u3059
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties
index 6002660..b7c4993 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties
@@ -38,6 +38,14 @@ create.class=fa fa-plus
create.title=create
create.alt=create icon
+create_connector.class=glyphicon glyphicon-plus
+create_connector.title=criar conector
+create_connector.alt=criar \u00edcone
+
+create_resource.class=glyphicon glyphicon-plus
+create_resource.title=criar recurso
+create_resource.alt=criar \u00edcone
+
template.class=fa fa-list-alt
template.title=template
template.alt=template icon
@@ -241,6 +249,10 @@ reconciliation_pull.class=fa fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+reconciliation_resource.class=fa fa-chevron-circle-left
+reconciliation_resource.title=reconcilia\u00e7\u00c3o
+reconciliation_resource.alt=\u00edcone de recurso de reconcilia\u00e7\u00c3o
+
manage_resources.class=fa fa-sitemap
manage_resources.title=manage resources
manage_resources.alt=manage resources icon
@@ -261,6 +273,14 @@ notification_tasks.class=fas fa-envelope
notification_tasks.title=notification tasks
notification_tasks.alt=notification tasks icon
+pull_tasks.class=fa fa-chevron-circle-left
+pull_tasks.title=puxar tarefas
+pull_tasks.alt=\u00edcone de puxar tarefas
+
+push_tasks.class=fa fa-chevron-circle-right
+push_tasks.title=tarefas push
+push_tasks.alt=\u00edcone de tarefas push
+
zoom_in.class=fa fa-search-plus
zoom_in.title=zoom-in
zoom_in.alt=zoom-in icon
@@ -289,3 +309,7 @@ external_editor.alt=external editor icon
merge_accounts.class=fa fa-compress-alt
merge_accounts.title=merge accounts
merge_accounts.alt=merge accounts icon
+
+explore_resource.class=fa fa-eye
+explore_resource.title=explorar recurso
+explore_resource.alt=\u00edcone de explorar recurso
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties
index 050558b..e215cd7 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties
@@ -38,6 +38,14 @@ create.class=fa fa-plus
create.title=create
create.alt=create icon
+create_connector.class=glyphicon glyphicon-plus
+create_connector.title=\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u0020\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0435\u043b\u044c
+create_connector.alt=\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u0020\u0437\u043d\u0430\u0447\u043e\u043a
+
+create_resource.class=glyphicon glyphicon-plus
+create_resource.title=\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+create_resource.alt=\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u0020\u0437\u043d\u0430\u0447\u043e\u043a
+
template.class=fa fa-list-alt
template.title=template
template.alt=template icon
@@ -250,6 +258,14 @@ notification_tasks.class=fas fa-envelope
notification_tasks.title=notification tasks
notification_tasks.alt=notification tasks icon
+pull_tasks.class=fa fa-chevron-circle-left
+pull_tasks.title=\u0442\u044f\u043d\u0443\u0442\u044c\u0020\u0437\u0430\u0434\u0430\u0447\u0438
+pull_tasks.alt=\u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c\u0020\u0437\u043d\u0430\u0447\u043e\u043a\u0020\u0437\u0430\u0434\u0430\u0447\u0438
+
+push_tasks.class=fa fa-chevron-circle-right
+push_tasks.title=push-\u0437\u0430\u0434\u0430\u0447\u0438
+push_tasks.alt=\u0437\u043d\u0430\u0447\u043e\u043a push-\u0437\u0430\u0434\u0430\u0447\u0438
+
zoom_in.class=fa fa-search-plus
zoom_in.title=zoom-in
zoom_in.alt=zoom-in icon
@@ -266,7 +282,11 @@ reconciliation_pull.class=fa fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
-manage_accounts.class=fas fa-users
+reconciliation_resource.class=fa fa-chevron-circle-left
+reconciliation_resource.title=\u043f\u0440\u0438\u043c\u0438\u0440\u0435\u043d\u0438\u0435
+reconciliation_resource.alt=\u0437\u043d\u0430\u0447\u043e\u043a\u0020\u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0020\u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f
+
+manage_accounts.class=fa fa-users
manage_accounts.title=manage accounts
manage_accounts.alt=manage accounts icon
@@ -285,3 +305,7 @@ external_editor.alt=external editor icon
merge_accounts.class=fa fa-compress-alt
merge_accounts.title=merge accounts
merge_accounts.alt=merge accounts icon
+
+explore_resource.class=fa fa-eye
+explore_resource.title=\u0438\u0437\u0443\u0447\u0438\u0442\u044c\u0020\u0440\u0435\u0441\u0443\u0440\u0441
+explore_resource.alt=\u0438\u0437\u0443\u0447\u0438\u0442\u044c\u0020\u0437\u043d\u0430\u0447\u043e\u043a\u0020\u0440\u0435\u0441\u0443\u0440\u0441\u0430
diff --git a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
index f33eb5f..71892b7 100644
--- a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
+++ b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
@@ -137,7 +137,8 @@ public abstract class AbstractTest {
@Bean
public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
- ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(Set.of());
+ ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(Set.of(),
+ consoleProperties());
lookup.load();
return lookup;
}
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
index 985da5c..708b81c 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
@@ -39,6 +39,7 @@ import org.apache.syncope.client.console.commons.PolicyTabProvider;
import org.apache.syncope.client.console.commons.PreviewUtils;
import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
import org.apache.syncope.client.console.pages.Login;
+import org.apache.syncope.client.console.topology.Topology;
import org.apache.syncope.client.console.wizards.any.UserFormFinalizerUtils;
import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
import org.apache.syncope.client.ui.commons.ApplicationContextProvider;
@@ -71,6 +72,7 @@ public abstract class AbstractConsoleITCase extends AbstractUIITCase {
consoleProperties.setAnonymousKey(ANONYMOUS_KEY);
consoleProperties.setCsrf(false);
+ consoleProperties.getPage().put("topology", Topology.class);
return consoleProperties;
}
@@ -102,7 +104,8 @@ public abstract class AbstractConsoleITCase extends AbstractUIITCase {
@Bean
public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
- ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(Set.of());
+ ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(Set.of(),
+ consoleProperties());
lookup.load();
return lookup;
}