]> source.dussan.org Git - gitea.git/commitdiff
Add modals to Organization and Team remove/leave (#16471)
authorzeripath <art27@cantab.net>
Fri, 27 Aug 2021 02:57:40 +0000 (03:57 +0100)
committerGitHub <noreply@github.com>
Fri, 27 Aug 2021 02:57:40 +0000 (22:57 -0400)
* Add modals to Organization and Team remove/leave

Add confirmation modals to Organization and Team remove and leave.

Fix #16215

Signed-off-by: Andrew Thornton <art27@cantab.net>
* avoid for-in

Signed-off-by: Andrew Thornton <art27@cantab.net>
* Revert "avoid for-in"

This reverts commit 2af9a6f9d46ed31b6fc6e3a29e695577dcf09f75.

* Apply suggestions from code review

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
19 files changed:
options/locale/locale_en-US.ini
routers/web/org/members.go
routers/web/org/teams.go
templates/org/member/members.tmpl
templates/org/team/members.tmpl
templates/org/team/sidebar.tmpl
templates/org/team/teams.tmpl
templates/user/settings/account.tmpl
templates/user/settings/applications.tmpl
templates/user/settings/applications_oauth2.tmpl
templates/user/settings/grants_oauth2.tmpl
templates/user/settings/keys_gpg.tmpl
templates/user/settings/keys_principal.tmpl
templates/user/settings/keys_ssh.tmpl
templates/user/settings/security_accountlinks.tmpl
templates/user/settings/security_openid.tmpl
templates/user/settings/security_twofa.tmpl
templates/user/settings/security_u2f.tmpl
web_src/js/index.js

index 0a030b9b0530f8fc71d06d8e04871512089cafef..76536f2d497523783ab2bce59f38d0d9419b1a06 100644 (file)
@@ -2176,12 +2176,15 @@ members.member_role = Member Role:
 members.owner = Owner
 members.member = Member
 members.remove = Remove
+members.remove.detail = Remove %[1]s from %[2]s?
 members.leave = Leave
+members.leave.detail = Leave %s?
 members.invite_desc = Add a new member to %s:
 members.invite_now = Invite Now
 
 teams.join = Join
 teams.leave = Leave
+teams.leave.detail = Leave %s?
 teams.can_create_org_repo = Create repositories
 teams.can_create_org_repo_helper = Members can create new repositories in organization. Creator will get administrator access to the new repository.
 teams.read_access = Read Access
index 84aaa28f6053070498f91a774f3e13c25729d387..ef5a69e157272839150afd479af8f4ea0b4709c0 100644 (file)
@@ -99,14 +99,18 @@ func MembersAction(ctx *context.Context) {
                err = org.RemoveMember(uid)
                if models.IsErrLastOrgOwner(err) {
                        ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
-                       ctx.Redirect(ctx.Org.OrgLink + "/members")
+                       ctx.JSON(http.StatusOK, map[string]interface{}{
+                               "redirect": ctx.Org.OrgLink + "/members",
+                       })
                        return
                }
        case "leave":
                err = org.RemoveMember(ctx.User.ID)
                if models.IsErrLastOrgOwner(err) {
                        ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
-                       ctx.Redirect(ctx.Org.OrgLink + "/members")
+                       ctx.JSON(http.StatusOK, map[string]interface{}{
+                               "redirect": ctx.Org.OrgLink + "/members",
+                       })
                        return
                }
        }
@@ -120,9 +124,12 @@ func MembersAction(ctx *context.Context) {
                return
        }
 
-       if ctx.Params(":action") != "leave" {
-               ctx.Redirect(ctx.Org.OrgLink + "/members")
-       } else {
-               ctx.Redirect(setting.AppSubURL + "/")
+       redirect := ctx.Org.OrgLink + "/members"
+       if ctx.Params(":action") == "leave" {
+               redirect = setting.AppSubURL + "/"
        }
+
+       ctx.JSON(http.StatusOK, map[string]interface{}{
+               "redirect": redirect,
+       })
 }
index 4725f19b3dbda3c5f49faa494799249097d9ee41..c93fcd062b5a8903624e55952b3c78deded28aa6 100644 (file)
@@ -66,6 +66,23 @@ func TeamsAction(ctx *context.Context) {
                err = ctx.Org.Team.AddMember(ctx.User.ID)
        case "leave":
                err = ctx.Org.Team.RemoveMember(ctx.User.ID)
+               if err != nil {
+                       if models.IsErrLastOrgOwner(err) {
+                               ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
+                       } else {
+                               log.Error("Action(%s): %v", ctx.Params(":action"), err)
+                               ctx.JSON(http.StatusOK, map[string]interface{}{
+                                       "ok":  false,
+                                       "err": err.Error(),
+                               })
+                               return
+                       }
+               }
+               ctx.JSON(http.StatusOK,
+                       map[string]interface{}{
+                               "redirect": ctx.Org.OrgLink + "/teams/",
+                       })
+               return
        case "remove":
                if !ctx.Org.IsOwner {
                        ctx.Error(http.StatusNotFound)
@@ -73,6 +90,23 @@ func TeamsAction(ctx *context.Context) {
                }
                err = ctx.Org.Team.RemoveMember(uid)
                page = "team"
+               if err != nil {
+                       if models.IsErrLastOrgOwner(err) {
+                               ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
+                       } else {
+                               log.Error("Action(%s): %v", ctx.Params(":action"), err)
+                               ctx.JSON(http.StatusOK, map[string]interface{}{
+                                       "ok":  false,
+                                       "err": err.Error(),
+                               })
+                               return
+                       }
+               }
+               ctx.JSON(http.StatusOK,
+                       map[string]interface{}{
+                               "redirect": ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName,
+                       })
+               return
        case "add":
                if !ctx.Org.IsOwner {
                        ctx.Error(http.StatusNotFound)
index 0952d127666da7c15a7c92b7aa5c14b0e1a30bbc..ecb535d570cae08c545583451122012ff8729774 100644 (file)
                                        <div class="ui four wide column">
                                                <div class="text right">
                                                        {{if eq $.SignedUser.ID .ID}}
-                                                               <form method="post" action="{{$.OrgLink}}/members/action/leave">
-                                                                       {{$.CsrfTokenHtml}}
-                                                                       <button type="submit" class="ui red small button" name="uid" value="{{.ID}}">{{$.i18n.Tr "org.members.leave"}}</button>
+                                                               <form>
+                                                                       <button class="ui red small button delete-button" data-modal-id="leave-organization"
+                                                                               data-url="{{$.OrgLink}}/members/action/leave" data-datauid="{{.ID}}"
+                                                                               data-name="{{.DisplayName}}"
+                                                                               data-data-organization-name="{{$.Org.DisplayName}}">{{$.i18n.Tr "org.members.leave"}}</button>
                                                                </form>
                                                        {{else if $.IsOrganizationOwner}}
-                                                               <form method="post" action="{{$.OrgLink}}/members/action/remove">
-                                                                       {{$.CsrfTokenHtml}}
-                                                                       <button type="submit" class="ui red small button" name="uid" value="{{.ID}}">{{$.i18n.Tr "org.members.remove"}}</button>
+                                                               <form>
+                                                                       <button class="ui red small button delete-button" data-modal-id="remove-organization-member"
+                                                                               data-url="{{$.OrgLink}}/members/action/remove" data-datauid="{{.ID}}"
+                                                                               data-name="{{.DisplayName}}"
+                                                                               data-data-organization-name="{{$.Org.DisplayName}}">{{$.i18n.Tr "org.members.remove"}}</button>
                                                                </form>
                                                        {{end}}
                                                </div>
                {{template "base/paginate" .}}
        </div>
 </div>
+<div class="ui small basic delete modal" id="leave-organization">
+       <div class="ui icon header">
+               {{svg "octicon-x" 16 "close inside"}}
+               {{$.i18n.Tr "org.members.leave"}}
+       </div>
+       <div class="content">
+               <p>{{$.i18n.Tr "org.members.leave.detail" `<span class="dataOrganizationName"></span>` | Safe}}</p>
+       </div>
+       {{template "base/delete_modal_actions" .}}
+</div>
+<div class="ui small basic delete modal" id="remove-organization-member">
+       <div class="ui icon header">
+               {{svg "octicon-x" 16 "close inside"}}
+               {{$.i18n.Tr "org.members.remove"}}
+       </div>
+       <div class="content">
+               <p>{{$.i18n.Tr "org.members.remove.detail" `<span class="name"></span>` `<span class="dataOrganizationName"></span>` | Safe}}</p>
+       </div>
+       {{template "base/delete_modal_actions" .}}
+</div>
+
 {{template "base/footer" .}}
index bfc151d00046ad0f12a17f94fe441cded4b66f31..f2c89e065364abc19f19007f449cb1a5109666e9 100644 (file)
                                <div class="ui bottom attached table segment members">
                                        {{range .Team.Members}}
                                                <div class="item">
-                                                       {{if $.IsOrganizationOwner}}
-                                                               <form method="post" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/remove">
-                                                                       {{$.CsrfTokenHtml}}
-                                                                       <button type="submit" class="ui red small button right" name="uid" value="{{.ID}}">{{$.i18n.Tr "org.members.remove"}}</button>
+                                                       {{if and $.IsOrganizationOwner (not (eq $.SignedUser.ID .ID))}}
+                                                               <form>
+                                                                       <button class="ui red button delete-button right" data-modal-id="remove-team-member"
+                                                                               data-url="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/remove" data-datauid="{{.ID}}"
+                                                                               data-name="{{.DisplayName}}"
+                                                                               data-data-team-name="{{$.Team.Name}}">{{$.i18n.Tr "org.members.remove"}}</button>
                                                                </form>
                                                        {{end}}
                                                        <a href="{{.HomeLink}}">
                </div>
        </div>
 </div>
+<div class="ui small basic delete modal" id="remove-team-member">
+       <div class="ui icon header">
+               {{svg "octicon-x" 16 "close inside"}}
+               {{$.i18n.Tr "org.members.remove"}}
+       </div>
+       <div class="content">
+               <p>{{$.i18n.Tr "org.members.remove.detail" `<span class="name"></span>` `<span class="dataTeamName"></span>` | Safe}}</p>
+       </div>
+       {{template "base/delete_modal_actions" .}}
+</div>
 {{template "base/footer" .}}
index 9ab6e8f4cd7f3046b093b87c6693cd4094425ff5..84729a08416136a77801c0bc770b3fa8e0420bdf 100644 (file)
@@ -3,10 +3,10 @@
                <strong>{{.Team.Name}}</strong>
                <div class="ui right">
                        {{if .Team.IsMember $.SignedUser.ID}}
-                               <form method="post" action="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave">
-                                       {{$.CsrfTokenHtml}}
-                                       <input type="hidden" name="page" value="home"/>
-                                       <button type="submit" class="ui red tiny button" name="uid" value="{{$.SignedUser.ID}}">{{$.i18n.Tr "org.teams.leave"}}</button>
+                               <form>
+                                       <button class="ui red tiny button delete-button" data-modal-id="leave-team-sidebar"
+                                               data-url="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave" data-datauid="{{$.SignedUser.ID}}"
+                                               data-name="{{.Team.Name}}">{{$.i18n.Tr "org.teams.leave"}}</button>
                                </form>
                        {{else if .IsOrganizationOwner}}
                                <form method="post" action="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/join">
                </div>
        {{end}}
 </div>
+<div class="ui small basic delete modal" id="leave-team-sidebar">
+       <div class="ui icon header">
+               {{svg "octicon-x" 16 "close inside"}}
+               {{$.i18n.Tr "org.teams.leave"}}
+       </div>
+       <div class="content">
+               <p>{{$.i18n.Tr "org.teams.leave.detail" `<span class="name"></span>` | Safe}}</p>
+       </div>
+       {{template "base/delete_modal_actions" .}}
+</div>
index 4e877bef2a1a4e27765ab0d5bbab04b688675d33..6f4f155072f7110e5e2a865654ee324696da6153 100644 (file)
                                                <a class="text black" href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a>
                                                <div class="ui right">
                                                        {{if .IsMember $.SignedUser.ID}}
-                                                               <form method="post" action="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave">
-                                                                       {{$.CsrfTokenHtml}}
-                                                                       <button type="submit" class="ui red small button" name="uid" value="{{$.SignedUser.ID}}">{{$.i18n.Tr "org.teams.leave"}}</button>
+                                                               <form>
+                                                                       <button class="ui red tiny button delete-button" data-modal-id="leave-team"
+                                                                               data-url="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave" data-datauid="{{$.SignedUser.ID}}"
+                                                                               data-name="{{.Name}}">{{$.i18n.Tr "org.teams.leave"}}</button>
                                                                </form>
                                                        {{else if $.IsOrganizationOwner}}
                                                                <form method="post" action="{{$.OrgLink}}/teams/{{.LowerName}}/action/join">
                </div>
        </div>
 </div>
+<div class="ui small basic delete modal" id="leave-team">
+       <div class="ui icon header">
+               {{svg "octicon-x" 16 "close inside"}}
+               {{$.i18n.Tr "org.teams.leave"}}
+       </div>
+       <div class="content">
+               <p>{{$.i18n.Tr "org.teams.leave.detail" `<span class="name"></span>` | Safe}}</p>
+       </div>
+       {{template "base/delete_modal_actions" .}}
+</div>
 {{template "base/footer" .}}
index 2e1976aaa95771d515a172a66ba1f093b6c6a92e..0468eb7e2a93fa2a4a9b9ee75f65f12ceb4984e5 100644 (file)
@@ -72,7 +72,7 @@
                                        <div class="item">
                                                {{if not .IsPrimary}}
                                                        <div class="right floated content">
-                                                               <button class="ui red tiny button delete-button" id="delete-email" data-url="{{AppSubUrl}}/user/settings/account/email/delete" data-id="{{.ID}}">
+                                                               <button class="ui red tiny button delete-button" data-modal-id="delete-email" data-url="{{AppSubUrl}}/user/settings/account/email/delete" data-id="{{.ID}}">
                                                                        {{$.i18n.Tr "settings.delete_email"}}
                                                                </button>
                                                        </div>
                                        <input id="password-confirmation" name="password" type="password" autocomplete="off" required>
                                </div>
                                <div class="field">
-                                       <div class="ui red button delete-button" id="delete-account" data-type="form" data-form="#delete-form">
+                                       <div class="ui red button delete-button" data-modal-id="delete-account" data-type="form" data-form="#delete-form">
                                                {{.i18n.Tr "settings.confirm_delete_account"}}
                                        </div>
                                        <a href="{{AppSubUrl}}/user/forgot_password?email={{.Email}}">{{.i18n.Tr "auth.forgot_password"}}</a>
index 0455b5e221bfcc2b6be4d7e04c7de64608b6a0df..811ce5d64397b36ab6ee3f448822b968e575de8d 100644 (file)
@@ -14,7 +14,7 @@
                                {{range .Tokens}}
                                        <div class="item">
                                                <div class="right floated content">
-                                                               <button class="ui red tiny button delete-button" id="delete-token" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
+                                                               <button class="ui red tiny button delete-button" data-modal-id="delete-token" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
                                                                        {{svg "octicon-trash" 16 "mr-2"}}
                                                                        {{$.i18n.Tr "settings.delete_token"}}
                                                                </button>
index 4de3f27ec3079eb3dd4039eec1cb44a8b21e8ead..8218674bce6116d3eeb6989810f995f1ea6093f8 100644 (file)
@@ -13,7 +13,7 @@
                                                {{svg "octicon-pencil" 16 "mr-2"}}
                                                {{$.i18n.Tr "settings.oauth2_application_edit"}}
                                        </a>
-                                       <button class="ui red tiny button delete-button" id="remove-gitea-oauth2-application"
+                                       <button class="ui red tiny button delete-button" data-modal-id="remove-gitea-oauth2-application"
                                                        data-url="{{AppSubUrl}}/user/settings/applications/oauth2/delete"
                                                        data-id="{{$app.ID}}">
                                                {{svg "octicon-trash" 16 "mr-2"}}
index cf24252ededc97c37a1ee0bac41afa26cf6ec711..35a851ff367fc5fb23d76bedc61a070b6b75e811 100644 (file)
@@ -9,7 +9,7 @@
                {{range $grant := .Grants}}
                        <div class="item">
                                <div class="right floated content">
-                                       <button class="ui red tiny button delete-button" id="revoke-gitea-oauth2-grant"
+                                       <button class="ui red tiny button delete-button" data-modal-id="revoke-gitea-oauth2-grant"
                                                        data-url="{{AppSubUrl}}/user/settings/applications/oauth2/revoke"
                                                        data-id="{{$grant.ID}}">
                                                {{$.i18n.Tr "settings.revoke_key"}}
index 2d80d481564067c16ec9758824c9127ba5b2d9db..c840801e5acb61e9b3f1ea4327b37ad8bc0e2712 100644 (file)
@@ -12,7 +12,7 @@
                {{range .GPGKeys}}
                        <div class="item">
                                <div class="right floated content">
-                                       <button class="ui red tiny button delete-button" id="delete-gpg" data-url="{{$.Link}}/delete?type=gpg" data-id="{{.ID}}">
+                                       <button class="ui red tiny button delete-button" data-modal-id="delete-gpg" data-url="{{$.Link}}/delete?type=gpg" data-id="{{.ID}}">
                                                {{$.i18n.Tr "settings.delete_key"}}
                                        </button>
                                        {{if and (not .Verified) (ne $.VerifyingID .KeyID)}}
index e8057c7cf3414e8ff432e4900682c45811550ec9..9d8ebab609b9339cf7d0e8ab314aa2623434bd1a 100644 (file)
@@ -17,7 +17,7 @@
                        {{range .Principals}}
                                <div class="item">
                                        <div class="right floated content">
-                                               <button class="ui red tiny button delete-button" id="delete-principal" data-url="{{$.Link}}/delete?type=principal" data-id="{{.ID}}">
+                                               <button class="ui red tiny button delete-button" data-modal-id="delete-principal" data-url="{{$.Link}}/delete?type=principal" data-id="{{.ID}}">
                                                        {{$.i18n.Tr "settings.delete_key"}}
                                                </button>
                                        </div>
index 62e697ad19ec91cf1d0e61d866a836a7c32ccdde..3d05578666c3a91b8b77ba14c4f821d57de9b858 100644 (file)
@@ -16,7 +16,7 @@
                {{range $index, $key := .Keys}}
                        <div class="item">
                                <div class="right floated content">
-                                       <button class="ui red tiny button delete-button{{if index $.ExternalKeys $index}} disabled{{end}}" id="delete-ssh" data-url="{{$.Link}}/delete?type=ssh" data-id="{{.ID}}"{{if index $.ExternalKeys $index}} title="{{$.i18n.Tr "settings.ssh_externally_managed"}}"{{end}}>
+                                       <button class="ui red tiny button delete-button{{if index $.ExternalKeys $index}} disabled{{end}}" data-modal-id="delete-ssh" data-url="{{$.Link}}/delete?type=ssh" data-id="{{.ID}}"{{if index $.ExternalKeys $index}} title="{{$.i18n.Tr "settings.ssh_externally_managed"}}"{{end}}>
                                                {{$.i18n.Tr "settings.delete_key"}}
                                        </button>
                                </div>
index 5aa9282083b61a599f790bdd6ab77cefb6dc1297..7a9935d031def2464ad2322f32caa3b6d0760cc9 100644 (file)
@@ -10,7 +10,7 @@
                {{range $loginSource, $provider := .AccountLinks}}
                        <div class="item">
                                <div class="right floated content">
-                                               <button class="ui red tiny button delete-button" id="delete-account-link" data-url="{{AppSubUrl}}/user/settings/security/account_link" data-id="{{$loginSource.ID}}">
+                                               <button class="ui red tiny button delete-button" data-modal-id="delete-account-link" data-url="{{AppSubUrl}}/user/settings/security/account_link" data-id="{{$loginSource.ID}}">
                                                        {{$.i18n.Tr "settings.delete_key"}}
                                                </button>
                                </div>
index 118f16203d0dcee87e9587bd4f8fda40db8c6689..2a167a712b2477f0d00ce02f71fa4b60cbecd288 100644 (file)
@@ -9,7 +9,7 @@
                {{range .OpenIDs}}
                        <div class="item">
                                <div class="right floated content">
-                                               <button class="ui red tiny button delete-button" id="delete-openid" data-url="{{AppSubUrl}}/user/settings/security/openid/delete" data-id="{{.ID}}">
+                                               <button class="ui red tiny button delete-button" data-modal-id="delete-openid" data-url="{{AppSubUrl}}/user/settings/security/openid/delete" data-id="{{.ID}}">
                                                        {{$.i18n.Tr "settings.delete_key"}}
                                                </button>
                                </div>
index 860bfdf569c01f4db306abbed33d98b7a47e9638..f48b2f4cb22700058f2f2268151efab2689e4014 100644 (file)
@@ -13,7 +13,7 @@
        <form class="ui form" action="{{AppSubUrl}}/user/settings/security/two_factor/disable" method="post" enctype="multipart/form-data" id="disable-form">
                {{.CsrfTokenHtml}}
                <p>{{.i18n.Tr "settings.twofa_disable_note"}}</p>
-               <div class="ui red button delete-button" id="disable-twofa" data-type="form" data-form="#disable-form">{{$.i18n.Tr "settings.twofa_disable"}}</div>
+               <div class="ui red button delete-button" data-modal-id="disable-twofa" data-type="form" data-form="#disable-form">{{$.i18n.Tr "settings.twofa_disable"}}</div>
        </form>
        {{else}}
        <p>{{.i18n.Tr "settings.twofa_not_enrolled"}}</p>
index dcc56d8729ffa5265e9e59a4f1f79ed684aa31bf..8fe01d8c70156e9b1093648850851c01b239241f 100644 (file)
@@ -8,7 +8,7 @@
                        {{range .U2FRegistrations}}
                                <div class="item">
                                        <div class="right floated content">
-                                               <button class="ui red tiny button delete-button" id="delete-registration" data-url="{{$.Link}}/u2f/delete" data-id="{{.ID}}">
+                                               <button class="ui red tiny button delete-button" data-modal-id="delete-registration" data-url="{{$.Link}}/u2f/delete" data-id="{{.ID}}">
                                                {{$.i18n.Tr "settings.delete_key"}}
                                                </button>
                                        </div>
index d349092717b577c5335470c4e2d51f08684b4f53..7e4970c3a062b8558923189196c080d953e01b4b 100644 (file)
@@ -2956,13 +2956,19 @@ $(() => {
 
 function showDeletePopup() {
   const $this = $(this);
+  const dataArray = $this.data();
   let filter = '';
-  if ($this.attr('id')) {
-    filter += `#${$this.attr('id')}`;
+  if ($this.data('modal-id')) {
+    filter += `#${$this.data('modal-id')}`;
   }
 
   const dialog = $(`.delete.modal${filter}`);
   dialog.find('.name').text($this.data('name'));
+  for (const [key, value] of Object.entries(dataArray)) {
+    if (key && key.startsWith('data')) {
+      dialog.find(`.${key}`).text(value);
+    }
+  }
 
   dialog.modal({
     closable: false,
@@ -2972,10 +2978,19 @@ function showDeletePopup() {
         return;
       }
 
-      $.post($this.data('url'), {
+      const postData = {
         _csrf: csrf,
-        id: $this.data('id')
-      }).done((data) => {
+      };
+      for (const [key, value] of Object.entries(dataArray)) {
+        if (key && key.startsWith('data')) {
+          postData[key.substr(4)] = value;
+        }
+        if (key === 'id') {
+          postData['id'] = value;
+        }
+      }
+
+      $.post($this.data('url'), postData).done((data) => {
         window.location.href = data.redirect;
       });
     }