You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by sk...@apache.org on 2019/11/04 15:38:18 UTC
[syncope] branch master updated: [SYNCOPE-957] Added new section in
Admin Console for the Multiaccount feature
This is an automated email from the ASF dual-hosted git repository.
skylark17 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 dd1ff82 [SYNCOPE-957] Added new section in Admin Console for the Multiaccount feature
dd1ff82 is described below
commit dd1ff8243199cb90ab9708ca371a98542fa1265c
Author: skylark17 <ma...@tirasa.net>
AuthorDate: Mon Nov 4 16:37:53 2019 +0100
[SYNCOPE-957] Added new section in Admin Console for the Multiaccount feature
---
...DirectoryPanelAditionalActionLinksProvider.java | 21 +
.../console/panels/ConnObjectListViewPanel.java | 15 +-
.../console/panels/LinkedAccountModalPanel.java | 232 +++++++++++
.../client/console/rest/ResourceRestClient.java | 19 +-
.../wizards/any/LinkedAccountCredentialsPanel.java | 125 ++++++
.../wizards/any/LinkedAccountDetailsPanel.java | 188 +++++++++
.../wizards/any/LinkedAccountPlainAttrsPanel.java | 255 ++++++++++++
.../wizards/any/LinkedAccountPrivilegesPanel.java | 66 +++
.../wizards/any/LinkedAccountWizardBuilder.java | 131 ++++++
.../resources/ResourceConnCapabilitiesPanel.html | 2 +-
.../syncope/client/ui/commons/Constants.java | 2 +
.../markup/html/form/AbstractFieldPanel.java | 2 +
.../markup/html/form/AbstractMultiPanel.java | 5 +
.../commons/markup/html/form/AjaxPalettePanel.java | 6 +
.../markup/html/form/AjaxSpinnerFieldPanel.java | 15 +-
.../ui/commons/wizards/AjaxWizardBuilder.java | 4 +-
.../ui/commons/wizards/any/EntityWrapper.java | 35 ++
.../commons/LinkedAccountPlainAttrProperty.java | 100 +++++
.../client/console/panels/ListViewPanel.java | 13 +-
.../wicket/markup/html/form/ActionLink.java | 1 +
.../wicket/markup/html/form/BinaryFieldPanel.java | 7 +
.../client/console/wizards/any/AbstractAttrs.java | 140 +------
.../wizards/any/AbstractAttrsWizardStep.java | 453 +++++++++++++++++++++
.../client/console/wizards/any/PlainAttrs.java | 280 +------------
.../wizards/any/TypeExtensionWizardBuilder.java | 2 +-
.../LinkedAccountModalPanel.html} | 6 +-
...operties => LinkedAccountModalPanel.properties} | 8 +-
...rties => LinkedAccountModalPanel_it.properties} | 8 +-
...rties => LinkedAccountModalPanel_ja.properties} | 8 +-
...es => LinkedAccountModalPanel_pt_BR.properties} | 8 +-
...rties => LinkedAccountModalPanel_ru.properties} | 8 +-
.../console/panels/UserDirectoryPanel.properties | 1 +
.../panels/UserDirectoryPanel_it.properties | 1 +
.../panels/UserDirectoryPanel_ja.properties | 1 +
.../panels/UserDirectoryPanel_pt_BR.properties | 1 +
.../panels/UserDirectoryPanel_ru.properties | 1 +
.../markup/html/form/ActionsPanel.properties | 4 +
.../markup/html/form/ActionsPanel_it.properties | 4 +
.../markup/html/form/ActionsPanel_ja.properties | 4 +
.../markup/html/form/ActionsPanel_pt_BR.properties | 4 +
.../markup/html/form/ActionsPanel_ru.properties | 4 +
.../client/console/wizards/any/AbstractAttrs.html | 9 +-
...s.html => AbstractAttrsWizardStep$Schemas.html} | 9 +-
...ractAttrs.html => AbstractAttrsWizardStep.html} | 0
.../any/LinkedAccountCredentialsPanel.html} | 18 +-
.../any/LinkedAccountCredentialsPanel.properties} | 6 +-
.../LinkedAccountCredentialsPanel_it.properties} | 6 +-
.../LinkedAccountCredentialsPanel_ja.properties} | 6 +-
...LinkedAccountCredentialsPanel_pt_BR.properties} | 6 +-
.../LinkedAccountCredentialsPanel_ru.properties} | 6 +-
.../wizards/any/LinkedAccountDetailsPanel.html} | 18 +-
.../any/LinkedAccountDetailsPanel.properties} | 6 +-
.../any/LinkedAccountDetailsPanel_it.properties} | 6 +-
.../any/LinkedAccountDetailsPanel_ja.properties} | 6 +-
.../LinkedAccountDetailsPanel_pt_BR.properties} | 6 +-
.../any/LinkedAccountDetailsPanel_ru.properties} | 6 +-
...ttrs.html => LinkedAccountPlainAttrsPanel.html} | 9 +-
.../wizards/any/LinkedAccountPrivilegesPanel.html} | 15 +-
.../any/LinkedAccountPrivilegesPanel.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_it.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_ja.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_pt_BR.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_ru.properties} | 4 +-
.../apache/syncope/fit/console/PoliciesITCase.java | 4 +-
.../apache/syncope/fit/console/UsersITCase.java | 2 +-
65 files changed, 1846 insertions(+), 508 deletions(-)
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
index fd66565..11df282 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.commons;
import java.util.ArrayList;
import java.util.List;
+import org.apache.syncope.client.console.panels.LinkedAccountModalPanel;
import org.apache.syncope.client.console.status.AnyStatusModal;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.Action;
@@ -106,6 +107,26 @@ public class IdMAnyDirectoryPanelAditionalActionLinksProvider
manageResources.setRealms(realm, modelObject.getDynRealms());
actions.add(manageResources);
+ Action<UserTO> manageAccounts = new Action<>(new ActionLink<UserTO>() {
+
+ private static final long serialVersionUID = 8011039414597736111L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
+ modal.setFooterVisible(false);
+ target.add(modal.setContent(new LinkedAccountModalPanel(modal, modelObject, pageRef)));
+
+ modal.header(new Model<>(header));
+
+ modal.show(true);
+ }
+ }, ActionLink.ActionType.MANAGE_ACCOUNTS);
+ manageAccounts.setEntitlements(
+ String.format("%s,%s", IdRepoEntitlement.USER_READ, IdRepoEntitlement.USER_UPDATE));
+ manageAccounts.setOnConfirm(false);
+ manageAccounts.setRealms(realm, modelObject.getDynRealms());
+ actions.add(manageAccounts);
+
return actions;
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
index a996c7e..33462a3 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
@@ -53,6 +53,7 @@ import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.syncope.common.lib.types.MatchType;
+import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
import org.apache.syncope.common.rest.api.beans.ReconQuery;
import org.apache.wicket.Component;
import org.apache.wicket.PageReference;
@@ -152,7 +153,8 @@ public abstract class ConnObjectListViewPanel extends Panel {
if (StringUtils.equals(key, STATUS)) {
ReconStatus status = ReconciliationRestClient.status(
new ReconQuery.Builder(anyType, resource.getKey()).
- connObjectKeyValue(bean.getAttr(ConnIdSpecialName.UID).get().getValues().get(0)).build());
+ connObjectKeyValue(bean.getAttr(ConnIdSpecialName.UID).get().getValues().get(0)).
+ build());
return status.getOnSyncope() == null
? StatusUtils.getLabel("field", "notfound icon", "Not found", Constants.NOT_FOUND_ICON)
@@ -283,12 +285,13 @@ public abstract class ConnObjectListViewPanel extends Panel {
final String cookie,
final String fiql) {
- Pair<String, List<ConnObjectTO>> items = ResourceRestClient.listConnObjects(resource,
+ Pair<String, List<ConnObjectTO>> items = new ResourceRestClient().searchConnObjects(resource,
anyType,
- SIZE,
- cookie,
- new SortParam<>(ConnIdSpecialName.UID, true),
- fiql);
+ new ConnObjectTOQuery.Builder().
+ size(SIZE).
+ pagedResultsCookie(cookie).
+ fiql(fiql),
+ new SortParam<>(ConnIdSpecialName.UID, true));
nextPageCookie = items.getLeft();
return items.getRight();
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
new file mode 100644
index 0000000..a9680e3
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
@@ -0,0 +1,232 @@
+/*
+ * 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 static org.apache.syncope.client.console.panels.AbstractModalPanel.LOG;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+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.AnyTypeRestClient;
+import org.apache.syncope.client.console.rest.UserRestClient;
+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.ActionLinksTogglePanel;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.any.LinkedAccountWizardBuilder;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.request.LinkedAccountUR;
+import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.StringResourceModel;
+
+public class LinkedAccountModalPanel extends AbstractModalPanel<Serializable> {
+
+ private static final long serialVersionUID = -4603032036433309900L;
+
+ private final LinkedAccountWizardBuilder wizard;
+
+ private final WizardMgtPanel<LinkedAccountTO> list;
+
+ private final AjaxLink<LinkedAccountTO> addAjaxLink;
+
+ protected ActionLinksTogglePanel<LinkedAccountTO> actionTogglePanel;
+
+ private UserRestClient userRestClient = new UserRestClient();
+
+ private final List<LinkedAccountTO> linkedAccountTOs;
+
+ @SuppressWarnings("unchecked")
+ public LinkedAccountModalPanel(
+ final BaseModal<?> modal,
+ final UserTO userTO,
+ final PageReference pageRef) {
+
+ super((BaseModal<Serializable>) modal, pageRef);
+
+ UserTO readUserTO = userRestClient.read(userTO.getKey());
+
+ setOutputMarkupId(true);
+
+ actionTogglePanel = new ActionLinksTogglePanel<>("toggle", pageRef);
+ add(actionTogglePanel);
+
+ wizard = new LinkedAccountWizardBuilder(readUserTO.getKey(), pageRef);
+
+ final ListViewPanel.Builder<LinkedAccountTO> builder = new ListViewPanel.Builder<LinkedAccountTO>(
+ LinkedAccountTO.class, pageRef) {
+
+ private static final long serialVersionUID = -5322423525438435153L;
+
+ @Override
+ protected LinkedAccountTO getActualItem(
+ final LinkedAccountTO item, final List<LinkedAccountTO> list) {
+
+ return item == null
+ ? null
+ : list.stream().filter(
+ in -> ((item.getKey() == null && in.getKey() == null)
+ || (in.getKey() != null && in.getKey().
+ equals(item.getKey())))).findAny().orElse(null);
+ }
+
+ @Override
+ protected void customActionCallback(final AjaxRequestTarget target) {
+ // change modal footer visibility
+ send(LinkedAccountModalPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
+ }
+
+ @Override
+ protected void customActionOnCancelCallback(final AjaxRequestTarget target) {
+ // change modal footer visibility
+ send(LinkedAccountModalPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void customActionOnFinishCallback(final AjaxRequestTarget target) {
+ checkAddButton();
+
+ linkedAccountTOs.clear();
+ linkedAccountTOs.addAll(userRestClient.read(userTO.getKey()).getLinkedAccounts());
+ sortLinkedAccounts();
+
+ ListViewPanel.class.cast(list).refreshList(linkedAccountTOs);
+
+ // change modal footer visibility
+ send(LinkedAccountModalPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
+ }
+
+ @Override
+ protected ActionLinksTogglePanel<LinkedAccountTO> getTogglePanel() {
+ return actionTogglePanel;
+ }
+ };
+
+ linkedAccountTOs = new ArrayList<>(readUserTO.getLinkedAccounts());
+ sortLinkedAccounts();
+
+ builder.setItems(linkedAccountTOs);
+ builder.includes("connObjectKeyValue", "resource", "suspended");
+ builder.setReuseItem(false);
+ builder.withChecks(ListViewPanel.CheckAvailability.NONE);
+
+ builder.addAction(new ActionLink<LinkedAccountTO>() {
+
+ private static final long serialVersionUID = 2555747430358755813L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final LinkedAccountTO linkedAccountTO) {
+ try {
+ send(LinkedAccountModalPanel.this, Broadcast.DEPTH,
+ new AjaxWizard.NewItemActionEvent<>(linkedAccountTO, 1, target).setResourceModel(
+ new StringResourceModel("inner.edit.linkedAccount",
+ LinkedAccountModalPanel.this,
+ Model.of(linkedAccountTO))));
+ } catch (SyncopeClientException e) {
+ LOG.error("While contacting linked account", e);
+ SyncopeConsoleSession.get().error(
+ StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+
+ send(LinkedAccountModalPanel.this, Broadcast.BREADTH,
+ new ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
+ }
+ }, ActionLink.ActionType.EDIT, IdRepoEntitlement.USER_READ).
+ addAction(new ActionLink<LinkedAccountTO>() {
+
+ private static final long serialVersionUID = 2555747430358755813L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final LinkedAccountTO linkedAccountTO) {
+ try {
+ LinkedAccountUR linkedAccountPatch = new LinkedAccountUR.Builder().
+ operation(PatchOperation.DELETE).
+ linkedAccountTO(linkedAccountTO).build();
+ linkedAccountPatch.setLinkedAccountTO(linkedAccountTO);
+ UserUR patch = new UserUR();
+ patch.setKey(readUserTO.getKey());
+ patch.getLinkedAccounts().add(linkedAccountPatch);
+ userRestClient.update(userRestClient.read(userTO.getKey()).getETagValue(), patch);
+ linkedAccountTOs.remove(linkedAccountTO);
+
+ SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ LOG.error("While removing linked account {}", linkedAccountTO.getKey(), e);
+ SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+ ? e.getClass().getName() : e.getMessage());
+ }
+
+ checkAddButton();
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ send(LinkedAccountModalPanel.this, Broadcast.DEPTH, new ListViewPanel.ListViewReload<>(target));
+ }
+ }, ActionLink.ActionType.DELETE, IdRepoEntitlement.USER_UPDATE, true);
+
+ builder.addNewItemPanelBuilder(wizard);
+
+ list = builder.build("linkedAccountsList");
+ list.setOutputMarkupId(true);
+ list.setReadOnly(!SyncopeConsoleSession.get().owns(IdRepoEntitlement.USER_UPDATE));
+
+ addAjaxLink = new AjaxLink<LinkedAccountTO>("add") {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ send(LinkedAccountModalPanel.this, Broadcast.BREADTH,
+ new ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
+
+ // this opens the wizard (set above) in CREATE mode
+ send(list, Broadcast.DEPTH, new AjaxWizard.NewItemActionEvent<>(new LinkedAccountTO(), target).
+ setResourceModel(new StringResourceModel("inner.create.linkedAccount",
+ LinkedAccountModalPanel.this)));
+ }
+ };
+ list.addOrReplaceInnerObject(addAjaxLink);
+ add(list);
+ }
+
+ private void sortLinkedAccounts() {
+ Collections.sort(linkedAccountTOs,
+ (o1, o2) -> AnyTypeRestClient.KEY_COMPARATOR.compare(
+ o1.getConnObjectKeyValue(), o2.getConnObjectKeyValue()));
+ }
+
+ private void checkAddButton() {
+ addAjaxLink.setVisible(SyncopeConsoleSession.get().owns(IdRepoEntitlement.USER_UPDATE));
+ }
+
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index 4174391..92f79f3 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -55,26 +55,21 @@ public class ResourceRestClient extends BaseRestClient {
return getService(ResourceService.class).readConnObject(resource, anyTypeKey, anyKey);
}
- public static Pair<String, List<ConnObjectTO>> listConnObjects(
+ public Pair<String, List<ConnObjectTO>> searchConnObjects(
final String resource,
final String anyTypeKey,
- final int size,
- final String pagedResultCookie,
- final SortParam<String> sort,
- final String fiql) {
-
- ConnObjectTOQuery.Builder builder = new ConnObjectTOQuery.Builder().
- pagedResultsCookie(pagedResultCookie).
- size(size).
- orderBy(toOrderBy(sort)).
- fiql(fiql);
+ final ConnObjectTOQuery.Builder queryBuilder,
+ final SortParam<String> sortParam) {
final List<ConnObjectTO> result = new ArrayList<>();
String nextPageResultCookie = null;
PagedConnObjectTOResult list;
try {
- list = getService(ResourceService.class).searchConnObjects(resource, anyTypeKey, builder.build());
+ if (sortParam != null) {
+ queryBuilder.orderBy(toOrderBy(sortParam));
+ }
+ list = getService(ResourceService.class).searchConnObjects(resource, anyTypeKey, queryBuilder.build());
result.addAll(list.getResult());
nextPageResultCookie = list.getPagedResultsCookie();
} catch (Exception e) {
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
new file mode 100644
index 0000000..4ae7049
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
@@ -0,0 +1,125 @@
+/*
+ * 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.wizards.any;
+
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.client.console.commons.LinkedAccountPlainAttrProperty;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPasswordFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+
+public class LinkedAccountCredentialsPanel extends WizardStep {
+
+ private static final long serialVersionUID = 5116461957402341603L;
+
+ public LinkedAccountCredentialsPanel(final LinkedAccountTO linkedAccountTO) {
+ super();
+ setOutputMarkupId(true);
+
+ AjaxTextFieldPanel usernameField = new AjaxTextFieldPanel(
+ "username",
+ "username",
+ new PropertyModel<>(linkedAccountTO, "username"),
+ false);
+ usernameField.setOutputMarkupId(true);
+ FieldPanel.class.cast(usernameField).setReadOnly(true);
+ LinkedAccountPlainAttrProperty property = new LinkedAccountPlainAttrProperty();
+ property.setOverridable(false);
+ property.setSchema("username");
+ property.getValues().add(linkedAccountTO.getUsername());
+ usernameField.showExternAction(checkboxToggle(property, usernameField));
+ add(usernameField);
+
+ AjaxPasswordFieldPanel passwordField = new AjaxPasswordFieldPanel(
+ "password",
+ "password",
+ new PropertyModel<>(linkedAccountTO, "password"));
+ passwordField.setOutputMarkupId(true);
+ passwordField.setRequired(true);
+ passwordField.setMarkupId("password");
+ FieldPanel.class.cast(passwordField).setReadOnly(true);
+ property = new LinkedAccountPlainAttrProperty();
+ property.setOverridable(false);
+ property.setSchema("password");
+ property.getValues().add(linkedAccountTO.getPassword());
+ passwordField.showExternAction(checkboxToggle(property, passwordField));
+ ((PasswordTextField) passwordField.getField()).setResetPassword(true);
+ add(passwordField);
+ }
+
+ private FormComponent<?> checkboxToggle(
+ final LinkedAccountPlainAttrProperty property, final FieldPanel<?> panel) {
+
+ final BootstrapToggleConfig config = new BootstrapToggleConfig().
+ withOnStyle(BootstrapToggleConfig.Style.success).
+ withOffStyle(BootstrapToggleConfig.Style.danger).
+ withSize(BootstrapToggleConfig.Size.mini);
+
+ return new BootstrapToggle("externalAction", new PropertyModel<Boolean>(property, "overridable"), config) {
+
+ private static final long serialVersionUID = -875219845189261873L;
+
+ @Override
+ protected CheckBox newCheckBox(final String id, final IModel<Boolean> model) {
+ final CheckBox checkBox = super.newCheckBox(id, model);
+ checkBox.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ panel.setReadOnly(!model.getObject());
+ target.add(panel);
+ }
+ });
+ return checkBox;
+ }
+
+ @Override
+ protected IModel<String> getOnLabel() {
+ return Model.of("Override");
+ }
+
+ @Override
+ protected IModel<String> getOffLabel() {
+ return Model.of("Override?");
+ }
+
+ @Override
+ protected void onComponentTag(final ComponentTag tag) {
+ super.onComponentTag(tag);
+ tag.append("class", "overridable", " ");
+ }
+ };
+ }
+
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
new file mode 100644
index 0000000..cccf7b8
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
@@ -0,0 +1,188 @@
+/*
+ * 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.wizards.any;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.commons.ConnIdSpecialName;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.attributes.ThrottlingSettings;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LinkedAccountDetailsPanel extends WizardStep {
+
+ private static final long serialVersionUID = 1221037007528732347L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(LinkedAccountDetailsPanel.class);
+
+ private static final int SEARCH_SIZE = 20;
+
+ private final ResourceRestClient resourceRestClient = new ResourceRestClient();
+
+ private ArrayList<String> connObjectKeyFieldValues;
+
+ public LinkedAccountDetailsPanel(final LinkedAccountTO linkedAccountTO) {
+ super();
+ setOutputMarkupId(true);
+
+ AjaxDropDownChoicePanel<String> dropdownResourceField = new AjaxDropDownChoicePanel<>(
+ "resource",
+ "resource",
+ new PropertyModel<>(linkedAccountTO, "resource"),
+ false);
+ dropdownResourceField.setChoices(resourceRestClient.list().stream().
+ filter(resource -> resource.getProvision(AnyTypeKind.USER.name()).isPresent()
+ && resource.getProvision(AnyTypeKind.USER.name()).get().getMapping() != null
+ && !resource.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems().isEmpty()).
+ map(resource -> resource.getKey()).
+ collect(Collectors.toList()));
+ dropdownResourceField.setOutputMarkupId(true);
+ dropdownResourceField.addRequiredLabel();
+ dropdownResourceField.setNullValid(false);
+ dropdownResourceField.setRequired(true);
+ add(dropdownResourceField);
+
+ final String connObjectKeyFieldId = "connObjectKeyValue";
+ AjaxTextFieldPanel connObjectKeyField = new AjaxTextFieldPanel(
+ "connObjectKeyValue",
+ "connObjectKeyValue",
+ new PropertyModel<>(linkedAccountTO, "connObjectKeyValue"),
+ false);
+ connObjectKeyField.setOutputMarkupId(true);
+ connObjectKeyField.addRequiredLabel();
+ connObjectKeyField.setChoices(Collections.<String>emptyList());
+ connObjectKeyField.setEnabled(false);
+ add(connObjectKeyField);
+
+ dropdownResourceField.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ boolean enabled = dropdownResourceField.getModelObject() != null
+ && !dropdownResourceField.getModelObject().isEmpty();
+ connObjectKeyField.setEnabled(enabled);
+ if (enabled) {
+ setConnObjectFieldChoices(connObjectKeyField, dropdownResourceField.getModelObject(), null);
+ }
+ target.add(connObjectKeyField);
+ }
+ });
+
+ connObjectKeyField.getField().setMarkupId(connObjectKeyFieldId);
+ connObjectKeyField.getField().add(new AjaxEventBehavior(Constants.ON_KEYDOWN) {
+
+ private static final long serialVersionUID = 3533589614190959822L;
+
+ @Override
+ protected void onEvent(final AjaxRequestTarget target) {
+ String searchTerm = connObjectKeyField.getField().getInput();
+ if (StringUtils.isNotBlank(searchTerm) && searchTerm.length() > 1) {
+ setConnObjectFieldChoices(connObjectKeyField, dropdownResourceField.getModelObject(), searchTerm);
+
+ // If elements are found, send an "arrow down" key event to open input autocomplete dropdown
+ target.appendJavaScript(connObjectKeyFieldValues.isEmpty()
+ ? "$('#" + connObjectKeyFieldId + "-autocomplete-container').hide();"
+ : "var simulatedEvent = new KeyboardEvent('keydown', {keyCode: 40, which: 40}); "
+ + "document.getElementById('" + connObjectKeyFieldId + "').dispatchEvent(simulatedEvent);");
+ }
+ }
+
+ @Override
+ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+ super.updateAjaxAttributes(attributes);
+
+ AjaxCallListener listener = new AjaxCallListener() {
+
+ private static final long serialVersionUID = 2208168001920794667L;
+
+ @Override
+ public CharSequence getPrecondition(final Component component) {
+ // Eevaluates weather an ajax call will be executed or not.
+ // If the key code is "arrow down" or "arrow up" do NOT trigger the event callback
+ return "var keycode = Wicket.Event.keyCode(attrs.event); "
+ + "if ((keycode == 40) || (keycode == 38)) {return false;} return true;";
+ }
+ };
+ attributes.getAjaxCallListeners().add(listener);
+ attributes.setThrottlingSettings(new ThrottlingSettings("id", Duration.seconds(1.2), true));
+ }
+ });
+ }
+
+ private void setConnObjectFieldChoices(
+ final AjaxTextFieldPanel ajaxTextFieldPanel,
+ final String resource,
+ final String searchTerm) {
+
+ Set<String> choices = new HashSet<>();
+ String resourceRemoteKey = ConnIdSpecialName.NAME;
+ try {
+ resourceRemoteKey = resourceRestClient.read(resource).getProvision(AnyTypeKind.USER.name()).get().
+ getMapping().getConnObjectKeyItem().getExtAttrName();
+ } catch (Exception ex) {
+ LOG.error("While reading mapping for resource {}", resource, ex);
+ }
+
+ ConnObjectTOQuery.Builder builder = new ConnObjectTOQuery.Builder().size(SEARCH_SIZE);
+ if (StringUtils.isNotBlank(searchTerm)) {
+ builder.fiql(SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
+ is(resourceRemoteKey).equalTo(searchTerm + "*").query()).build();
+ }
+ Pair<String, List<ConnObjectTO>> items = resourceRestClient.searchConnObjects(resource,
+ AnyTypeKind.USER.name(),
+ builder,
+ new SortParam<>(resourceRemoteKey, true));
+
+ choices.addAll(items.getRight().stream().map(item -> {
+ return item.getAttr(ConnIdSpecialName.UID).get().getValues().get(0);
+ }).collect(Collectors.toSet()));
+
+ connObjectKeyFieldValues = new ArrayList<>(choices);
+ Collections.sort(connObjectKeyFieldValues);
+ ajaxTextFieldPanel.setChoices(connObjectKeyFieldValues);
+ }
+
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
new file mode 100644
index 0000000..cac1afb
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
@@ -0,0 +1,255 @@
+/*
+ * 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.wizards.any;
+
+import org.apache.syncope.client.ui.commons.wizards.any.EntityWrapper;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.client.console.commons.LinkedAccountPlainAttrProperty;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
+import org.apache.syncope.client.ui.commons.markup.html.form.AbstractFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
+import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.Attr;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+
+public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainSchemaTO> {
+
+ private static final long serialVersionUID = -6664931684253730934L;
+
+ private final LinkedAccountTO linkedAccountTO;
+
+ private final UserTO userTO;
+
+ private final Set<Attr> fixedAttrs = new HashSet<>();
+
+ private final List<LinkedAccountPlainAttrProperty> accountPlainAttrProperties = new ArrayList<>();
+
+ public <T extends AnyTO> LinkedAccountPlainAttrsPanel(
+ final EntityWrapper<LinkedAccountTO> modelObject,
+ final UserTO userTO) throws IllegalArgumentException {
+
+ super(userTO,
+ AjaxWizard.Mode.EDIT,
+ new AnyTypeRestClient().read(userTO.getType()).getClasses(),
+ FormLayoutInfoUtils.fetch(Arrays.asList(userTO.getType())).getLeft().getWhichPlainAttrs(),
+ modelObject);
+
+ this.linkedAccountTO = modelObject.getInnerObject();
+ this.fixedAttrs.addAll(this.linkedAccountTO.getPlainAttrs());
+ this.userTO = userTO;
+
+ add(new Accordion("plainSchemas", Collections.<ITab>singletonList(new AbstractTab(
+ new ResourceModel("attributes.accordion", "Plain Attributes")) {
+
+ private static final long serialVersionUID = -7078941093668723016L;
+
+ @Override
+ public WebMarkupContainer getPanel(final String panelId) {
+ return new PlainSchemasOwn(panelId, schemas, attrs);
+ }
+ }), Model.of(0)).setOutputMarkupId(true));
+ }
+
+ @Override
+ protected FormComponent<?> checkboxToggle(
+ final Attr attrTO,
+ final AbstractFieldPanel<?> panel,
+ final boolean isMultivalue) {
+
+ LinkedAccountPlainAttrProperty property = accountPlainAttrProperties.stream().filter(
+ existingProperty -> {
+ return existingProperty.getSchema().equals(attrTO.getSchema());
+ }).findFirst().orElseGet(() -> {
+ LinkedAccountPlainAttrProperty newProperty = new LinkedAccountPlainAttrProperty();
+ newProperty.setOverridable(linkedAccountTO.getPlainAttr(attrTO.getSchema()).isPresent());
+ newProperty.setSchema(attrTO.getSchema());
+ newProperty.getValues().addAll(attrTO.getValues());
+ accountPlainAttrProperties.add(newProperty);
+ return newProperty;
+ });
+
+ final BootstrapToggleConfig config = new BootstrapToggleConfig().
+ withOnStyle(BootstrapToggleConfig.Style.success).
+ withOffStyle(BootstrapToggleConfig.Style.danger).
+ withSize(BootstrapToggleConfig.Size.mini);
+
+ return new BootstrapToggle("externalAction", new PropertyModel<Boolean>(property, "overridable"), config) {
+
+ private static final long serialVersionUID = -875219845189261873L;
+
+ @Override
+ protected CheckBox newCheckBox(final String id, final IModel<Boolean> model) {
+ final CheckBox checkBox = super.newCheckBox(id, model);
+ checkBox.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ if (isMultivalue) {
+ MultiFieldPanel.class.cast(panel).setFormReadOnly(!model.getObject());
+ } else {
+ FieldPanel.class.cast(panel).setReadOnly(!model.getObject());
+ }
+
+ updateAccountPlainSchemas(property, model.getObject());
+ target.add(panel);
+ }
+ });
+ return checkBox;
+ }
+
+ @Override
+ protected IModel<String> getOnLabel() {
+ return Model.of("Override");
+ }
+
+ @Override
+ protected IModel<String> getOffLabel() {
+ return Model.of("Override?");
+ }
+
+ @Override
+ protected void onComponentTag(final ComponentTag tag) {
+ super.onComponentTag(tag);
+ tag.append("class", "overridable", " ");
+ }
+ };
+ }
+
+ private void updateAccountPlainSchemas(final LinkedAccountPlainAttrProperty property, final Boolean modelObject) {
+ Set<Attr> withoutCurrentSChema = new HashSet<>(linkedAccountTO.getPlainAttrs().stream().
+ filter(attr -> !attr.getSchema().equals(property.getSchema())).
+ collect(Collectors.toSet()));
+ linkedAccountTO.getPlainAttrs().clear();
+ linkedAccountTO.getPlainAttrs().addAll(withoutCurrentSChema);
+ if (modelObject) {
+ linkedAccountTO.getPlainAttrs().add(
+ fixedAttrs.stream().filter(attrTO -> attrTO.getSchema().equals(property.getSchema())).findFirst().
+ orElseGet(() -> new Attr.Builder(property.getSchema()).
+ values(property.getValues()).build()));
+ }
+ }
+
+ @Override
+ protected SchemaType getSchemaType() {
+ return SchemaType.PLAIN;
+ }
+
+ @Override
+ protected void setAttrs() {
+ List<Attr> attrs = new ArrayList<>();
+ setFixedAttr(schemas.values());
+ Map<String, Attr> attrMap = EntityTOUtils.buildAttrMap(fixedAttrs);
+
+ attrs.addAll(schemas.values().stream().map(schema -> {
+ Attr attrTO = new Attr();
+ attrTO.setSchema(schema.getKey());
+ if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) {
+ attrTO.getValues().add("");
+ } else {
+ attrTO = attrMap.get(schema.getKey());
+ }
+ return attrTO;
+ }).collect(Collectors.toList()));
+
+ fixedAttrs.clear();
+ fixedAttrs.addAll(attrs);
+ }
+
+ @Override
+ protected List<Attr> getAttrsFromTO() {
+ return fixedAttrs.stream().sorted(attrComparator).collect(Collectors.toList());
+ }
+
+ private void setFixedAttr(final Collection<PlainSchemaTO> values) {
+ values.forEach(schema -> {
+ if (linkedAccountTO.getPlainAttr(schema.getKey()).isPresent()) {
+ fixedAttrs.add(linkedAccountTO.getPlainAttr(schema.getKey()).get());
+ } else if (userTO.getPlainAttr(schema.getKey()).isPresent()) {
+ fixedAttrs.add(userTO.getPlainAttr(schema.getKey()).get());
+ }
+ });
+ }
+
+ private class PlainSchemasOwn extends PlainSchemas<List<Attr>> {
+
+ private static final long serialVersionUID = -4730563859116024676L;
+
+ PlainSchemasOwn(
+ final String id,
+ final Map<String, PlainSchemaTO> schemas,
+ final IModel<List<Attr>> attrTOs) {
+
+ super(id, schemas, attrTOs);
+
+ add(new ListView<Attr>("schemas", attrTOs) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ protected void populateItem(final ListItem<Attr> item) {
+ Attr attrTO = item.getModelObject();
+ final boolean isMultivalue = schemas.get(attrTO.getSchema()).isMultivalue();
+
+ AbstractFieldPanel<?> panel = setPanel(
+ schemas,
+ item,
+ !linkedAccountTO.getPlainAttr(attrTO.getSchema()).isPresent());
+
+ panel.showExternAction(checkboxToggle(attrTO, panel, isMultivalue));
+ }
+ });
+ }
+ }
+
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.java
new file mode 100644
index 0000000..c33351a
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.java
@@ -0,0 +1,66 @@
+/*
+ * 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.wizards.any;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.client.console.rest.ApplicationRestClient;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.util.ListModel;
+
+public class LinkedAccountPrivilegesPanel extends WizardStep {
+
+ private static final long serialVersionUID = 3388483585148725922L;
+
+ private final ApplicationRestClient applicationRestClient = new ApplicationRestClient();
+
+ public LinkedAccountPrivilegesPanel(final LinkedAccountTO linkedAccountTO) {
+ super();
+ setOutputMarkupId(true);
+
+ final LoadableDetachableModel<List<String>> availablePrivilges = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ return applicationRestClient.list().stream().
+ flatMap(app -> app.getPrivileges().stream()).
+ map(privilege -> privilege.getKey()).
+ distinct().
+ sorted().
+ collect(Collectors.toList());
+ }
+ };
+ AjaxPalettePanel<String> privilegesPanel = new AjaxPalettePanel.Builder<String>().
+ setAllowOrder(true).
+ setAllowMoveAll(true).
+ build("privileges",
+ new PropertyModel<>(linkedAccountTO, "privileges"),
+ new ListModel<>(availablePrivilges.getObject()));
+ privilegesPanel.hideLabel();
+ privilegesPanel.setOutputMarkupId(true);
+ add(privilegesPanel);
+ }
+
+}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
new file mode 100644
index 0000000..371ab09
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
@@ -0,0 +1,131 @@
+/*
+ * 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.wizards.any;
+
+import org.apache.syncope.client.ui.commons.wizards.any.EntityWrapper;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal.ModalEvent;
+import org.apache.syncope.client.console.wizards.BaseAjaxWizardBuilder;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.Attr;
+import org.apache.syncope.common.lib.request.LinkedAccountUR;
+import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.wizard.WizardModel;
+
+/**
+ * Accounts wizard builder.
+ */
+public class LinkedAccountWizardBuilder extends BaseAjaxWizardBuilder<LinkedAccountTO> {
+
+ private static final long serialVersionUID = -9142332740863374891L;
+
+ private final UserRestClient userRestClient = new UserRestClient();
+
+ private UserTO userTO;
+
+ private final String userKey;
+
+ public LinkedAccountWizardBuilder(final String userKey, final PageReference pageRef) {
+ super(new LinkedAccountTO(), pageRef);
+ this.userKey = userKey;
+ this.userTO = userRestClient.read(userKey);
+ }
+
+ @Override
+ public AjaxWizard<LinkedAccountTO> build(final String id, final AjaxWizard.Mode mode) {
+ this.userTO = userRestClient.read(userKey);
+ return super.build(id, mode);
+ }
+
+ @Override
+ protected WizardModel buildModelSteps(final LinkedAccountTO modelObject, final WizardModel wizardModel) {
+ wizardModel.add(new LinkedAccountDetailsPanel(modelObject));
+ wizardModel.add(new LinkedAccountCredentialsPanel(modelObject));
+ wizardModel.add(new LinkedAccountPlainAttrsPanel(new EntityWrapper<>(modelObject), userTO));
+ wizardModel.add(new LinkedAccountPrivilegesPanel(modelObject));
+ return wizardModel;
+ }
+
+ @Override
+ protected Serializable onApplyInternal(final LinkedAccountTO modelObject) {
+ fixPlainAttrs(modelObject);
+
+ LinkedAccountUR linkedAccountPatch = new LinkedAccountUR.Builder().linkedAccountTO(modelObject).build();
+ linkedAccountPatch.setLinkedAccountTO(modelObject);
+ UserUR patch = new UserUR();
+ patch.setKey(userTO.getKey());
+ patch.getLinkedAccounts().add(linkedAccountPatch);
+ userRestClient.update(userTO.getETagValue(), patch);
+
+ return modelObject;
+ }
+
+ private void fixPlainAttrs(final LinkedAccountTO linkedAccountTO) {
+ Set<Attr> validAttrs = new HashSet<>(linkedAccountTO.getPlainAttrs().stream().
+ filter(attr -> !attr.getValues().isEmpty()).
+ collect(Collectors.toSet()));
+ linkedAccountTO.getPlainAttrs().clear();
+ linkedAccountTO.getPlainAttrs().addAll(validAttrs);
+ }
+
+ @Override
+ protected Serializable getCreateCustomPayloadEvent(final Serializable afterObject, final AjaxRequestTarget target) {
+ LinkedAccountTO linkedAccountTO = LinkedAccountTO.class.cast(afterObject);
+ return new CreateEvent(
+ linkedAccountTO.getConnObjectKeyValue(),
+ userTO,
+ target);
+ }
+
+ private static class CreateEvent extends ModalEvent {
+
+ private static final long serialVersionUID = 6416834092156281986L;
+
+ private final String key;
+
+ private final UserTO userTO;
+
+ CreateEvent(
+ final String key,
+ final UserTO userTO,
+ final AjaxRequestTarget target) {
+
+ super(target);
+ this.key = key;
+ this.userTO = userTO;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public UserTO getUserTO() {
+ return userTO;
+ }
+ }
+
+}
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
index e2da0f2..97c6734 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
@@ -23,7 +23,7 @@ under the License.
</div>
<div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <span wicket:id="capabilities">[capabilities]</span>
</div>
</wicket:panel>
</html>
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java
index 579db02..4f3a090 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java
@@ -57,6 +57,8 @@ public final class Constants {
public static final String ON_CHANGE = "change";
+ public static final String ON_KEYDOWN = "keydown";
+
public static final String ON_BLUR = "blur";
public static final String PNG_EXT = ".png";
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractFieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractFieldPanel.java
index f9c2878..30dfe7f 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractFieldPanel.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractFieldPanel.java
@@ -122,4 +122,6 @@ public abstract class AbstractFieldPanel<T> extends Panel {
public String getName() {
return this.name;
}
+
+ public abstract AbstractFieldPanel<T> setReadOnly(boolean readOnly);
}
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java
index e4eb01a..3079bf6 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java
@@ -205,4 +205,9 @@ public abstract class AbstractMultiPanel<INNER> extends AbstractFieldPanel<List<
container.setEnabled(!readOnly);
return this;
}
+
+ public AbstractFieldPanel<List<INNER>> setFormReadOnly(final boolean readOnly) {
+ form.setEnabled(!readOnly);
+ return this;
+ }
}
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java
index 5af8052..818dd77 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java
@@ -197,6 +197,12 @@ public class AjaxPalettePanel<T extends Serializable> extends AbstractFieldPanel
target.add(palette);
}
+ @Override
+ public AbstractFieldPanel<List<T>> setReadOnly(final boolean readOnly) {
+ palette.setEnabled(!readOnly);
+ return this;
+ }
+
public static class Builder<T extends Serializable> implements Serializable {
private static final long serialVersionUID = 991248996001040352L;
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxSpinnerFieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxSpinnerFieldPanel.java
index 3074dbf..acb92a3 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxSpinnerFieldPanel.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxSpinnerFieldPanel.java
@@ -48,6 +48,8 @@ public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T>
private final Options options;
+ private SpinnerBehavior behavior;
+
private AjaxSpinnerFieldPanel(
final String id,
final String name,
@@ -64,7 +66,7 @@ public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T>
@Override
public JQueryUIBehavior newWidgetBehavior(final String selector) {
- SpinnerBehavior behavior = new SpinnerBehavior(selector, new SpinnerAdapter());
+ behavior = new SpinnerBehavior(selector, new SpinnerAdapter());
behavior.setOptions(options);
return behavior;
}
@@ -229,6 +231,17 @@ public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T>
return panel;
}
+ @Override
+ public FieldPanel<T> setReadOnly(final boolean readOnly) {
+ super.setReadOnly(readOnly);
+ AjaxSpinner.class.cast(field).setEnabled(!readOnly);
+ options.set("disabled", readOnly);
+ if (behavior != null) {
+ behavior.setOptions(options);
+ }
+ return this;
+ }
+
public static class Builder<T extends Number> {
private final Options options = new Options();
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java
index 3aecf67..9a72010 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java
@@ -88,7 +88,7 @@ public abstract class AjaxWizardBuilder<T extends Serializable> extends Abstract
// get the specified item if available
final T modelObject = newModelObject();
- return new AjaxWizard<T>(id, modelObject, buildModelSteps(modelObject, new WizardModel()), mode, this.pageRef) {
+ return new AjaxWizard<T>(id, modelObject, buildModelSteps(modelObject, new WizardModel()), mode, pageRef) {
private static final long serialVersionUID = 7770507663760640735L;
@@ -170,7 +170,7 @@ public abstract class AjaxWizardBuilder<T extends Serializable> extends Abstract
* @return payload to be sent.
*/
protected static Serializable getEditCustomPayloadEvent(final Serializable afterObject,
- final AjaxRequestTarget target) {
+ final AjaxRequestTarget target) {
return null;
}
}
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/EntityWrapper.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/EntityWrapper.java
new file mode 100644
index 0000000..6764049
--- /dev/null
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/EntityWrapper.java
@@ -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.
+ */
+package org.apache.syncope.client.ui.commons.wizards.any;
+
+import org.apache.syncope.common.lib.to.EntityTO;
+
+public class EntityWrapper<T extends EntityTO> {
+
+ protected final T entityTO;
+
+ public EntityWrapper(final T entityTO) {
+ this.entityTO = entityTO;
+ }
+
+ public T getInnerObject() {
+ return entityTO;
+ }
+
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/LinkedAccountPlainAttrProperty.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/LinkedAccountPlainAttrProperty.java
new file mode 100644
index 0000000..3f0468a
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/LinkedAccountPlainAttrProperty.java
@@ -0,0 +1,100 @@
+/*
+ * 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 com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+@XmlRootElement
+@XmlType
+public class LinkedAccountPlainAttrProperty implements Serializable, Comparable<LinkedAccountPlainAttrProperty> {
+
+ private static final long serialVersionUID = -5309050337675968950L;
+
+ private String schema;
+
+ private final List<String> values = new ArrayList<>();
+
+ private boolean overridable;
+
+ public String getSchema() {
+ return schema;
+ }
+
+ public void setSchema(final String schema) {
+ this.schema = schema;
+ }
+
+ @XmlElementWrapper(name = "values")
+ @XmlElement(name = "value")
+ @JsonProperty("values")
+ public List<String> getValues() {
+ return values;
+ }
+
+ public boolean isOverridable() {
+ return overridable;
+ }
+
+ public void setOverridable(final boolean overridable) {
+ this.overridable = overridable;
+ }
+
+ @Override
+ public int compareTo(final LinkedAccountPlainAttrProperty connConfProperty) {
+ return ObjectUtils.compare(this.getSchema(), connConfProperty.getSchema());
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ append(schema).
+ append(values).
+ append(overridable).
+ build();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final LinkedAccountPlainAttrProperty other = (LinkedAccountPlainAttrProperty) obj;
+ return new EqualsBuilder().
+ append(schema, other.schema).
+ append(values, other.values).
+ append(overridable, other.overridable).
+ build();
+ }
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index 099d8a8..fbcd14b 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -227,6 +227,15 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
};
}
+ /**
+ * Use this to refresh the ListView with updated items (e.g. from callback methods)
+ *
+ * @param elements
+ */
+ public void refreshList(final List<T> elements) {
+ beans.setList(elements);
+ }
+
public void setCheckAvailability(final CheckAvailability check) {
// used to perform selectable enabling check condition
this.check.setObject(check);
@@ -384,8 +393,8 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
LOG.debug("Field value {}", value);
return Optional.ofNullable(value)
- .map(o -> new Label("field", new ResourceModel(o.toString(), o.toString())))
- .orElseGet(() -> new Label("field", StringUtils.EMPTY));
+ .map(o -> new Label("field", new ResourceModel(o.toString(), o.toString())))
+ .orElseGet(() -> new Label("field", StringUtils.EMPTY));
}
protected T getActualItem(final T item, final List<T> list) {
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 f37e91b..5416be7 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
@@ -97,6 +97,7 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
MANAGE_RESOURCES("update"),
MANAGE_USERS("update"),
MANAGE_GROUPS("update"),
+ MANAGE_ACCOUNTS("update"),
PROPAGATION_TASKS("read"),
NOTIFICATION_TASKS("read"),
ZOOM_IN("zoomin"),
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
index 4a98a4e..3d2a0c2 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
@@ -305,4 +305,11 @@ public class BinaryFieldPanel extends BaseBinaryFieldPanel {
protected Integer getMaxUploadFileSizeMB() {
return SyncopeWebApplication.get().getMaxUploadFileSizeMB();
}
+
+ @Override
+ public FieldPanel<String> setReadOnly(final boolean readOnly) {
+ super.setReadOnly(readOnly);
+ fileUpload.setEnabled(!readOnly);
+ return this;
+ }
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
index 920afb3..c4638c3 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
@@ -18,84 +18,49 @@
*/
package org.apache.syncope.client.console.wizards.any;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
-import org.apache.cxf.common.util.StringUtils;
import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
import org.apache.syncope.client.console.rest.GroupRestClient;
-import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
import org.apache.syncope.common.lib.to.SchemaTO;
-import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.Attr;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.wicket.PageReference;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.core.util.lang.PropertyResolver;
-import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
-import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
-import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.util.ListModel;
-public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep implements ICondition {
+public abstract class AbstractAttrs<S extends SchemaTO> extends AbstractAttrsWizardStep<S> {
private static final long serialVersionUID = -5387344116983102292L;
- protected final Comparator<Attr> attrComparator = new AttrComparator();
-
- private final AnyTypeClassRestClient anyTypeClassRestClient = new AnyTypeClassRestClient();
-
private final GroupRestClient groupRestClient = new GroupRestClient();
- protected final AnyTO anyTO;
-
- private final List<String> whichAttrs;
-
- protected final Map<String, S> schemas = new LinkedHashMap<>();
-
- protected final Map<String, Map<String, S>> membershipSchemas = new LinkedHashMap<>();
-
- protected final IModel<List<Attr>> attrs;
-
protected final IModel<List<MembershipTO>> membershipTOs;
- private final List<String> anyTypeClasses;
+ protected final Map<String, Map<String, S>> membershipSchemas = new LinkedHashMap<>();
public AbstractAttrs(
final AnyWrapper<?> modelObject,
final List<String> anyTypeClasses,
final List<String> whichAttrs) {
- super();
- this.anyTypeClasses = anyTypeClasses;
- this.attrs = new ListModel<>(List.of());
- this.membershipTOs = new ListModel<>(Collections.<MembershipTO>emptyList());
- this.setOutputMarkupId(true);
+ super(modelObject.getInnerObject(), AjaxWizard.Mode.CREATE, anyTypeClasses, whichAttrs, null);
- this.anyTO = modelObject.getInnerObject();
- this.whichAttrs = whichAttrs;
- }
+ this.membershipTOs = new ListModel<>(Collections.<MembershipTO>emptyList());
- private List<Attr> loadAttrs() {
- List<String> classes = new ArrayList<>(anyTypeClasses);
- classes.addAll(AnyTypeClassRestClient.list(anyTO.getAuxClasses()).stream().
- map(EntityTO::getKey).collect(Collectors.toList()));
- setSchemas(classes);
- setAttrs();
- return AbstractAttrs.this.getAttrsFromTO();
+ this.setOutputMarkupId(true);
}
@SuppressWarnings("unchecked")
@@ -126,12 +91,6 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
return memberships;
}
- protected boolean reoderSchemas() {
- return !whichAttrs.isEmpty();
- }
-
- protected abstract SchemaType getSchemaType();
-
private void setSchemas(final String membership, final List<String> anyTypeClasses) {
final Map<String, S> mscs;
@@ -144,28 +103,18 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
setSchemas(anyTypeClasses, mscs);
}
- private void setSchemas(final List<String> anyTypeClasses) {
- setSchemas(anyTypeClasses, schemas);
- }
-
- private void setSchemas(final List<String> anyTypeClasses, final Map<String, S> scs) {
- final List<S> allSchemas;
- if (anyTypeClasses.isEmpty()) {
- allSchemas = new ArrayList<>();
- } else {
- allSchemas = SchemaRestClient.getSchemas(getSchemaType(), null, anyTypeClasses.toArray(new String[] {}));
+ protected List<String> getMembershipAuxClasses(final MembershipTO membershipTO, final String anyType) {
+ try {
+ final GroupTO groupTO = groupRestClient.read(membershipTO.getGroupKey());
+ return groupTO.getTypeExtension(anyType).get().getAuxClasses();
+ } catch (Exception e) {
+ return List.of();
}
+ }
- scs.clear();
-
- if (reoderSchemas()) {
- // 1. remove attributes not selected for display
- allSchemas.removeAll(allSchemas.stream().
- filter(schemaTO -> !whichAttrs.contains(schemaTO.getKey())).collect(Collectors.toSet()));
- }
+ protected abstract void setAttrs(MembershipTO membershipTO);
- allSchemas.forEach(schemaTO -> scs.put(schemaTO.getKey(), schemaTO));
- }
+ protected abstract List<Attr> getAttrsFromTO(MembershipTO membershipTO);
@Override
public void renderHead(final IHeaderResponse response) {
@@ -178,23 +127,6 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
}
}
- protected abstract void setAttrs();
-
- protected abstract void setAttrs(MembershipTO membershipTO);
-
- protected abstract List<Attr> getAttrsFromTO();
-
- protected abstract List<Attr> getAttrsFromTO(MembershipTO membershipTO);
-
- protected List<String> getMembershipAuxClasses(final MembershipTO membershipTO, final String anyType) {
- try {
- final GroupTO groupTO = groupRestClient.read(membershipTO.getGroupKey());
- return groupTO.getTypeExtension(anyType).get().getAuxClasses();
- } catch (Exception e) {
- return List.of();
- }
- }
-
@Override
public boolean evaluate() {
this.attrs.setObject(loadAttrs());
@@ -202,46 +134,4 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
return !attrs.getObject().isEmpty() || !membershipTOs.getObject().isEmpty();
}
- public PageReference getPageReference() {
- // SYNCOPE-1213
- // default implementation does not require to pass page reference, override this method of want otherwise
- return null;
- }
-
- private class AttrComparator implements Comparator<Attr>, Serializable {
-
- private static final long serialVersionUID = -5105030477767941060L;
-
- @Override
- public int compare(final Attr left, final Attr right) {
- if (left == null || StringUtils.isEmpty(left.getSchema())) {
- return -1;
- }
- if (right == null || StringUtils.isEmpty(right.getSchema())) {
- return 1;
- } else if (AbstractAttrs.this.reoderSchemas()) {
- int leftIndex = AbstractAttrs.this.whichAttrs.indexOf(left.getSchema());
- int rightIndex = AbstractAttrs.this.whichAttrs.indexOf(right.getSchema());
-
- if (leftIndex > rightIndex) {
- return 1;
- } else if (leftIndex < rightIndex) {
- return -1;
- } else {
- return 0;
- }
- } else {
- return left.getSchema().compareTo(right.getSchema());
- }
- }
- }
-
- public static class Schemas extends Panel {
-
- private static final long serialVersionUID = -2447602429647965090L;
-
- public Schemas(final String id) {
- super(id);
- }
- }
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
new file mode 100644
index 0000000..047628e
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
@@ -0,0 +1,453 @@
+/*
+ * 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.wizards.any;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
+import org.apache.syncope.client.ui.commons.SchemaUtils;
+import org.apache.syncope.client.ui.commons.ajax.markup.html.LabelInfo;
+import org.apache.syncope.client.ui.commons.markup.html.form.AbstractFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDateFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDateTimeFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxSpinnerFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.EncryptedFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.client.ui.commons.wizards.any.EntityWrapper;
+import org.apache.syncope.common.lib.Attr;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.SchemaTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.util.ListModel;
+
+public abstract class AbstractAttrsWizardStep<S extends SchemaTO> extends WizardStep implements ICondition {
+
+ private static final long serialVersionUID = 8931397230194043674L;
+
+ protected final Comparator<Attr> attrComparator = new AttrComparator();
+
+ protected final AnyTypeClassRestClient anyTypeClassRestClient = new AnyTypeClassRestClient();
+
+ protected final AnyTO anyTO;
+
+ protected AnyTO previousObject;
+
+ private final List<String> whichAttrs;
+
+ protected final Map<String, S> schemas = new LinkedHashMap<>();
+
+ protected final IModel<List<Attr>> attrs;
+
+ private final List<String> anyTypeClasses;
+
+ protected String fileKey = "";
+
+ protected final AjaxWizard.Mode mode;
+
+ public AbstractAttrsWizardStep(
+ final AnyTO anyTO,
+ final AjaxWizard.Mode mode,
+ final List<String> anyTypeClasses,
+ final List<String> whichAttrs,
+ final EntityWrapper<?> modelObject) {
+
+ super();
+ this.anyTypeClasses = anyTypeClasses;
+ this.attrs = new ListModel<>(Collections.<Attr>emptyList());
+
+ this.setOutputMarkupId(true);
+
+ this.mode = mode;
+ this.anyTO = anyTO;
+ this.whichAttrs = whichAttrs;
+ }
+
+ protected List<Attr> loadAttrs() {
+ List<String> classes = new ArrayList<>(anyTypeClasses);
+ classes.addAll(AnyTypeClassRestClient.list(anyTO.getAuxClasses()).stream().
+ map(EntityTO::getKey).collect(Collectors.toList()));
+ setSchemas(classes);
+ setAttrs();
+ return AbstractAttrsWizardStep.this.getAttrsFromTO();
+ }
+
+ protected boolean reoderSchemas() {
+ return !whichAttrs.isEmpty();
+ }
+
+ protected abstract SchemaType getSchemaType();
+
+ protected void setSchemas(final List<String> anyTypeClasses) {
+ setSchemas(anyTypeClasses, schemas);
+ }
+
+ protected void setSchemas(final List<String> anyTypeClasses, final Map<String, S> scs) {
+ final List<S> allSchemas;
+ if (anyTypeClasses.isEmpty()) {
+ allSchemas = new ArrayList<>();
+ } else {
+ allSchemas = SchemaRestClient.getSchemas(getSchemaType(), null, anyTypeClasses.toArray(new String[] {}));
+ }
+
+ scs.clear();
+
+ if (reoderSchemas()) {
+ // 1. remove attributes not selected for display
+ allSchemas.removeAll(allSchemas.stream().
+ filter(schemaTO -> !whichAttrs.contains(schemaTO.getKey())).collect(Collectors.toSet()));
+ }
+
+ allSchemas.forEach(schemaTO -> scs.put(schemaTO.getKey(), schemaTO));
+ }
+
+ @Override
+ public void renderHead(final IHeaderResponse response) {
+ super.renderHead(response);
+ if (CollectionUtils.isEmpty(attrs.getObject())) {
+ response.render(OnDomReadyHeaderItem.forScript(
+ String.format("$('#emptyPlaceholder').append(\"%s\"); $('#attributes').hide();",
+ getString("attribute.empty.list"))));
+ }
+ }
+
+ protected abstract void setAttrs();
+
+ protected abstract List<Attr> getAttrsFromTO();
+
+ @Override
+ public boolean evaluate() {
+ this.attrs.setObject(loadAttrs());
+ return !attrs.getObject().isEmpty();
+ }
+
+ public PageReference getPageReference() {
+ // SYNCOPE-1213
+ // default implementation does not require to pass page reference, override this method of want otherwise
+ return null;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected FieldPanel getFieldPanel(final PlainSchemaTO schemaTO) {
+ final boolean required;
+ final boolean readOnly;
+ final AttrSchemaType type;
+ final boolean jexlHelp;
+
+ if (mode == AjaxWizard.Mode.TEMPLATE) {
+ required = false;
+ readOnly = false;
+ type = AttrSchemaType.String;
+ jexlHelp = true;
+ } else {
+ required = schemaTO.getMandatoryCondition().equalsIgnoreCase("true");
+ readOnly = schemaTO.isReadonly();
+ type = schemaTO.getType();
+ jexlHelp = false;
+
+ }
+
+ FieldPanel panel;
+ switch (type) {
+ case Boolean:
+ panel = new AjaxCheckBoxPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ true);
+ panel.setRequired(required);
+ break;
+
+ case Date:
+ String datePattern = schemaTO.getConversionPattern() == null
+ ? SyncopeConstants.DEFAULT_DATE_PATTERN
+ : schemaTO.getConversionPattern();
+
+ if (datePattern.contains("H")) {
+ panel = new AjaxDateTimeFieldPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ FastDateFormat.getInstance(datePattern));
+ } else {
+ panel = new AjaxDateFieldPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ FastDateFormat.getInstance(datePattern));
+ }
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+
+ break;
+
+ case Enum:
+ panel = new AjaxDropDownChoicePanel<>("panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+ ((AjaxDropDownChoicePanel<String>) panel).setChoices(SchemaUtils.getEnumeratedValues(schemaTO));
+
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(schemaTO.getEnumerationKeys())) {
+ ((AjaxDropDownChoicePanel) panel).setChoiceRenderer(new IChoiceRenderer<String>() {
+
+ private static final long serialVersionUID = -3724971416312135885L;
+
+ private final Map<String, String> valueMap = SchemaUtils.getEnumeratedKeyValues(schemaTO);
+
+ @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;
+ }
+ });
+ }
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Long:
+ panel = new AjaxSpinnerFieldPanel.Builder<Long>().enableOnChange().build(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ Long.class,
+ new Model<>());
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Double:
+ panel = new AjaxSpinnerFieldPanel.Builder<Double>().enableOnChange().step(0.1).build(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ Double.class,
+ new Model<>());
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Binary:
+ final PageReference pageRef = getPageReference();
+ panel = new BinaryFieldPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ schemaTO.getMimeType(),
+ fileKey) {
+
+ private static final long serialVersionUID = -3268213909514986831L;
+
+ @Override
+ protected PageReference getPageReference() {
+ return pageRef;
+ }
+
+ };
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Encrypted:
+ panel = new EncryptedFieldPanel("panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ default:
+ panel = new AjaxTextFieldPanel("panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+
+ if (jexlHelp) {
+ AjaxTextFieldPanel.class.cast(panel).enableJexlHelp();
+ }
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ }
+
+ panel.setReadOnly(readOnly);
+
+ return panel;
+ }
+
+ protected FormComponent<?> checkboxToggle(
+ final Attr attr,
+ final AbstractFieldPanel<?> panel,
+ final boolean isMultivalue) {
+
+ // do nothing
+ return null;
+ }
+
+ private class AttrComparator implements Comparator<Attr>, Serializable {
+
+ private static final long serialVersionUID = -5105030477767941060L;
+
+ @Override
+ public int compare(final Attr left, final Attr right) {
+ if (left == null || StringUtils.isEmpty(left.getSchema())) {
+ return -1;
+ }
+ if (right == null || StringUtils.isEmpty(right.getSchema())) {
+ return 1;
+ } else if (AbstractAttrsWizardStep.this.reoderSchemas()) {
+ int leftIndex = AbstractAttrsWizardStep.this.whichAttrs.indexOf(left.getSchema());
+ int rightIndex = AbstractAttrsWizardStep.this.whichAttrs.indexOf(right.getSchema());
+
+ if (leftIndex > rightIndex) {
+ return 1;
+ } else if (leftIndex < rightIndex) {
+ return -1;
+ } else {
+ return 0;
+ }
+ } else {
+ return left.getSchema().compareTo(right.getSchema());
+ }
+ }
+ }
+
+ public static class Schemas extends Panel {
+
+ private static final long serialVersionUID = -2447602429647965090L;
+
+ public Schemas(final String id) {
+ super(id);
+ }
+ }
+
+ protected abstract class PlainSchemas<T> extends Schemas {
+
+ private static final long serialVersionUID = 8315035592714180404L;
+
+ public PlainSchemas(
+ final String id,
+ final Map<String, PlainSchemaTO> schemas,
+ final IModel<T> attrs) {
+
+ super(id);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ protected AbstractFieldPanel<?> setPanel(
+ final Map<String, PlainSchemaTO> schemas,
+ final ListItem<Attr> item,
+ final boolean setReadOnly) {
+
+ Attr attr = item.getModelObject();
+ final boolean isMultivalue = mode != AjaxWizard.Mode.TEMPLATE
+ && schemas.get(attr.getSchema()).isMultivalue();
+
+ AbstractFieldPanel<?> panel = getFieldPanel(schemas.get(attr.getSchema()));
+ if (isMultivalue) {
+ // SYNCOPE-1476 set form as multipart to properly manage membership attributes
+ panel = new MultiFieldPanel.Builder<>(
+ new PropertyModel<>(attr, "values")).build(
+ "panel",
+ attr.getSchema(),
+ FieldPanel.class.cast(panel)).setFormAsMultipart(true);
+ // SYNCOPE-1215 the entire multifield panel must be readonly, not only its field
+ MultiFieldPanel.class.cast(panel).setReadOnly(schemas.get(attr.getSchema()).isReadonly());
+ MultiFieldPanel.class.cast(panel).setFormReadOnly(setReadOnly);
+ } else {
+ FieldPanel.class.cast(panel).setNewModel(attr.getValues()).setReadOnly(setReadOnly);
+ }
+ item.add(panel);
+
+ setExternalAction(attr, panel);
+
+ return panel;
+ }
+
+ protected void setExternalAction(final Attr attr, final AbstractFieldPanel<?> panel) {
+ Optional<Attr> prevAttr = previousObject == null
+ ? Optional.empty()
+ : previousObject.getPlainAttr(attr.getSchema());
+ if (previousObject != null
+ && ((prevAttr.isEmpty() && attr.getValues().stream().anyMatch(StringUtils::isNotBlank))
+ || (prevAttr.isPresent() && !ListUtils.isEqualList(
+ prevAttr.get().getValues().stream().
+ filter(StringUtils::isNotBlank).collect(Collectors.toList()),
+ attr.getValues().stream().
+ filter(StringUtils::isNotBlank).collect(Collectors.toList()))))) {
+
+ List<String> oldValues = prevAttr.isPresent()
+ ? prevAttr.get().getValues()
+ : List.of();
+ panel.showExternAction(new LabelInfo("externalAction", oldValues));
+ }
+ }
+ }
+
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
index 7727cb4..cd35090 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
@@ -25,29 +25,14 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.stream.Collectors;
-import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.FastDateFormat;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDateFieldPanel;
-import org.apache.syncope.client.ui.commons.SchemaUtils;
-import org.apache.syncope.client.ui.commons.ajax.markup.html.LabelInfo;
import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.client.ui.commons.markup.html.form.AbstractFieldPanel;
-import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
-import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.ui.commons.markup.html.form.AjaxSpinnerFieldPanel;
-import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPanel;
-import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDateTimeFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
-import org.apache.syncope.client.ui.commons.markup.html.form.EncryptedFieldPanel;
import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
import org.apache.syncope.common.lib.EntityTOUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.GroupTO;
@@ -55,20 +40,16 @@ import org.apache.syncope.common.lib.to.GroupableRelatableTO;
import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.PlainSchemaTO;
import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.wicket.PageReference;
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.form.Form;
-import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.model.util.ListModel;
@@ -79,12 +60,6 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
private static final long serialVersionUID = 552437609667518888L;
- protected final AjaxWizard.Mode mode;
-
- protected final AnyTO previousObject;
-
- protected String fileKey = "";
-
public <T extends AnyTO> PlainAttrs(
final AnyWrapper<T> modelObject,
final Form<?> form,
@@ -93,7 +68,6 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
final List<String> whichPlainAttrs) throws IllegalArgumentException {
super(modelObject, anyTypeClasses, whichPlainAttrs);
- this.mode = mode;
if (modelObject.getInnerObject() instanceof UserTO) {
fileKey = UserTO.class.cast(modelObject.getInnerObject()).getUsername();
@@ -214,12 +188,12 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
attrs.addAll(membershipSchemas.get(membershipTO.getGroupKey()).values().stream().
map(schema -> {
Attr attrTO = new Attr();
- attrTO.setSchema(schema.getKey());
- if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) {
- attrTO.getValues().add(StringUtils.EMPTY);
- } else {
- attrTO.getValues().addAll(attrMap.get(schema.getKey()).getValues());
- }
+ attrTO.setSchema(schema.getKey());
+ if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) {
+ attrTO.getValues().add(StringUtils.EMPTY);
+ } else {
+ attrTO.getValues().addAll(attrMap.get(schema.getKey()).getValues());
+ }
return attrTO;
}).collect(Collectors.toList()));
@@ -227,168 +201,27 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
membershipTO.getPlainAttrs().addAll(attrs);
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
- protected FieldPanel getFieldPanel(final PlainSchemaTO schemaTO) {
- final boolean required;
- final boolean readOnly;
- final AttrSchemaType type;
- final boolean jexlHelp;
-
- if (mode == AjaxWizard.Mode.TEMPLATE) {
- required = false;
- readOnly = false;
- type = AttrSchemaType.String;
- jexlHelp = true;
- } else {
- required = schemaTO.getMandatoryCondition().equalsIgnoreCase("true");
- readOnly = schemaTO.isReadonly();
- type = schemaTO.getType();
- jexlHelp = false;
-
- }
-
- FieldPanel panel;
- switch (type) {
- case Boolean:
- panel = new AjaxCheckBoxPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- true);
- panel.setRequired(required);
- break;
-
- case Date:
- String datePattern = schemaTO.getConversionPattern() == null
- ? SyncopeConstants.DEFAULT_DATE_PATTERN
- : schemaTO.getConversionPattern();
-
- if (datePattern.contains("H")) {
- panel = new AjaxDateTimeFieldPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- FastDateFormat.getInstance(datePattern));
- } else {
- panel = new AjaxDateFieldPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- FastDateFormat.getInstance(datePattern));
- }
-
- if (required) {
- panel.addRequiredLabel();
- }
-
- break;
-
- case Enum:
- panel = new AjaxDropDownChoicePanel<>("panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
- ((AjaxDropDownChoicePanel<String>) panel).setChoices(SchemaUtils.getEnumeratedValues(schemaTO));
-
- if (StringUtils.isNotBlank(schemaTO.getEnumerationKeys())) {
- ((AjaxDropDownChoicePanel) panel).setChoiceRenderer(new IChoiceRenderer<String>() {
-
- private static final long serialVersionUID = -3724971416312135885L;
-
- private final Map<String, String> valueMap = SchemaUtils.getEnumeratedKeyValues(schemaTO);
-
- @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;
- }
- });
- }
-
- if (required) {
- panel.addRequiredLabel();
- }
- break;
-
- case Long:
- panel = new AjaxSpinnerFieldPanel.Builder<Long>().enableOnChange().build(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- Long.class,
- new Model<>());
-
- if (required) {
- panel.addRequiredLabel();
- }
- break;
-
- case Double:
- panel = new AjaxSpinnerFieldPanel.Builder<Double>().enableOnChange().step(0.1).build(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- Double.class,
- new Model<>());
-
- if (required) {
- panel.addRequiredLabel();
- }
- break;
-
- case Binary:
- final PageReference pageRef = getPageReference();
- panel = new BinaryFieldPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- schemaTO.getMimeType(),
- fileKey) {
-
- private static final long serialVersionUID = -3268213909514986831L;
-
- @Override
- protected PageReference getPageReference() {
- return pageRef;
- }
+ protected class PlainSchemasOwn extends PlainSchemas<List<Attr>> {
- };
- if (required) {
- panel.addRequiredLabel();
- }
- break;
+ private static final long serialVersionUID = -4730563859116024676L;
- case Encrypted:
- panel = new EncryptedFieldPanel("panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+ public PlainSchemasOwn(
+ final String id,
+ final Map<String, PlainSchemaTO> schemas,
+ final IModel<List<Attr>> attrTOs) {
- if (required) {
- panel.addRequiredLabel();
- }
- break;
+ super(id, schemas, attrTOs);
- default:
- panel = new AjaxTextFieldPanel("panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+ add(new ListView<Attr>("schemas", attrTOs) {
- if (jexlHelp) {
- AjaxTextFieldPanel.class.cast(panel).enableJexlHelp();
- }
+ private static final long serialVersionUID = 9101744072914090143L;
- if (required) {
- panel.addRequiredLabel();
+ @Override
+ protected void populateItem(final ListItem<Attr> item) {
+ setPanel(schemas, item, false);
}
+ });
}
-
- panel.setReadOnly(readOnly);
-
- return panel;
}
protected class PlainSchemasMemberships extends PlainSchemas<Attributable> {
@@ -442,79 +275,4 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
}
}
- protected class PlainSchemasOwn extends PlainSchemas<List<Attr>> {
-
- private static final long serialVersionUID = -4730563859116024676L;
-
- public PlainSchemasOwn(
- final String id,
- final Map<String, PlainSchemaTO> schemas,
- final IModel<List<Attr>> attrTOs) {
-
- super(id, schemas, attrTOs);
-
- add(new ListView<Attr>("schemas", attrTOs) {
-
- private static final long serialVersionUID = 9101744072914090143L;
-
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected void populateItem(final ListItem<Attr> item) {
- Attr attrTO = item.getModelObject();
-
- AbstractFieldPanel<?> panel = getFieldPanel(schemas.get(attrTO.getSchema()));
- if (mode == AjaxWizard.Mode.TEMPLATE
- || !schemas.get(attrTO.getSchema()).isMultivalue()) {
-
- FieldPanel.class.cast(panel).setNewModel(attrTO.getValues());
- } else {
- // SYNCOPE-1476 set form as multipart to properly manage membership attributes
- panel = new MultiFieldPanel.Builder<>(
- new PropertyModel<>(attrTO, "values")).build(
- "panel",
- attrTO.getSchema(),
- FieldPanel.class.cast(panel)).setFormAsMultipart(true);
- // SYNCOPE-1215 the entire multifield panel must be readonly, not only its field
- ((MultiFieldPanel) panel).setReadOnly(schemas.get(attrTO.getSchema()).isReadonly());
- }
- item.add(panel);
-
- setExternalAction(attrTO, panel);
- }
- });
- }
- }
-
- protected abstract class PlainSchemas<T> extends Schemas {
-
- private static final long serialVersionUID = 8315035592714180404L;
-
- public PlainSchemas(
- final String id,
- final Map<String, PlainSchemaTO> schemas,
- final IModel<T> attrTOs) {
-
- super(id);
- }
-
- protected void setExternalAction(final Attr attrTO, final AbstractFieldPanel<?> panel) {
- Optional<Attr> prevAttr = previousObject == null
- ? Optional.empty()
- : previousObject.getPlainAttr(attrTO.getSchema());
- if (previousObject != null
- && ((prevAttr.isEmpty() && attrTO.getValues().stream().anyMatch(StringUtils::isNotBlank))
- || (prevAttr.isPresent() && !ListUtils.isEqualList(
- prevAttr.get().getValues().stream().
- filter(StringUtils::isNotBlank).collect(Collectors.toList()),
- attrTO.getValues().stream().
- filter(StringUtils::isNotBlank).collect(Collectors.toList()))))) {
-
- List<String> oldValues = prevAttr.isPresent()
- ? prevAttr.get().getValues()
- : List.of();
- panel.showExternAction(new LabelInfo("externalAction", oldValues));
- }
- }
- }
-
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
index a62b5d7..66dce02 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
@@ -112,7 +112,7 @@ public class TypeExtensionWizardBuilder extends BaseAjaxWizardBuilder<TypeExtens
map(EntityTO::getKey).collect(Collectors.toList());
AjaxPalettePanel<String> auxClassesPalette = new AjaxPalettePanel.Builder<String>().build(
"auxClasses.palette",
- new PropertyModel<List<String>>(typeExtensionTO, "auxClasses"),
+ new PropertyModel<>(typeExtensionTO, "auxClasses"),
new ListModel<>(anyTypeClasses));
add(auxClassesPalette.hideLabel().setOutputMarkupId(true));
}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
similarity index 89%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
index d0d803f..dd5288c 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
@@ -18,9 +18,7 @@ under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
- <div id="emptyPlaceholder"/>
- <div id="attributes">
- <wicket:child/>
- </div>
+ <span wicket:id="linkedAccountsList">[linkedAccountsList]</span>
+ <div wicket:id="toggle"/>
</wicket:panel>
</html>
\ No newline at end of file
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.properties
index ebae232..5f28a07 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Resource
+suspended=Suspended
+connObjectKeyValue=External key
+inner.edit.linkedAccount=Edit account
+inner.create.linkedAccount=Create account
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_it.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_it.properties
index ebae232..ce0bcf8 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_it.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Risorsa
+suspended=Sospeso
+connObjectKeyValue=Chiave esterna
+inner.edit.linkedAccount=Modifica account
+inner.create.linkedAccount=Crea account
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ja.properties
similarity index 74%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ja.properties
index ebae232..b825afb 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ja.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u8cc7\u6e90
+suspended=\u4e00\u6642\u505c\u6b62
+connObjectKeyValue=\u5916\u90e8\u30ad\u30fc
+inner.edit.linkedAccount=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u7de8\u96c6
+inner.create.linkedAccount=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u4f5c\u6210\u3059\u308b
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_pt_BR.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_pt_BR.properties
index ebae232..62a2310 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_pt_BR.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Recurso
+suspended=Suspenso
+connObjectKeyValue=Chave externa
+inner.edit.linkedAccount=Editar conta
+inner.create.linkedAccount=Criar Conta
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ru.properties
similarity index 63%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ru.properties
index ebae232..8a337d3 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ru.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u0420\u0435\u0441\u0443\u0440\u0441
+suspended=\u043f\u043e\u0434\u0432\u0435\u0448\u0435\u043d\u043d\u044b\u0439
+connObjectKeyValue=\u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043b\u044e\u0447
+inner.edit.linkedAccount=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u043a\u043a\u0430\u0443\u043d\u0442
+inner.create.linkedAccount=\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
index ebae232..6acf5db 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
@@ -17,3 +17,4 @@
any.edit=Edit ${anyTO.type} ${anyTO.username}
any.propagation.tasks=Propagation tasks for ${type} ${username}
any.notification.tasks=Notification tasks for ${type} ${username}
+linkedAccounts.title=Manage user accounts
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties
index 1b03294..38fa14d 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties
@@ -17,3 +17,4 @@
any.edit=Modifica ${anyTO.type} ${anyTO.username}
any.propagation.tasks=Task di propagazione per ${type} ${username}
any.notification.tasks=Task di notifica per ${type} ${username}
+linkedAccounts.title=Gestisci account utente
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties
index c8baff6..9107368 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties
@@ -17,3 +17,4 @@
any.edit=${anyTO.type} ${anyTO.username} \u3092\u7de8\u96c6
any.propagation.tasks=${type} ${username} \u306e\u4f1d\u64ad\u30bf\u30b9\u30af
any.notification.tasks=${type} ${username} \u306e\u901a\u77e5\u30bf\u30b9\u30af
+linkedAccounts.title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7ba1\u7406\u3059\u308b
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties
index 9498b19..865e74d 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties
@@ -17,3 +17,4 @@
any.edit=Alterar ${anyTO.type} ${anyTO.username}
any.propagation.tasks=Propagation tasks for ${type} ${username}
any.notification.tasks=Notification tasks for ${type} ${username}
+linkedAccounts.title=Gerenciar contas de usu\u00e1rio
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties
index ad11a87..53e0e86 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties
@@ -18,3 +18,4 @@
any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${anyTO.type} ${anyTO.username}
any.propagation.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f ${type} ${username}
any.notification.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f ${type} ${username}
+linkedAccounts.title=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u043c\u0438 \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439
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 e5affd7..6831a2b 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
@@ -233,3 +233,7 @@ zoom_in.alt=zoom-in icon
zoom_out.class=fa fa-search-minus
zoom_out.title=zoom-out
zoom_out.alt=zoom-out icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=manage accounts
+manage_accounts.alt=manage accounts icon
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 d0dbb16..2e13f6e 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
@@ -231,3 +231,7 @@ reconciliation_push.alt=reconciliation push icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=gestisci account
+manage_accounts.alt=manage accounts 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 71156bd..33d593c 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
@@ -231,3 +231,7 @@ reconciliation_push.alt=\u7167\u5408\u30d7\u30c3\u30b7\u30e5 icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=\u30d7\u30eb
reconciliation_pull.alt=\u7167\u5408\u30d7\u30eb icon
+
+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
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 4aedf76..7a61862 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
@@ -231,3 +231,7 @@ reconciliation_push.alt=reconciliation push icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=manage accounts
+manage_accounts.alt=manage accounts icon
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 e7fc2d3..d825127 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
@@ -231,3 +231,7 @@ reconciliation_push.alt=reconciliation push icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=manage accounts
+manage_accounts.alt=manage accounts icon
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
index d0d803f..2c13529 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
@@ -17,10 +17,7 @@ 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 id="emptyPlaceholder"/>
- <div id="attributes">
- <wicket:child/>
- </div>
- </wicket:panel>
+ <wicket:extend>
+ <wicket:child/>
+ </wicket:extend>
</html>
\ No newline at end of file
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep$Schemas.html
similarity index 83%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep$Schemas.html
index d0d803f..f62795a 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep$Schemas.html
@@ -18,9 +18,12 @@ under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
- <div id="emptyPlaceholder"/>
- <div id="attributes">
- <wicket:child/>
+ <div wicket:id="schemas">
+ <div class="form-group">
+ <span wicket:id="panel">
+ [panel for dynamic input type markup]
+ </span>
+ </div>
</div>
</wicket:panel>
</html>
\ No newline at end of file
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.html
similarity index 100%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.html
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.html
similarity index 68%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.html
index e2da0f2..ed2f180 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.html
@@ -19,11 +19,19 @@ under the License.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div class="form-group">
- <span wicket:id="overrideCapabilities">[overrideCapabilities]</span>
- </div>
-
- <div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <div class="box">
+ <div class="box-header with-border">
+ <h3 class="box-title"><wicket:message key="title"/></h3>
+ </div>
+ <div class="box-body">
+ <div id="group-forum">
+ <span wicket:id="username">[username]</span>
+ </div>
+ <div id="group-forum">
+ <span wicket:id="password">[password]</span>
+ </div>
+ </div>
+ </div>
</div>
</wicket:panel>
</html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.properties
index ebae232..387b986 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=Username
+password=Password
+title=Credentials
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_it.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_it.properties
index ebae232..c98ccb0 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_it.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=Username
+password=Password
+title=Credenziali
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ja.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ja.properties
index ebae232..6a73f2a 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ja.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=\u30e6\u30fc\u30b6\u30fc\u540d
+password=\u30d1\u30b9\u30ef\u30fc\u30c9
+title=\u8cc7\u683c\u60c5\u5831
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_pt_BR.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_pt_BR.properties
index ebae232..cbef682 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_pt_BR.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=Username
+password=Password
+title=Credenciais
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ru.properties
similarity index 78%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ru.properties
index ebae232..219c104 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ru.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=\u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+password=\u043f\u0430\u0440\u043e\u043b\u044c
+title=\u043f\u043e\u043b\u043d\u043e\u043c\u043e\u0447\u0438\u044f
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.html
similarity index 67%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.html
index e2da0f2..f2087ab 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.html
@@ -19,11 +19,19 @@ under the License.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div class="form-group">
- <span wicket:id="overrideCapabilities">[overrideCapabilities]</span>
- </div>
-
- <div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <div class="box">
+ <div class="box-header with-border">
+ <h3 class="box-title"><wicket:message key="title"/></h3>
+ </div>
+ <div class="box-body">
+ <div id="group-forum">
+ <span wicket:id="resource">[resource]</span>
+ </div>
+ <div id="group-forum">
+ <span wicket:id="connObjectKeyValue">[connObjectKeyValue]</span>
+ </div>
+ </div>
+ </div>
</div>
</wicket:panel>
</html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.properties
index ebae232..c820770 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Resource
+connObjectKeyValue=Value of the key of the object as on the external resource
+title=Details
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_it.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_it.properties
index ebae232..b098daf 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_it.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Risorsa
+connObjectKeyValue=Valore della chiave dell'oggetto come com'\u00e8 sulla risorsa esterna
+title=Dettagli
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ja.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ja.properties
index ebae232..03d0baa 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ja.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u8cc7\u6e90
+connObjectKeyValue=\u5916\u90e8\u30ea\u30bd\u30fc\u30b9\u4e0a\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30ad\u30fc\u306e\u5024
+title=\u8a73\u7d30
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_pt_BR.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_pt_BR.properties
index ebae232..9d1da54 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_pt_BR.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Recurso
+connObjectKeyValue=Valor da chave do objeto como no recurso externo
+title=Detalhes
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ru.properties
similarity index 67%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ru.properties
index ebae232..bbaba52 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ru.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u0420\u0435\u0441\u0443\u0440\u0441
+connObjectKeyValue=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043a\u0430\u043a \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0435
+title=\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.html
similarity index 86%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.html
index d0d803f..5310309 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.html
@@ -17,10 +17,7 @@ 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 id="emptyPlaceholder"/>
- <div id="attributes">
- <wicket:child/>
- </div>
- </wicket:panel>
+ <wicket:extend>
+ <div wicket:id="plainSchemas"/>
+ </wicket:extend>
</html>
\ No newline at end of file
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.html
similarity index 74%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.html
index e2da0f2..7a9b812 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.html
@@ -19,11 +19,16 @@ under the License.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div class="form-group">
- <span wicket:id="overrideCapabilities">[overrideCapabilities]</span>
- </div>
-
- <div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <div class="box">
+ <div class="box-header with-border">
+ <h3 class="box-title"><wicket:message key="title"/></h3>
+ </div>
+ <div class="box-body">
+ <div id="group-forum">
+ <span wicket:id="privileges">[privileges]</span>
+ </div>
+ </div>
+ </div>
</div>
</wicket:panel>
</html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.properties
index ebae232..5887b81 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=Privileges
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_it.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_it.properties
index ebae232..8b9d8d5 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_it.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=Privilegi
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ja.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ja.properties
index ebae232..c83d230 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ja.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=\u7279\u5178
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_pt_BR.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_pt_BR.properties
index ebae232..2ef9db4 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_pt_BR.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=Privil\u00e9gios
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ru.properties
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ru.properties
index ebae232..4d83a4c 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ru.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=\u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
index eeb654a..b29dce1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
@@ -837,7 +837,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
UTILITY_UI.getTester().executeAjaxEvent(UTILITY_UI.getTester().getComponentFromLastRenderedPage(
"body:content:body:container:content:tabbedPanel:panel:searchResult:outerObjectsRepeater:"
- + "1:outer:container:content:togglePanelContainer:container:actions:actions:actionRepeater:8:"
+ + "1:outer:container:content:togglePanelContainer:container:actions:actions:actionRepeater:9:"
+ "action:action"), Constants.ON_CLICK);
UTILITY_UI.getTester().assertInfoMessages("Operation successfully executed");
@@ -845,7 +845,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
component = UTILITY_UI.findComponentByProp("username",
"body:content:body:container:content:tabbedPanel:panel:searchResult:container:content:"
- + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini_clone");
+ + "searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini_clone");
assertNull(component);
// delete default policy
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
index 59ec6ea..daa617e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
@@ -582,7 +582,7 @@ public class UsersITCase extends AbstractConsoleITCase {
UTILITY_UI.getTester().executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
UTILITY_UI.getTester().assertComponent(TAB_PANEL
+ "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
- + "actions:actions:actionRepeater:8:action:action", IndicatingOnConfirmAjaxLink.class);
+ + "actions:actions:actionRepeater:9:action:action", IndicatingOnConfirmAjaxLink.class);
}
@Test