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 2017/11/24 16:53:08 UTC

syncope git commit: [SYNCOPE-1237] New feature to copy table row element key to clipboard by clicking on its name in toggle menu

Repository: syncope
Updated Branches:
  refs/heads/2_0_X 42445e5f5 -> 0cf558895


[SYNCOPE-1237] New feature to copy table row element key to clipboard by clicking on its name in toggle menu


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/0cf55889
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/0cf55889
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/0cf55889

Branch: refs/heads/2_0_X
Commit: 0cf5588958a51e72d16375db2b72acd3d28e99a3
Parents: 42445e5
Author: skylark17 <ma...@tirasa.net>
Authored: Fri Nov 24 17:52:57 2017 +0100
Committer: skylark17 <ma...@tirasa.net>
Committed: Fri Nov 24 17:52:57 2017 +0100

----------------------------------------------------------------------
 .../client/console/panels/TogglePanel.java      | 136 ++++++++++++++++++-
 .../console/topology/TopologyTogglePanel.java   |   2 +-
 .../html/form/ActionLinksTogglePanel.java       |   6 +-
 .../META-INF/resources/js/copyToClipboard.js    |  65 +++++++++
 .../client/console/panels/TogglePanel.html      |  36 ++++-
 .../console/panels/TogglePanel.properties       |  18 +++
 .../console/panels/TogglePanel_it.properties    |  18 +++
 .../panels/TogglePanel_it_pt_BR.properties      |  18 +++
 .../console/panels/TogglePanel_it_ru.properties |  18 +++
 9 files changed, 305 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
index 62c2af4..afabac0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
@@ -21,7 +21,30 @@ package org.apache.syncope.client.console.panels;
 import java.io.Serializable;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.policies.PolicyRuleDirectoryPanel;
+import org.apache.syncope.client.console.reports.ReportletDirectoryPanel;
+import org.apache.syncope.client.console.topology.TopologyNode;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.any.AnyWrapper;
+import org.apache.syncope.client.console.wizards.any.GroupWrapper;
+import org.apache.syncope.client.console.wizards.any.UserWrapper;
+import org.apache.syncope.client.console.wizards.resources.ResourceProvision;
+import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.AccessTokenTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.to.ExecTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.JobTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.to.SecurityQuestionTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxEventBehavior;
@@ -29,6 +52,7 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.model.ResourceModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,6 +73,25 @@ public abstract class TogglePanel<T extends Serializable> extends WizardMgtPanel
 
     }
 
+    private static final String LABEL_DATA_VALUE = "data-value";
+
+    private enum ToggleMenuCSS {
+        CLASS("toggle-menu"),
+        CLASS_ACTIVE("active-toggle-menu"),
+        CLASS_INACTIVE("active-toggle-menu");
+
+        private final String value;
+
+        ToggleMenuCSS(final String value) {
+            this.value = value;
+        }
+
+        public String value() {
+            return value;
+        }
+
+    }
+
     private final WebMarkupContainer container;
 
     private Status status = Status.INACTIVE;
@@ -64,15 +107,18 @@ public abstract class TogglePanel<T extends Serializable> extends WizardMgtPanel
     public TogglePanel(final String id, final String markupId, final PageReference pageRef) {
         super(id, true);
         this.activeId = markupId;
+        final String containerID = StringUtils.isBlank(markupId) ? id : markupId;
+
         setRenderBodyOnly(true);
         setOutputMarkupId(true);
         disableContainerAutoRefresh();
         setPageRef(pageRef);
 
         container = new WebMarkupContainer("togglePanelContainer");
-        super.addInnerObject(container.setMarkupId(markupId == null ? id : markupId));
+        super.addInnerObject(container.setMarkupId(containerID));
 
         header = new Label("label", StringUtils.EMPTY);
+        header.add(new AttributeModifier("title", new ResourceModel("copy_to_clipboard.title")));
         header.setOutputMarkupId(true);
         container.add(header);
 
@@ -124,6 +170,83 @@ public abstract class TogglePanel<T extends Serializable> extends WizardMgtPanel
         toggle(target, false);
     }
 
+    @SuppressWarnings("cast")
+    private String getTargetKey(final Serializable modelObject) {
+        final String key;
+        if (modelObject == null) {
+            key = new ResourceModel("actions", StringUtils.EMPTY).getObject();
+        } else if (modelObject instanceof UserTO) {
+            key = ((UserTO) modelObject).getKey();
+        } else if (modelObject instanceof UserWrapper) {
+            key = ((UserWrapper) modelObject).getInnerObject().getKey();
+        } else if (modelObject instanceof GroupTO) {
+            key = ((GroupTO) modelObject).getKey();
+        } else if (modelObject instanceof GroupWrapper) {
+            key = ((GroupWrapper) modelObject).getInnerObject().getKey();
+        } else if (modelObject instanceof AnyObjectTO) {
+            key = ((AnyObjectTO) modelObject).getKey();
+        } else if (modelObject instanceof AnyWrapper
+                && AnyWrapper.class.cast(modelObject).getInnerObject() instanceof AnyObjectTO) {
+            key = ((AnyObjectTO) ((AnyWrapper) modelObject).getInnerObject()).getKey();
+        } else if (modelObject instanceof ReportTO) {
+            key = ((ReportTO) modelObject).getKey();
+        } else if (modelObject instanceof AttrTO) {
+            key = ((AttrTO) modelObject).getSchemaInfo().getKey();
+        } else if (modelObject instanceof AbstractPolicyTO) {
+            key = ((AbstractPolicyTO) modelObject).getKey();
+        } else if (modelObject instanceof SecurityQuestionTO) {
+            key = ((SecurityQuestionTO) modelObject).getKey();
+        } else if (modelObject instanceof AccessTokenTO) {
+            key = ((AccessTokenTO) modelObject).getKey();
+        } else if (modelObject instanceof ExecTO) {
+            key = ((ExecTO) modelObject).getKey();
+        } else if (modelObject instanceof WorkflowDefinitionTO) {
+            key = ((WorkflowDefinitionTO) modelObject).getKey();
+        } else if (modelObject instanceof SchedTaskTO) {
+            key = ((SchedTaskTO) modelObject).getKey();
+        } else if (modelObject instanceof WorkflowFormTO) {
+            key = ((WorkflowFormTO) modelObject).getKey();
+        } else if (modelObject instanceof EntityTO) {
+            key = ((EntityTO) modelObject).getKey();
+        } else if (modelObject instanceof StatusBean) {
+            key = ((StatusBean) modelObject).getKey();
+        } else if (modelObject instanceof PolicyRuleDirectoryPanel.PolicyRuleWrapper) {
+            key = ((PolicyRuleDirectoryPanel.PolicyRuleWrapper) modelObject).getName();
+        } else if (modelObject instanceof PolicyRuleDirectoryPanel.PolicyRuleWrapper) {
+            key = ((PolicyRuleDirectoryPanel.PolicyRuleWrapper) modelObject).getName();
+        } else if (modelObject instanceof ReportletDirectoryPanel.ReportletWrapper) {
+            key = ((ReportletDirectoryPanel.ReportletWrapper) modelObject).getName();
+        } else if (modelObject instanceof JobTO) {
+            key = ((JobTO) modelObject).getRefKey() == null
+                    ? ((JobTO) modelObject).getRefDesc() : ((JobTO) modelObject).getRefKey();
+        } else if (modelObject instanceof ResourceProvision) {
+            key = ((ResourceProvision) modelObject).getKey();
+        } else if (modelObject instanceof TopologyNode) {
+            key = ((TopologyNode) modelObject).getKey();
+        } else {
+            key = new ResourceModel("actions", StringUtils.EMPTY).getObject();
+        }
+        return key;
+    }
+
+    private void updateLabelKeyValue(final Serializable modelObject) {
+        header.add(new AttributeModifier(LABEL_DATA_VALUE, getTargetKey(modelObject)));
+    }
+
+    /**
+     * Force toggle via java. To be used when the onclick has been intercepted before.
+     * Also, set key value in label name for copy-to-clipboard feature.
+     *
+     * @param target ajax request target.
+     * @param modelObject model object
+     * @param toggle toggle action.
+     */
+    public void toggle(final AjaxRequestTarget target, final Serializable modelObject, final boolean toggle) {
+        updateLabelKeyValue(modelObject);
+
+        toggle(target, toggle);
+    }
+
     /**
      * Force toggle via java. To be used when the onclick has been intercepted before.
      *
@@ -137,18 +260,21 @@ public abstract class TogglePanel<T extends Serializable> extends WizardMgtPanel
                 target.add(TogglePanel.this.container);
                 target.appendJavaScript(
                         selector + ".toggle(\"slow\");"
-                        + selector + ".attr(\"class\", \"toggle-menu active-toggle-menu\");");
+                        + selector + ".attr(\"class\", \""
+                        + ToggleMenuCSS.CLASS.value() + " " + ToggleMenuCSS.CLASS_ACTIVE.value() + "\");");
                 status = Status.ACTIVE;
             } else if (status == Status.ACTIVE) {
                 // useful when handling action menu after refreshing (ref. SYNCOPE-1134)
                 target.appendJavaScript(
-                        selector + ".not(':visible')" + ".toggle(\"slow\")" + ".removeClass(\"inactive-toggle-menu\")"
-                        + ".addClass(\"active-toggle-menu\");");
+                        selector + ".not(':visible')" + ".toggle(\"slow\")" + ".removeClass(\""
+                        + ToggleMenuCSS.CLASS_INACTIVE.value() + "\")"
+                        + ".addClass(\"" + ToggleMenuCSS.CLASS_ACTIVE.value() + "y\");");
             }
         } else if (status == Status.ACTIVE) {
             target.appendJavaScript(
                     selector + ".toggle(\"slow\");"
-                    + selector + ".attr(\"class\", \"toggle-menu inactive-toggle-menu\");");
+                    + selector + ".attr(\"class\", \""
+                    + ToggleMenuCSS.CLASS.value() + " " + ToggleMenuCSS.CLASS_INACTIVE.value() + "\");");
             status = Status.INACTIVE;
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index 8ffa39a..e0cb0cc 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -156,7 +156,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
 
         target.add(container);
 
-        this.toggle(target, true);
+        toggle(target, node, true);
     }
 
     private Fragment getEmptyFragment() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
index 87f184d..32f3e75 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
@@ -127,7 +127,7 @@ public class ActionLinksTogglePanel<T extends Serializable> extends TogglePanel<
         }
         setHeader(target, StringUtils.abbreviate(header, 25));
     }
-
+        
     public void toggleWithContent(
             final AjaxRequestTarget target, final ActionsPanel<T> actionsPanel, final T modelObject) {
         updateHeader(target, modelObject);
@@ -147,8 +147,8 @@ public class ActionLinksTogglePanel<T extends Serializable> extends TogglePanel<
 
         container.addOrReplace(frag);
         target.add(this.container);
-
-        this.toggle(target, true);
+        
+        toggle(target, modelObject, true);
     }
 
     private Fragment getEmptyFragment() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/resources/META-INF/resources/js/copyToClipboard.js
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/js/copyToClipboard.js b/client/console/src/main/resources/META-INF/resources/js/copyToClipboard.js
new file mode 100644
index 0000000..9598c77
--- /dev/null
+++ b/client/console/src/main/resources/META-INF/resources/js/copyToClipboard.js
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+// Copy to clipboard
+if (typeof copyToClipboard === 'undefined') {
+  copyToClipboard = function (element, tag_value_to_copy, fake_textarea_ID, feedback_selector) {
+    // creating new textarea element and giveing it id 't'
+    var temp = document.createElement('textarea');
+    temp.id = fake_textarea_ID;
+
+    // Optional step to make less noise in the page, if any!
+    temp.style.height = 0;
+
+    // You have to append it to your page somewhere, I chose <body>
+    $(document.body).append(temp);
+
+    // Copy whatever is in your div to our new textarea
+    temp.value = $(element).attr(tag_value_to_copy);
+
+    // Now copy whatever inside the textarea to clipboard
+    var selector = document.querySelector("#" + fake_textarea_ID);
+    selector.select();
+
+    document.execCommand('copy');
+
+    // Remove the textarea
+    $(temp).remove();
+
+    $(feedback_selector).fadeIn();
+
+    // Remove Message of feedback
+    setTimeout(function () {
+      $(feedback_selector).fadeOut();
+    }, 1000);
+  };
+
+  $(document).off('click', '.label-with-key:visible');
+  $(document).on('click', '.label-with-key:visible', function (e) {
+    var feedback_selector = '.copy-clipboard-feedback';
+    var fake_textarea_selector = 'tttt';
+    var tag_value_to_copy = 'data-value';
+
+    if (!$(feedback_selector + ":visible").length) {
+      copyToClipboard(this, tag_value_to_copy, fake_textarea_selector, feedback_selector);
+    }
+    e.stopPropagation();
+  });
+}
+
+

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.html
index 0cdf046..659872a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.html
@@ -31,7 +31,7 @@ under the License.
         min-width: 250px;
         z-index: 999 !important;
       }
-      
+
       .modal-content div.toggle-menu {
         top: 60px !important;
       }
@@ -87,19 +87,49 @@ under the License.
       div.toggle-menu div.header .close {
         text-align: right;
       }
+
+      /* Copy key to clipboard */
+      .copy-clipboard-feedback {
+        position: absolute;
+        top: -30px;
+
+        max-width: 200px;
+        max-height: 30px;
+
+        border-radius: 10px;
+        background: #00a65a;
+        padding: 5px;
+        text-align: center;
+        color: #FFF;
+        text-decoration: none;
+        font-weight: 400;
+        font-size: 14px;
+      }
+      .label-with-key {
+        cursor: pointer;
+      }
     </style>
   </wicket:head>
   <wicket:extend>
     <div wicket:id="togglePanelContainer" class="toggle-menu inactive-toggle-menu">
       <div class="header">
         <div class="label">
-          <label wicket:id="label"/>
+
+          <!-- Copy key to clipboard feedback -->
+          <div class="copy-clipboard-feedback" style="display: none"> 
+            <wicket:message key="copy_to_clipboard.feedback"/>
+          </div>
+          <label wicket:id="label" class="label-with-key"/>
+
         </div>
         <div class="close">
           <a wicket:id="close" href="#"><i class="glyphicon glyphicon-remove"></i></a>
         </div>
       </div>
-      <wicket:child/>
+      <wicket:child/>      
     </div>
+
+    <script type="text/javascript" src="js/copyToClipboard.js"></script>
   </wicket:extend>
 </html>
+

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.properties
new file mode 100644
index 0000000..f13bc1c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+copy_to_clipboard.feedback=Key copied to clipboard!
+copy_to_clipboard.title=Click to copy key to clipboard

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it.properties
new file mode 100644
index 0000000..079a959
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+copy_to_clipboard.feedback=Chiave copiata negli appunti!
+copy_to_clipboard.title=Clicca per copiare la chiave negli appunti

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_pt_BR.properties
new file mode 100644
index 0000000..d3d50f3
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_pt_BR.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+copy_to_clipboard.feedback=Chave copiada para a \u00e1rea de transfer\u00eancia!
+copy_to_clipboard.title=Clique para copiar a tecla para a \u00e1rea de transfer\u00eancia
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/0cf55889/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_ru.properties
new file mode 100644
index 0000000..9d158d7
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/TogglePanel_it_ru.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+copy_to_clipboard.feedback=\u041a\u043b\u044e\u0447 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430!
+copy_to_clipboard.title=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
\ No newline at end of file