index: Make user choose after login page
@ac01ceeeb798397180d9bf3adf681e0f3f35bf1e
--- app/controllers/Application.java
+++ app/controllers/Application.java
... | ... | @@ -10,7 +10,9 @@ |
10 | 10 |
import controllers.annotation.AnonymousCheck; |
11 | 11 |
import jsmessages.JsMessages; |
12 | 12 |
import models.Project; |
13 |
+import models.User; |
|
13 | 14 |
import models.UserCredential; |
15 |
+import models.UserSetting; |
|
14 | 16 |
import org.apache.commons.lang3.StringUtils; |
15 | 17 |
import play.Logger; |
16 | 18 |
import play.mvc.Controller; |
... | ... | @@ -19,6 +21,7 @@ |
19 | 21 |
import playRepository.RepositoryService; |
20 | 22 |
import views.html.error.notfound_default; |
21 | 23 |
import views.html.index.index; |
24 |
+import views.html.index.notifications; |
|
22 | 25 |
|
23 | 26 |
import static com.feth.play.module.pa.controllers.Authenticate.*; |
24 | 27 |
|
... | ... | @@ -33,9 +36,19 @@ |
33 | 36 |
|
34 | 37 |
@AnonymousCheck |
35 | 38 |
public static Result index() { |
39 |
+ User user = UserApp.currentUser(); |
|
40 |
+ UserSetting userSetting = UserSetting.findByUser(user.id); |
|
41 |
+ if(!user.isAnonymous() && StringUtils.isNotBlank(userSetting.loginDefaultPage)) { |
|
42 |
+ return redirect(userSetting.loginDefaultPage); |
|
43 |
+ } |
|
36 | 44 |
return ok(index.render(UserApp.currentUser())); |
37 | 45 |
} |
38 | 46 |
|
47 |
+ @AnonymousCheck |
|
48 |
+ public static Result notifications() { |
|
49 |
+ return ok(notifications.render(UserApp.currentUser())); |
|
50 |
+ } |
|
51 |
+ |
|
39 | 52 |
public static Result oAuth(final String provider) { |
40 | 53 |
return authenticate(provider); |
41 | 54 |
} |
--- app/controllers/IssueApp.java
+++ app/controllers/IssueApp.java
... | ... | @@ -59,6 +59,11 @@ |
59 | 59 |
} |
60 | 60 |
|
61 | 61 |
@AnonymousCheck(requiresLogin = true, displaysFlashMessage = true) |
62 |
+ public static Result userIssuesPage() throws WriteException, IOException { |
|
63 |
+ return controllers.IssueApp.userIssues("", "html", 1); |
|
64 |
+ } |
|
65 |
+ |
|
66 |
+ @AnonymousCheck(requiresLogin = true, displaysFlashMessage = true) |
|
62 | 67 |
public static Result userIssues(String state, String format, int pageNum) throws WriteException, IOException { |
63 | 68 |
Project project = null; |
64 | 69 |
// SearchCondition from param |
--- app/controllers/UserApp.java
+++ app/controllers/UserApp.java
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 |
import com.feth.play.module.mail.Mailer.Mail.Body; |
16 | 16 |
import com.feth.play.module.pa.PlayAuthenticate; |
17 | 17 |
import controllers.annotation.AnonymousCheck; |
18 |
+import jxl.write.WriteException; |
|
18 | 19 |
import models.*; |
19 | 20 |
import models.enumeration.Operation; |
20 | 21 |
import models.enumeration.UserState; |
... | ... | @@ -44,14 +45,13 @@ |
44 | 45 |
import javax.naming.AuthenticationException; |
45 | 46 |
import javax.naming.CommunicationException; |
46 | 47 |
import javax.naming.NamingException; |
48 |
+import java.io.IOException; |
|
47 | 49 |
import java.util.*; |
48 | 50 |
|
49 | 51 |
import static com.feth.play.module.mail.Mailer.getEmailName; |
50 |
-import static com.feth.play.module.pa.controllers.Authenticate.noCache; |
|
51 | 52 |
import static play.data.Form.form; |
52 | 53 |
import static play.libs.Json.toJson; |
53 | 54 |
import static utils.HtmlUtil.defaultSanitize; |
54 |
-import org.apache.commons.lang3.StringEscapeUtils; |
|
55 | 55 |
|
56 | 56 |
public class UserApp extends Controller { |
57 | 57 |
public static final String SESSION_USERID = "userId"; |
... | ... | @@ -1215,6 +1215,17 @@ |
1215 | 1215 |
} |
1216 | 1216 |
} |
1217 | 1217 |
|
1218 |
+ @AnonymousCheck |
|
1219 |
+ public static Result setDefaultLoginPage() throws IOException, WriteException { |
|
1220 |
+ UserSetting userSetting = UserSetting.findByUser(UserApp.currentUser().id); |
|
1221 |
+ userSetting.loginDefaultPage = request().getQueryString("path"); |
|
1222 |
+ userSetting.save(); |
|
1223 |
+ |
|
1224 |
+ ObjectNode json = Json.newObject(); |
|
1225 |
+ json.put("defaultLoginPage", userSetting.loginDefaultPage); |
|
1226 |
+ return ok(json); |
|
1227 |
+ } |
|
1228 |
+ |
|
1218 | 1229 |
public static Result usermenuTabContentList(){ |
1219 | 1230 |
return ok(views.html.common.usermenu_tab_content_list.render()); |
1220 | 1231 |
} |
+++ app/models/UserSetting.java
... | ... | @@ -0,0 +1,41 @@ |
1 | +/** | |
2 | + * Yona, 21st Century Project Hosting SW | |
3 | + * <p> | |
4 | + * Copyright Yona & Yobi Authors & NAVER Corp. | |
5 | + * https://yona.io | |
6 | + **/ | |
7 | +package models; | |
8 | + | |
9 | +import play.db.ebean.Model; | |
10 | + | |
11 | +import javax.persistence.Entity; | |
12 | +import javax.persistence.Id; | |
13 | +import javax.persistence.OneToOne; | |
14 | + | |
15 | +@Entity | |
16 | +public class UserSetting extends Model { | |
17 | + private static final long serialVersionUID = -2377215889638087516L; | |
18 | + | |
19 | + public static final Model.Finder<Long, UserSetting> find = new Finder<>(Long.class, UserSetting.class); | |
20 | + | |
21 | + @Id | |
22 | + public Long id; | |
23 | + | |
24 | + @OneToOne | |
25 | + public User user; | |
26 | + | |
27 | + public String loginDefaultPage; | |
28 | + | |
29 | + public UserSetting(User user) { | |
30 | + this.user = user; | |
31 | + } | |
32 | + | |
33 | + public static UserSetting findByUser(Long id){ | |
34 | + UserSetting userSetting = find.where().eq("user.id", id).findUnique(); | |
35 | + if (userSetting == null) { | |
36 | + userSetting = new UserSetting(User.find.byId(id)); | |
37 | + } | |
38 | + return userSetting; | |
39 | + } | |
40 | + | |
41 | +} |
--- app/views/common/mySeriesMenuTab.scala.html
+++ app/views/common/mySeriesMenuTab.scala.html
... | ... | @@ -13,8 +13,14 @@ |
13 | 13 |
} |
14 | 14 |
active |
15 | 15 |
} |
16 |
+ |
|
16 | 17 |
<ul class="nav nav-tabs"> |
17 |
- <li @isActive(viewType, TAB_NOTI)><a href="@routes.Application.index()">@Messages("notification")</a></li> |
|
18 |
+ <li @isActive(viewType, TAB_NOTI)><a href="@routes.Application.notifications()">@Messages("notification")</a></li> |
|
18 | 19 |
<li @isActive(viewType, TAB_MY_ISSUES)><a href="@routes.IssueApp.userIssues()">@Messages("issue.myIssue")</a></li> |
19 | 20 |
<li @isActive(viewType, TAB_MY_FILES)><a href="@routes.UserApp.userFiles()">@Messages("user.files")</a></li> |
21 |
+ <li>@if(isActive(viewType, TAB_NOTI) || isActive(viewType, TAB_MY_ISSUES)){ |
|
22 |
+ @if(!requestHeader.path.equals("/") && !requestHeader.path.substring(1).equals(UserSetting.findByUser(UserApp.currentUser().id).loginDefaultPage)){ |
|
23 |
+ <button id="setDefaultLoginPage" type="button" class="ybtn hide-in-mobile" data-url="@requestHeader.path.substring(1)" title="@Messages("button.setDefaultLoginPage")" data-trigger="hover" data-placement="bottom" data-toggle="popover" data-content="@Messages("button.setDefaultLoginPage.desc")">@Messages("button.setDefaultLoginPage")</button> |
|
24 |
+ } |
|
25 |
+ }</li> |
|
20 | 26 |
</ul> |
--- app/views/index/index.scala.html
+++ app/views/index/index.scala.html
... | ... | @@ -10,131 +10,4 @@ |
10 | 10 |
@import utils.JodaDateUtil |
11 | 11 |
@import utils.MenuType._ |
12 | 12 |
|
13 |
-@siteLayout(utils.Config.getSiteName, utils.MenuType.SITE_HOME) { |
|
14 |
- @if(currentUser == User.anonymous){ |
|
15 |
- @partial_intro() |
|
16 |
- } else { |
|
17 |
- <div class="page-wrap-outer"> |
|
18 |
- <div class="page-wrap"> |
|
19 |
- <div class="site-guide-outer hide"> |
|
20 |
- <h3> |
|
21 |
- <span>@Messages("app.welcome",utils.Config.getSiteName) - @Messages("app.description")</span> |
|
22 |
- </h3> |
|
23 |
- <table class="welcome-table table borderless"> |
|
24 |
- <tr> |
|
25 |
- <td> |
|
26 |
- <a href="@routes.ProjectApp.newProjectForm()" class="ybtn ybtn-success"> |
|
27 |
- @Messages("button.newProject") |
|
28 |
- </a> |
|
29 |
- </td> |
|
30 |
- <td>@Messages("app.welcome.project.desc")</td> |
|
31 |
- </tr> |
|
32 |
- <tr> |
|
33 |
- <td> |
|
34 |
- <a href="@routes.OrganizationApp.newForm()" class="ybtn ybtn-success"> |
|
35 |
- @Messages("title.newOrganization") |
|
36 |
- </a> |
|
37 |
- </td> |
|
38 |
- <td>@Messages("app.welcome.group.desc")</td> |
|
39 |
- </tr> |
|
40 |
- <tr> |
|
41 |
- <td> |
|
42 |
- <a href="@routes.ProjectApp.projects()" class="ybtn ybtn-success"> |
|
43 |
- @Messages("title.projectList") |
|
44 |
- </a> |
|
45 |
- </td> |
|
46 |
- <td>@Messages("app.welcome.searchProject.desc")</td> |
|
47 |
- </tr> |
|
48 |
- </table> |
|
49 |
- </div> |
|
50 |
- <div class="guide-toggle"> |
|
51 |
- <button class="btn-transparent" id="toggleIntro"><i class="yobicon-resizev"></i></button> |
|
52 |
- </div> |
|
53 |
- <div class="page on-fold-intro"> |
|
54 |
- <div class="row-fluid content-container"> |
|
55 |
- <div class="span8 main-stream"> |
|
56 |
- @views.html.common.mySeriesMenuTab(TAB_NOTI) |
|
57 |
- <ul class="activity-streams notification-wrap unstyled"> |
|
58 |
- @partial_notifications(0, 20) |
|
59 |
- </ul> |
|
60 |
- </div> |
|
61 |
- <div class="span4 index-menu right-menu span-hard-wrap"> |
|
62 |
- </div> |
|
63 |
- </div> |
|
64 |
- </div> |
|
65 |
- </div> |
|
66 |
- </div> |
|
67 |
- } |
|
68 |
- <script type="text/javascript"> |
|
69 |
- $(document).ready(function(){ |
|
70 |
- $("#toggleIntro").click(function(){ |
|
71 |
- var $outerGuide = $(".site-guide-outer"); |
|
72 |
- $outerGuide.toggleClass("hide"); |
|
73 |
- localStorage.setItem("yobi-intro", !$outerGuide.hasClass("hide")); |
|
74 |
- }); |
|
75 |
- |
|
76 |
- if(localStorage.getItem("yobi-intro") != "false"){ |
|
77 |
- $(".site-guide-outer").removeClass("hide"); |
|
78 |
- } |
|
79 |
- |
|
80 |
- $('.notification-wrap').on('click','[data-toggle="learnmore"]',function(event) { |
|
81 |
- var $this = $(this); |
|
82 |
- $this.find(".more").toggle(); |
|
83 |
- var sTargetId = $this.data('target'), |
|
84 |
- welMessage = $('#'+sTargetId), |
|
85 |
- nHeight; |
|
86 |
- |
|
87 |
- if(event.target.localName =='a' || event.target.localName =='img') { |
|
88 |
- return ; |
|
89 |
- } |
|
90 |
- |
|
91 |
- welMessage.toggleClass('nowrap'); |
|
92 |
- |
|
93 |
- nHeight = (welMessage.hasClass('nowrap')) ? '' : $(welMessage).find('.message').height(); |
|
94 |
- |
|
95 |
- $(welMessage).css('min-height',nHeight); |
|
96 |
- }); |
|
97 |
- |
|
98 |
- function checkOverflow(el) { |
|
99 |
- var curOverflow = el.style.overflow; |
|
100 |
- |
|
101 |
- if (!curOverflow || curOverflow === "visible") |
|
102 |
- el.style.overflow = "hidden"; |
|
103 |
- |
|
104 |
- var isOverflowing = el.clientWidth < el.scrollWidth |
|
105 |
- || el.clientHeight < el.scrollHeight; |
|
106 |
- |
|
107 |
- el.style.overflow = curOverflow; |
|
108 |
- |
|
109 |
- return isOverflowing; |
|
110 |
- } |
|
111 |
- |
|
112 |
- $(".message-wrap").each(function(index, value){ |
|
113 |
- var $this = $(this); |
|
114 |
- if(checkOverflow($this[0])){ |
|
115 |
- $this.after("<div class='more'>...</div>"); |
|
116 |
- } |
|
117 |
- }); |
|
118 |
- |
|
119 |
- // Show side bar menu default and focus to search box |
|
120 |
- // Also, see layout.scala.html for normal user menu click !! |
|
121 |
- var requiredLoggedIn = $("#required-logged-in").length === 1; |
|
122 |
- if(!requiredLoggedIn){ |
|
123 |
- var viewSize = $(window).width(); |
|
124 |
- if( viewSize > 720) { |
|
125 |
- $("#mySidenav").width("420px").css("border", "1px solid #ccc"); |
|
126 |
- setTimeout(function () { |
|
127 |
- $("#main").off("click"); |
|
128 |
- }, 1000); |
|
129 |
- $(".search-input").focus(); |
|
130 |
- } else { |
|
131 |
- $("#mySidenav").width("100vw").css("border", "1px solid #ccc"); |
|
132 |
- } |
|
133 |
- } |
|
134 |
- |
|
135 |
- if ($(".admin-logged-in-affix").length === 1) { |
|
136 |
- $(".sidenav").css("top", "84px"); |
|
137 |
- } |
|
138 |
- }); |
|
139 |
- </script> |
|
140 |
-} |
|
13 |
+@views.html.index.notifications(currentUser) |
+++ app/views/index/notifications.scala.html
... | ... | @@ -0,0 +1,153 @@ |
1 | +@** | |
2 | +* Yona, 21st Century Project Hosting SW | |
3 | +* | |
4 | +* Copyright Yona & Yobi Authors & NAVER Corp. | |
5 | +* https://yona.io | |
6 | +**@ | |
7 | +@(currentUser:models.User) | |
8 | + | |
9 | +@import utils.TemplateHelper._ | |
10 | +@import utils.JodaDateUtil | |
11 | +@import utils.MenuType._ | |
12 | + | |
13 | +@siteLayout(utils.Config.getSiteName, utils.MenuType.SITE_HOME) { | |
14 | + @if(currentUser == User.anonymous){ | |
15 | + @partial_intro() | |
16 | + } else { | |
17 | + <div class="page-wrap-outer"> | |
18 | + <div class="page-wrap"> | |
19 | + <div class="site-guide-outer hide"> | |
20 | + <h3> | |
21 | + <span>@Messages("app.welcome",utils.Config.getSiteName) - @Messages("app.description")</span> | |
22 | + </h3> | |
23 | + <table class="welcome-table table borderless"> | |
24 | + <tr> | |
25 | + <td> | |
26 | + <a href="@routes.ProjectApp.newProjectForm()" class="ybtn ybtn-success"> | |
27 | + @Messages("button.newProject") | |
28 | + </a> | |
29 | + </td> | |
30 | + <td>@Messages("app.welcome.project.desc")</td> | |
31 | + </tr> | |
32 | + <tr> | |
33 | + <td> | |
34 | + <a href="@routes.OrganizationApp.newForm()" class="ybtn ybtn-success"> | |
35 | + @Messages("title.newOrganization") | |
36 | + </a> | |
37 | + </td> | |
38 | + <td>@Messages("app.welcome.group.desc")</td> | |
39 | + </tr> | |
40 | + <tr> | |
41 | + <td> | |
42 | + <a href="@routes.ProjectApp.projects()" class="ybtn ybtn-success"> | |
43 | + @Messages("title.projectList") | |
44 | + </a> | |
45 | + </td> | |
46 | + <td>@Messages("app.welcome.searchProject.desc")</td> | |
47 | + </tr> | |
48 | + </table> | |
49 | + </div> | |
50 | + <div class="guide-toggle"> | |
51 | + <button class="btn-transparent" id="toggleIntro"><i class="yobicon-resizev"></i></button> | |
52 | + </div> | |
53 | + <div class="page on-fold-intro"> | |
54 | + <div class="row-fluid content-container"> | |
55 | + <div class="span8 main-stream"> | |
56 | + @views.html.common.mySeriesMenuTab(TAB_NOTI) | |
57 | + <ul class="activity-streams notification-wrap unstyled"> | |
58 | + @partial_notifications(0, 20) | |
59 | + </ul> | |
60 | + </div> | |
61 | + <div class="span4 index-menu right-menu span-hard-wrap"> | |
62 | + </div> | |
63 | + </div> | |
64 | + </div> | |
65 | + </div> | |
66 | + </div> | |
67 | + } | |
68 | + <script type="text/javascript"> | |
69 | + $(document).ready(function(){ | |
70 | + $("#toggleIntro").click(function(){ | |
71 | + var $outerGuide = $(".site-guide-outer"); | |
72 | + $outerGuide.toggleClass("hide"); | |
73 | + localStorage.setItem("yobi-intro", !$outerGuide.hasClass("hide")); | |
74 | + }); | |
75 | + | |
76 | + if(localStorage.getItem("yobi-intro") != "false"){ | |
77 | + $(".site-guide-outer").removeClass("hide"); | |
78 | + } | |
79 | + | |
80 | + $('.notification-wrap').on('click','[data-toggle="learnmore"]',function(event) { | |
81 | + var $this = $(this); | |
82 | + $this.find(".more").toggle(); | |
83 | + var sTargetId = $this.data('target'), | |
84 | + welMessage = $('#'+sTargetId), | |
85 | + nHeight; | |
86 | + | |
87 | + if(event.target.localName =='a' || event.target.localName =='img') { | |
88 | + return ; | |
89 | + } | |
90 | + | |
91 | + welMessage.toggleClass('nowrap'); | |
92 | + | |
93 | + nHeight = (welMessage.hasClass('nowrap')) ? '' : $(welMessage).find('.message').height(); | |
94 | + | |
95 | + $(welMessage).css('min-height',nHeight); | |
96 | + }); | |
97 | + | |
98 | + function checkOverflow(el) { | |
99 | + var curOverflow = el.style.overflow; | |
100 | + | |
101 | + if (!curOverflow || curOverflow === "visible") | |
102 | + el.style.overflow = "hidden"; | |
103 | + | |
104 | + var isOverflowing = el.clientWidth < el.scrollWidth | |
105 | + || el.clientHeight < el.scrollHeight; | |
106 | + | |
107 | + el.style.overflow = curOverflow; | |
108 | + | |
109 | + return isOverflowing; | |
110 | + } | |
111 | + | |
112 | + $(".message-wrap").each(function(index, value){ | |
113 | + var $this = $(this); | |
114 | + if(checkOverflow($this[0])){ | |
115 | + $this.after("<div class='more'>...</div>"); | |
116 | + } | |
117 | + }); | |
118 | + | |
119 | + // Show side bar menu default and focus to search box | |
120 | + // Also, see layout.scala.html for normal user menu click !! | |
121 | + var requiredLoggedIn = $("#required-logged-in").length === 1; | |
122 | + if(!requiredLoggedIn){ | |
123 | + var viewSize = $(window).width(); | |
124 | + if( viewSize > 720) { | |
125 | + $("#mySidenav").width("420px").css("border", "1px solid #ccc"); | |
126 | + setTimeout(function () { | |
127 | + $("#main").off("click"); | |
128 | + }, 1000); | |
129 | + $(".search-input").focus(); | |
130 | + } else { | |
131 | + $("#mySidenav").width("100vw").css("border", "1px solid #ccc"); | |
132 | + } | |
133 | + } | |
134 | + | |
135 | + if ($(".admin-logged-in-affix").length === 1) { | |
136 | + $(".sidenav").css("top", "84px"); | |
137 | + } | |
138 | + | |
139 | + var $setDefaultLoginPage = $("#setDefaultLoginPage"); | |
140 | + $setDefaultLoginPage.popover(); | |
141 | + $setDefaultLoginPage.on('click', function(){ | |
142 | + $.post("@routes.UserApp.setDefaultLoginPage()?path=" + $setDefaultLoginPage.data("url")) | |
143 | + .done(function (data) { | |
144 | + $yobi.notify("Set to default: " + data.defaultLoginPage, 3000); | |
145 | + $setDefaultLoginPage.hide(); | |
146 | + }) | |
147 | + .fail(function (data) { | |
148 | + $yobi.alert("set Default page failed: " + data); | |
149 | + }); | |
150 | + }); | |
151 | + }); | |
152 | + </script> | |
153 | +} |
--- app/views/issue/my_list.scala.html
+++ app/views/issue/my_list.scala.html
... | ... | @@ -25,7 +25,17 @@ |
25 | 25 |
$(function(){ |
26 | 26 |
$yobi.loadModule("issue.List"); |
27 | 27 |
|
28 |
- |
|
28 |
+ var $setDefaultLoginPage = $("#setDefaultLoginPage"); |
|
29 |
+ $setDefaultLoginPage.on('click', function(){ |
|
30 |
+ $.post("@routes.UserApp.setDefaultLoginPage()?path=" + $setDefaultLoginPage.data("url")) |
|
31 |
+ .done(function (data) { |
|
32 |
+ $yobi.notify("Set to default: " + data.defaultLoginPage, 3000); |
|
33 |
+ $setDefaultLoginPage.hide(); |
|
34 |
+ }) |
|
35 |
+ .fail(function (data) { |
|
36 |
+ $yobi.alert("set Default page failed: " + data); |
|
37 |
+ }); |
|
38 |
+ }); |
|
29 | 39 |
}); |
30 | 40 |
</script> |
31 | 41 |
} |
+++ conf/evolutions/default/14.sql
... | ... | @@ -0,0 +1,14 @@ |
1 | +# --- !Ups | |
2 | +CREATE TABLE user_setting ( | |
3 | + id BIGINT AUTO_INCREMENT NOT NULL, | |
4 | + user_id BIGINT, | |
5 | + login_default_page VARCHAR(255), | |
6 | + CONSTRAINT pk_user_setting PRIMARY KEY (id), | |
7 | + CONSTRAINT fk_user_setting_user FOREIGN KEY (user_id) REFERENCES n4user (id) on DELETE CASCADE | |
8 | +) | |
9 | +row_format=compressed, key_block_size=8; | |
10 | + | |
11 | +CREATE index ix_user_setting_user_1 ON user_setting (user_id); | |
12 | + | |
13 | +# --- !Downs | |
14 | +DROP TABLE user_setting; |
--- conf/messages.ko-KR
+++ conf/messages.ko-KR
... | ... | @@ -71,6 +71,8 @@ |
71 | 71 |
button.save = 저장 |
72 | 72 |
button.selectAll = 전체 선택 |
73 | 73 |
button.selectFile = 파일 선택 |
74 |
+button.setDefaultLoginPage = 기본 페이지로 지정 |
|
75 |
+button.setDefaultLoginPage.desc = 현재 페이지를 로그인 후 표시되는 기본 인덱스 페이지로 지정합니다 |
|
74 | 76 |
button.show.original = 원문 보기 |
75 | 77 |
button.signup = {0} 시작 하기 |
76 | 78 |
button.submitForm = 폼 전송 |
--- conf/routes
+++ conf/routes
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 |
|
8 | 8 |
# Home page |
9 | 9 |
GET / controllers.Application.index() |
10 |
+GET /notifications controllers.Application.notifications() |
|
10 | 11 |
|
11 | 12 |
# Play!Authenticate |
12 | 13 |
GET /logout controllers.Application.oAuthLogout |
... | ... | @@ -48,6 +49,7 @@ |
48 | 49 |
GET /-_-api/v1/favoriteOrganizations controllers.api.UserApi.getFoveriteOrganizations |
49 | 50 |
POST /-_-api/v1/favoriteOrganizations/:organizationId controllers.api.UserApi.toggleFoveriteOrganization(organizationId:String) |
50 | 51 |
GET /-_-api/v1/users controllers.UserApp.users(query: String ?= "") |
52 |
+POST /-_-api/v1/user/defultLoginPage controllers.UserApp.setDefaultLoginPage() |
|
51 | 53 |
|
52 | 54 |
|
53 | 55 |
|
... | ... | @@ -80,6 +82,7 @@ |
80 | 82 |
POST /noti/toggle/:projectId/:notiType controllers.WatchProjectApp.toggle(projectId: Long, notiType) |
81 | 83 |
|
82 | 84 |
# User |
85 |
+GET /user/issues controllers.IssueApp.userIssuesPage() |
|
83 | 86 |
GET /user/issues controllers.IssueApp.userIssues(state:String ?= "", format:String ?= "html", pageNum: Int ?= 1) |
84 | 87 |
GET /user/files controllers.UserApp.userFiles() |
85 | 88 |
GET /users/loginform controllers.UserApp.loginForm() |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?