← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~ines-almeida/launchpad:social-accounts-edit-view into launchpad:master

 

Ines Almeida has proposed merging ~ines-almeida/launchpad:social-accounts-edit-view into launchpad:master with ~pelpsi/launchpad:social-account-interface-and-implementation as a prerequisite.

Commit message:
ui: Add edit matrix accounts view

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~ines-almeida/launchpad/+git/launchpad/+merge/458537

This adds a new view: https://launchpad.net/~<username>/+editsocialaccounts-matrix

This view allows users to add, edit or remove their matrix accounts.

(Update to view the matrix accounts in the profile will go in a separate MP)
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~ines-almeida/launchpad:social-accounts-edit-view into launchpad:master.
diff --git a/lib/lp/registry/browser/configure.zcml b/lib/lp/registry/browser/configure.zcml
index 046db06..eaf8e17 100644
--- a/lib/lp/registry/browser/configure.zcml
+++ b/lib/lp/registry/browser/configure.zcml
@@ -1219,6 +1219,13 @@
         template="../templates/person-editircnicknames.pt"
         />
     <browser:page
+        name="+editsocialaccounts-matrix"
+        for="lp.registry.interfaces.person.IPerson"
+        class="lp.registry.browser.person.PersonEditMatrixAccountsView"
+        permission="launchpad.Edit"
+        template="../templates/person-editmatrixaccounts.pt"
+        />
+    <browser:page
         name="+editjabberids"
         for="lp.registry.interfaces.person.IPerson"
         class="lp.registry.browser.person.PersonEditJabberIDsView"
diff --git a/lib/lp/registry/browser/person.py b/lib/lp/registry/browser/person.py
index 65ae0ba..b247e59 100644
--- a/lib/lp/registry/browser/person.py
+++ b/lib/lp/registry/browser/person.py
@@ -19,6 +19,7 @@ __all__ = [
     "PersonEditEmailsView",
     "PersonEditIRCNicknamesView",
     "PersonEditJabberIDsView",
+    "PersonEditMatrixAccountsView",
     "PersonEditTimeZoneView",
     "PersonEditSSHKeysView",
     "PersonEditView",
@@ -152,7 +153,10 @@ from lp.registry.interfaces.persontransferjob import (
 from lp.registry.interfaces.pillar import IPillarNameSet
 from lp.registry.interfaces.poll import IPollSubset
 from lp.registry.interfaces.product import InvalidProductName, IProduct
-from lp.registry.interfaces.socialaccount import ISocialAccountSet
+from lp.registry.interfaces.socialaccount import (
+    ISocialAccountSet,
+    SocialPlatform,
+)
 from lp.registry.interfaces.ssh import ISSHKeySet, SSHKeyAdditionError
 from lp.registry.interfaces.teammembership import (
     ITeamMembershipSet,
@@ -824,6 +828,7 @@ class PersonOverviewMenu(
         "editmailinglists",
         "editircnicknames",
         "editjabberids",
+        "editmatrixaccounts",
         "editsshkeys",
         "editpgpkeys",
         "editlocation",
@@ -889,6 +894,12 @@ class PersonOverviewMenu(
         return Link(target, text, icon="edit")
 
     @enabled_with_permission("launchpad.Edit")
+    def editmatrixaccounts(self):
+        target = "+editsocialaccounts-matrix"
+        text = "Update Matrix accounts"
+        return Link(target, text, icon="edit")
+
+    @enabled_with_permission("launchpad.Edit")
     def editjabberids(self):
         target = "+editjabberids"
         text = "Update Jabber IDs"
@@ -2415,6 +2426,69 @@ class PersonEditIRCNicknamesView(LaunchpadFormView):
                 )
 
 
+class PersonEditMatrixAccountsView(LaunchpadFormView):
+    schema = Interface
+
+    @property
+    def page_title(self):
+        return smartquote(f"{self.context.displayname}'s Matrix accounts")
+
+    label = page_title
+
+    @property
+    def cancel_url(self):
+        return canonical_url(self.context)
+
+    @property
+    def matrix_accounts(self):
+        accounts = []
+        for account in self.context.social_accounts:
+            if account.platform == SocialPlatform.MATRIX:
+                accounts.append(account)
+        return accounts
+
+    @action(_("Save Changes"), name="save")
+    def save(self, action, data):
+        """Process the matrix accounts form."""
+        form = self.request.form
+        for social_account in self.matrix_accounts:
+            if form.get(f"remove_{social_account.id}"):
+                social_account.destroySelf()
+
+            else:
+                updated_identity = {
+                    field: form.get(f"{field}_{social_account.id}")
+                    for field in SocialPlatform.matrix_identity_fields
+                }
+                if not all(updated_identity.values()):
+                    self.request.response.addErrorNotification(
+                        "Fields cannot be empty."
+                    )
+                    return
+
+                social_account.identity = updated_identity
+
+        new_account_identity = {
+            field_name: form.get(f"new_{field_name}")
+            for field_name in SocialPlatform.matrix_identity_fields
+        }
+
+        if all(new_account_identity.values()):
+            getUtility(ISocialAccountSet).new(
+                self.context, SocialPlatform.MATRIX, new_account_identity
+            )
+
+        elif any(new_account_identity.values()):
+            for field_key, field_value in new_account_identity.items():
+                self.__setattr__(f"new_{field_key}", field_value)
+            self.request.response.addErrorNotification(
+                "All fields must be filled."
+            )
+
+        # Clean the cached social_accounts if form is saved
+        del get_property_cache(self.context).social_accounts
+
+
 class PersonEditJabberIDsView(LaunchpadFormView):
     schema = IJabberID
     field_names = ["jabberid"]
diff --git a/lib/lp/registry/interfaces/socialaccount.py b/lib/lp/registry/interfaces/socialaccount.py
index 7e910cc..e8c219e 100644
--- a/lib/lp/registry/interfaces/socialaccount.py
+++ b/lib/lp/registry/interfaces/socialaccount.py
@@ -40,6 +40,7 @@ class SocialPlatform(DBEnumeratedType):
         The Social Account will hold Matrix account info.
         """,
     )
+    matrix_identity_fields = ["nickname", "network"]
 
 
 # XXX pelpsi 2023-12-14 bug=760849: "beta" is a lie to get WADL generation
diff --git a/lib/lp/registry/templates/person-editmatrixaccounts.pt b/lib/lp/registry/templates/person-editmatrixaccounts.pt
new file mode 100644
index 0000000..7d8e659
--- /dev/null
+++ b/lib/lp/registry/templates/person-editmatrixaccounts.pt
@@ -0,0 +1,73 @@
+<html
+  xmlns="http://www.w3.org/1999/xhtml";
+  xmlns:tal="http://xml.zope.org/namespaces/tal";
+  xmlns:metal="http://xml.zope.org/namespaces/metal";
+  xmlns:i18n="http://xml.zope.org/namespaces/i18n";
+  metal:use-macro="view/macro:page/main_only"
+  i18n:domain="launchpad"
+>
+<body>
+
+<div metal:fill-slot="main">
+<div metal:use-macro="context/@@launchpad_form/form">
+  <div metal:fill-slot="widgets">
+
+    <p tal:condition="view/error_message"
+       tal:content="structure view/error_message/escapedtext" class="error message" />
+
+    <table>
+
+      <div tal:condition="view/matrix_accounts">
+        <tr>
+          <td><label>Network:</label></td>
+          <td><label>Nickname:</label></td>
+        </tr>
+        <tr tal:repeat="matrix_account view/matrix_accounts">
+          <td>
+            <input tal:attributes="name string:network_${matrix_account/id};
+                                   value matrix_account/identity/network"
+                   type="text" style="margin-bottom: 0.5em;"/>
+          </td>
+          <td>
+            <input type="text"
+                   tal:attributes="name string:nickname_${matrix_account/id};
+                                   value matrix_account/identity/nickname" />
+          </td>
+
+          <td>
+            <label>
+              <input type="checkbox"
+                     value="Remove"
+                     tal:attributes="name string:remove_${matrix_account/id}" />
+              Remove
+            </label>
+          </td>
+        </tr>
+      </div>
+
+      <tr>
+        <td>
+          <input name="new_network"
+                 type="text"
+                 placeholder="Enter new network"
+                 tal:attributes="value view/new_network|nothing" />
+        </td>
+        <td>
+          <input name="new_nickname" 
+                 type="text"
+                 placeholder="Enter new nickname"
+                 tal:attributes="value view/new_nickname|nothing" />
+        </td>
+      </tr>
+
+      <tr>
+        <td class="formHelp">Example: ubuntu.com</td>
+        <td class="formHelp">Example: mark</td>
+      </tr>
+    </table>
+  </div>
+</div>
+</div>
+
+</body>
+</html>

References