Skip to content

Commit

Permalink
Use AJAX for notifications table
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Thornton <art27@cantab.net>
  • Loading branch information
zeripath committed Apr 21, 2020
1 parent 74cc3c5 commit 2d23ad7
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 95 deletions.
29 changes: 23 additions & 6 deletions routers/user/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package user
import (
"errors"
"fmt"
"net/http"
"strconv"
"strings"

Expand All @@ -17,7 +18,8 @@ import (
)

const (
tplNotification base.TplName = "user/notification/notification"
tplNotification base.TplName = "user/notification/notification"
tplNotificationDiv = "user/notification/notification_div"
)

// GetNotificationCount is the middleware that sets the notification count in the context
Expand All @@ -41,6 +43,14 @@ func GetNotificationCount(c *context.Context) {

// Notifications is the notifications page
func Notifications(c *context.Context) {
getNotifications(c)
if c.Written() {
return
}
c.HTML(http.StatusOK, tplNotification)
}

func getNotifications(c *context.Context) {
var (
keyword = strings.Trim(c.Query("q"), " ")
status models.NotificationStatus
Expand Down Expand Up @@ -126,8 +136,6 @@ func Notifications(c *context.Context) {

pager.SetDefaultParams(c)
c.Data["Page"] = pager

c.HTML(200, tplNotification)
}

// NotificationStatusPost is a route for changing the status of a notification
Expand Down Expand Up @@ -155,8 +163,17 @@ func NotificationStatusPost(c *context.Context) {
return
}

url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, c.Query("page"))
c.Redirect(url, 303)
if !c.QueryBool("noredirect") {
url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, c.Query("page"))
c.Redirect(url, http.StatusSeeOther)
}

getNotifications(c)
if c.Written() {
return
}

c.HTML(http.StatusOK, tplNotificationDiv)
}

// NotificationPurgePost is a route for 'purging' the list of notifications - marking all unread as read
Expand All @@ -168,5 +185,5 @@ func NotificationPurgePost(c *context.Context) {
}

url := fmt.Sprintf("%s/notifications", setting.AppSubURL)
c.Redirect(url, 303)
c.Redirect(url, http.StatusSeeOther)
}
90 changes: 1 addition & 89 deletions templates/user/notification/notification.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,95 +23,7 @@
</form>
{{end}}
</div>
<div class="ui bottom attached active tab segment">
{{if eq (len .Notifications) 0}}
{{if eq .Status 1}}
{{.i18n.Tr "notification.no_unread"}}
{{else}}
{{.i18n.Tr "notification.no_read"}}
{{end}}
{{else}}
<table class="ui unstackable striped very compact small selectable table">
<tbody>
{{range $notification := .Notifications}}
{{$issue := $notification.Issue}}
{{$repo := $notification.Repository}}
{{$repoOwner := $repo.MustOwner}}

<tr data-href="{{$notification.HTMLURL}}">
<td class="collapsing">
{{if eq $notification.Status 3}}
<span class="blue">{{svg "octicon-pin" 16}}</span>
{{else if $issue.IsPull}}
{{if $issue.IsClosed}}
{{if $issue.GetPullRequest.HasMerged}}
<span class="purple">{{svg "octicon-git-merge" 16}}</span>
{{else}}
<span class="red">{{svg "octicon-git-pull-request" 16}}</span>
{{end}}
{{else}}
<span class="green">{{svg "octicon-git-pull-request" 16}}</span>
{{end}}
{{else}}
{{if $issue.IsClosed}}
<span class="red">{{svg "octicon-issue-closed" 16}}</span>
{{else}}
<span class="green">{{svg "octicon-issue-opened" 16}}</span>
{{end}}
{{end}}
</td>
<td class="eleven wide">
<a class="item" href="{{$notification.HTMLURL}}">
#{{$issue.Index}} - {{$issue.Title}}
</a>
</td>
<td>
<a class="item" href="{{AppSubUrl}}/{{$repoOwner.Name}}/{{$repo.Name}}">
{{$repoOwner.Name}}/{{$repo.Name}}
</a>
</td>
<td class="collapsing">
{{if ne $notification.Status 3}}
<form action="{{AppSubUrl}}/notifications/status" method="POST">
{{$.CsrfTokenHtml}}
<input type="hidden" name="notification_id" value="{{$notification.ID}}" />
<input type="hidden" name="status" value="pinned" />
<button class="ui mini button" title='{{$.i18n.Tr "notification.pin"}}'>
{{svg "octicon-pin" 16}}
</button>
</form>
{{end}}
</td>
<td class="collapsing">
{{if or (eq $notification.Status 1) (eq $notification.Status 3)}}
<form action="{{AppSubUrl}}/notifications/status" method="POST">
{{$.CsrfTokenHtml}}
<input type="hidden" name="notification_id" value="{{$notification.ID}}" />
<input type="hidden" name="status" value="read" />
<input type="hidden" name="page" value="{{$.Page.Paginater.Current}}" />
<button class="ui mini button" title='{{$.i18n.Tr "notification.mark_as_read"}}'>
{{svg "octicon-check" 16}}
</button>
</form>
{{else if eq $notification.Status 2}}
<form action="{{AppSubUrl}}/notifications/status" method="POST">
{{$.CsrfTokenHtml}}
<input type="hidden" name="notification_id" value="{{$notification.ID}}" />
<input type="hidden" name="status" value="unread" />
<input type="hidden" name="page" value="{{$.Page.Paginater.Current}}" />
<button class="ui mini button" title='{{$.i18n.Tr "notification.mark_as_unread"}}'>
{{svg "octicon-bell" 16}}
</button>
</form>
{{end}}
</td>
</tr>
{{end}}
</tbody>
</table>
{{end}}
</div>

{{template "user/notification/notification_div" .}}
{{template "base/paginate" .}}
</div>
</div>
Expand Down
102 changes: 102 additions & 0 deletions templates/user/notification/notification_div.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<div class="ui bottom attached active tab segment" id="notification_div">
{{if eq (len .Notifications) 0}}
{{if eq .Status 1}}
{{.i18n.Tr "notification.no_unread"}}
{{else}}
{{.i18n.Tr "notification.no_read"}}
{{end}}
{{else}}
<table class="ui unstackable striped very compact small selectable table" id="notification_table">
<tbody>
{{range $notification := .Notifications}}
{{$issue := .Issue}}
{{$repo := .Repository}}
{{$repoOwner := $repo.MustOwner}}
<tr id="notification_{{.ID}}">
<td class="collapsing" data-href="{{.HTMLURL}}">
{{if eq .Status 3}}
<span class="blue">{{svg "octicon-pin" 16}}</span>
{{else if $issue.IsPull}}
{{if $issue.IsClosed}}
{{if $issue.GetPullRequest.HasMerged}}
<span class="purple">{{svg "octicon-git-merge" 16}}</span>
{{else}}
<span class="red">{{svg "octicon-git-pull-request" 16}}</span>
{{end}}
{{else}}
<span class="green">{{svg "octicon-git-pull-request" 16}}</span>
{{end}}
{{else}}
{{if $issue.IsClosed}}
<span class="red">{{svg "octicon-issue-closed" 16}}</span>
{{else}}
<span class="green">{{svg "octicon-issue-opened" 16}}</span>
{{end}}
{{end}}
</td>
<td class="eleven wide" data-href="{{.HTMLURL}}">
<a class="item" href="{{.HTMLURL}}">
#{{$issue.Index}} - {{$issue.Title}}
</a>
</td>
<td data-href="{{AppSubUrl}}/{{$repoOwner.Name}}/{{$repo.Name}}">
<a class="item" href="{{AppSubUrl}}/{{$repoOwner.Name}}/{{$repo.Name}}">
{{$repoOwner.Name}}/{{$repo.Name}}
</a>
</td>
<td class="collapsing">
{{if ne .Status 3}}
<form action="{{AppSubUrl}}/notifications/status" method="POST">
{{$.CsrfTokenHtml}}
<input type="hidden" name="notification_id" value="{{.ID}}" />
<input type="hidden" name="status" value="pinned" />
<button class="ui mini button" title='{{$.i18n.Tr "notification.pin"}}'
data-url="{{AppSubUrl}}/notifications/status"
data-status="pinned"
data-page="{{$.Page.Paginater.Current}}"
data-notification-id="{{.ID}}"
data-q="{{$.Keyword}}">
{{svg "octicon-pin" 16}}
</button>
</form>
{{end}}
</td>
<td class="collapsing">
{{if or (eq .Status 1) (eq .Status 3)}}
<form action="{{AppSubUrl}}/notifications/status" method="POST">
{{$.CsrfTokenHtml}}
<input type="hidden" name="notification_id" value="{{.ID}}" />
<input type="hidden" name="status" value="read" />
<input type="hidden" name="page" value="{{$.Page.Paginater.Current}}" />
<button class="ui mini button" title='{{$.i18n.Tr "notification.mark_as_read"}}'
data-url="{{AppSubUrl}}/notifications/status"
data-status="read"
data-page="{{$.Page.Paginater.Current}}"
data-notification-id="{{.ID}}"
data-q="{{$.Keyword}}">
{{svg "octicon-check" 16}}
</button>
</form>
{{else if eq .Status 2}}
<form action="{{AppSubUrl}}/notifications/status" method="POST">
{{$.CsrfTokenHtml}}
<input type="hidden" name="notification_id" value="{{.ID}}" />
<input type="hidden" name="status" value="unread" />
<input type="hidden" name="page" value="{{$.Page.Paginater.Current}}" />
<button class="ui mini button" title='{{$.i18n.Tr "notification.mark_as_unread"}}'
data-url="{{AppSubUrl}}/notifications/status"
data-status="unread"
data-page="{{$.Page.Paginater.Current}}"
data-notification-id="{{.ID}}"
data-q="{{$.Keyword}}">
{{svg "octicon-bell" 16}}
</button>
</form>
{{end}}
</td>
</tr>
{{end}}
</tbody>
</table>
{{end}}
</div>
46 changes: 46 additions & 0 deletions web_src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,46 @@ function updateIssuesMeta(url, action, issueIds, elementId, isAdd) {
}));
}

function initNotificationsTable() {
const $notificationTable = $('#notification_table');
if ($notificationTable) {
$notificationTable.find('.button').click(function () {
updateNotification(
$(this).data('url'),
$(this).data('status'),
$(this).data('page'),
$(this).data('q'),
$(this).data('notification-id')
).then((data) => {
$('#notification_div').replaceWith(data);
initNotificationsTable();
});
return false;
});
}
}

function updateNotification(url, status, page, q, notificationID) {
return new Promise(((resolve) => {
if (status != "pinned") {
$(`#notification_${notificationID}`).remove();
}
$.ajax({
type: 'POST',
url,
data: {
_csrf: csrf,
notification_id: notificationID,
status,
page,
q,
noredirect: true,
},
success: resolve
});
}));
}

function initRepoStatusChecker() {
const migrating = $('#repo_migrating');
$('#repo_migrating_failed').hide();
Expand Down Expand Up @@ -2431,6 +2471,11 @@ $(document).ready(async () => {
window.location = $(this).data('href');
});

// make table <td> element clickable like a link
$('td[data-href]').click(function () {
window.location = $(this).data('href');
});

// Dropzone
const $dropzone = $('#dropzone');
if ($dropzone.length > 0) {
Expand Down Expand Up @@ -2606,6 +2651,7 @@ $(document).ready(async () => {
initRepoStatusChecker();
initTemplateSearch();
initContextPopups();
initNotificationsTable();

// Repo clone url.
if ($('#repo-clone-url').length > 0) {
Expand Down

0 comments on commit 2d23ad7

Please sign in to comment.