← 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 8f044fd..c119073 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,
+    MatrixPlatform,
+)
 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", summary=text)
 
     @enabled_with_permission("launchpad.Edit")
+    def editmatrixaccounts(self):
+        target = "+editsocialaccounts-matrix"
+        text = "Update Matrix accounts"
+        return Link(target, text, icon="edit", summary=text)
+
+    @enabled_with_permission("launchpad.Edit")
     def editjabberids(self):
         target = "+editjabberids"
         text = "Update Jabber IDs"
@@ -2419,6 +2430,77 @@ class PersonEditIRCNicknamesView(LaunchpadFormView):
                 )
 
 
+class PersonEditMatrixAccountsView(LaunchpadFormView):
+    schema = Interface
+
+    @property
+    def page_title(self):
+        return smartquote(
+            f"{self.context.displayname}'s {self.platform.title} accounts"
+        )
+
+    label = page_title
+    platform = MatrixPlatform
+
+    @property
+    def cancel_url(self):
+        return canonical_url(self.context)
+
+    # TODO before merge: test this next URL properly when fields are empty
+    @property
+    def next_url(self):
+        return canonical_url(self.context)
+
+    @property
+    def matrix_accounts(self):
+        return self.context.getSocialAccounts(
+            platform=self.platform.platform_type
+        )
+
+    @action(_("Save Changes"), name="save")
+    def save(self, action, data):
+        """Process the social accounts form."""
+        form = self.request.form
+
+        # Update or remove existing accounts
+        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 self.platform.identity_fields
+                }
+                if not all(updated_identity.values()):
+                    self.request.response.addErrorNotification(
+                        "Fields cannot be empty."
+                    )
+                    return
+
+                social_account.identity = updated_identity
+
+        # Add new account
+        new_account_identity = {
+            field_name: form.get(f"new_{field_name}")
+            for field_name in self.platform.identity_fields
+        }
+
+        if all(new_account_identity.values()):
+            getUtility(ISocialAccountSet).new(
+                person=self.context,
+                platform=self.platform.platform_type,
+                identity=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."
+            )
+
+
 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 66003ec..6d1ff92 100644
--- a/lib/lp/registry/interfaces/socialaccount.py
+++ b/lib/lp/registry/interfaces/socialaccount.py
@@ -103,11 +103,13 @@ class ISocialAccountSet(Interface):
 class SocialPlatform:
     title = ""
     identity_fields = []
+    platform_type = None
 
 
 class MatrixPlatform(SocialPlatform):
     title = "Matrix"
     identity_fields = ["username", "homeserver"]
+    platform_type = SocialPlatformType.MATRIX
 
 
 @error_status(http.client.BAD_REQUEST)
diff --git a/lib/lp/registry/model/person.py b/lib/lp/registry/model/person.py
index cac9ab5..001d3cd 100644
--- a/lib/lp/registry/model/person.py
+++ b/lib/lp/registry/model/person.py
@@ -706,6 +706,7 @@ class Person(
     # than one Social Platform Type.
     def getSocialAccounts(self, platform=None):
         if platform:
+            print("SBOOORRROOOOO")
             return list(
                 getUtility(ISocialAccountSet).getByPersonAndSocialPlatform(
                     self, platform
diff --git a/lib/lp/registry/templates/person-editmatrixaccounts.pt b/lib/lp/registry/templates/person-editmatrixaccounts.pt
new file mode 100644
index 0000000..1c7a60b
--- /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>Homeserver</label></td>
+          <td><label>Username</label></td>
+        </tr>
+        <tr tal:repeat="matrix_account view/matrix_accounts">
+          <td>
+            <input tal:attributes="name string:homeserver_${matrix_account/id};
+                                   value matrix_account/identity/homeserver"
+                   type="text" style="margin-bottom: 0.5em;"/>
+          </td>
+          <td>
+            <input type="text"
+                   tal:attributes="name string:username_${matrix_account/id};
+                                   value matrix_account/identity/username" />
+          </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_homeserver"
+                 type="text"
+                 placeholder="Enter new homeserver"
+                 tal:attributes="value view/new_homeserver|nothing" />
+        </td>
+        <td>
+          <input name="new_username"
+                 type="text"
+                 placeholder="Enter new username"
+                 tal:attributes="value view/new_username|nothing" />
+        </td>
+      </tr>
+
+      <tr>
+        <td class="formHelp">Example: ubuntu.com</td>
+        <td class="formHelp">Example: mark</td>
+      </tr>
+    </table>
+  </div>
+</div>
+</div>
+
+</body>
+</html>

Follow ups