mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Get group admin page working with angular and new style
This commit is contained in:
parent
c542116b41
commit
8525bf4a72
7 changed files with 210 additions and 115 deletions
|
@ -231,7 +231,7 @@ block content
|
|||
.row.row-spaced
|
||||
.col-md-12
|
||||
.card.card-thin
|
||||
ul.list-unstyled.project-list(
|
||||
ul.list-unstyled.project-list.structured-list(
|
||||
select-all-list,
|
||||
ng-if="projects.length > 0",
|
||||
ng-cloak
|
||||
|
@ -243,11 +243,11 @@ block content
|
|||
select-all,
|
||||
type="checkbox"
|
||||
)
|
||||
span.title TITLE
|
||||
| TITLE
|
||||
.col-md-2
|
||||
span.owner OWNER
|
||||
| OWNER
|
||||
.col-md-4
|
||||
span.last-modified LAST MODIFIED
|
||||
| LAST MODIFIED
|
||||
li.project_entry.container-fluid(
|
||||
ng-repeat="project in visibleProjects | orderBy:'lastUpdated':true",
|
||||
ng-controller="ProjectListItemController"
|
||||
|
|
|
@ -1,52 +1,84 @@
|
|||
extends ../layout
|
||||
|
||||
block content
|
||||
.container.box
|
||||
.content.content-alt
|
||||
.container
|
||||
.row
|
||||
.span12
|
||||
.col-md-10.col-md-offset-1
|
||||
.card(ng-controller="GroupMembersController")
|
||||
.page-header
|
||||
h2 Group Admin
|
||||
.pull-right(ng-cloak)
|
||||
small(ng-show="selectedUsers.length == 0") You have added <strong>{{ users.length }}</strong> of <strong>{{ groupSize }}</strong> available members
|
||||
a.btn.btn-danger(
|
||||
href,
|
||||
ng-show="selectedUsers.length > 0"
|
||||
ng-click="removeMembers()"
|
||||
) Remove from group
|
||||
h1 Group Account
|
||||
|
||||
div You are allowed up to
|
||||
strong #{subscription.membersLimit}
|
||||
| members in this group
|
||||
.row-spaced-small
|
||||
ul.list-unstyled.structured-list(
|
||||
select-all-list,
|
||||
ng-cloak
|
||||
)
|
||||
li.container-fluid
|
||||
.row
|
||||
.col-md-5
|
||||
input.select-all(
|
||||
select-all,
|
||||
type="checkbox"
|
||||
)
|
||||
span.email EMAIL
|
||||
.col-md-5
|
||||
span.name NAME
|
||||
.col-md-2
|
||||
span.registered REGISTERED
|
||||
li.container-fluid(
|
||||
ng-repeat="user in users | orderBy:'email':true",
|
||||
ng-controller="GroupMemberListItemController"
|
||||
)
|
||||
.row
|
||||
.col-md-5
|
||||
input.select-item(
|
||||
select-individual,
|
||||
type="checkbox",
|
||||
ng-model="user.selected"
|
||||
)
|
||||
span.email {{ user.email }}
|
||||
.col-md-5
|
||||
span.name {{ user.first_name }} {{ user.last_name }}
|
||||
.col-md-2
|
||||
span.registered
|
||||
i.fa.fa-check.text-success(ng-show="!user.holdingAccount")
|
||||
i.fa.fa-times(ng-show="user.holdingAccount")
|
||||
li(
|
||||
ng-if="users.length == 0",
|
||||
ng-cloak
|
||||
)
|
||||
.row
|
||||
.col-md-12.text-centered
|
||||
small No members
|
||||
|
||||
table.table-striped.table.table-striped
|
||||
thead
|
||||
tr
|
||||
th
|
||||
input(type="checkbox").select-all
|
||||
th email
|
||||
th Name
|
||||
th Registered
|
||||
div(ng-if="users.length < groupSize", ng-cloak)
|
||||
hr
|
||||
p
|
||||
.small Add more members
|
||||
form.form
|
||||
.row
|
||||
.col-xs-6
|
||||
input.form-control(
|
||||
name="email",
|
||||
type="text",
|
||||
placeholder="jane@example.com, joe@example.com",
|
||||
ng-model="inputs.emails",
|
||||
on-enter="addMembers()"
|
||||
)
|
||||
.col-xs-6
|
||||
button.btn.btn-primary(ng-click="addMembers()") Add
|
||||
|
||||
tbody#userList
|
||||
-each user in users
|
||||
tr
|
||||
td
|
||||
input(type="checkbox").select-one
|
||||
td #{user.email}
|
||||
td #{user.first_name} #{user.last_name}
|
||||
td #{!user.holdingAccount}
|
||||
td
|
||||
input(type="hidden", name="user_id", value=user._id).user_id {{user._id}}
|
||||
|
||||
|
||||
div
|
||||
button.btn.btn-danger#deleteUsers Delete Selected
|
||||
div
|
||||
div
|
||||
form.well.form-inline#addUserToGroup
|
||||
div
|
||||
input(name="_csrf", type="hidden", value=csrfToken)
|
||||
input(name="email", type="email", placeholder="someone@email.com")#newEmail.email.input-large
|
||||
button.btn.btn-primary.addUser Add
|
||||
div
|
||||
div Add multiple emails seperated with commas or space.
|
||||
|
||||
|
||||
- locals.supressDefaultJs = true
|
||||
script(data-main='/js/SubscriptionGroupsManager.js', src='/js/libs/require.js')
|
||||
script(type="text/javascript").
|
||||
window.users = !{JSON.stringify(users)};
|
||||
window.groupSize = #{subscription.membersLimit};
|
||||
|
||||
|
||||
|
||||
|
|
67
services/web/public/coffee/app/directives/selectAll.coffee
Normal file
67
services/web/public/coffee/app/directives/selectAll.coffee
Normal file
|
@ -0,0 +1,67 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
App.directive "selectAllList", () ->
|
||||
return {
|
||||
controller: ["$scope", ($scope) ->
|
||||
# Selecting or deselecting all should apply to all projects
|
||||
selectAll = () ->
|
||||
$scope.$broadcast "select-all:select"
|
||||
|
||||
deselectAll = () ->
|
||||
$scope.$broadcast "select-all:deselect"
|
||||
|
||||
clearSelectAllState = () ->
|
||||
$scope.$broadcast "select-all:clear"
|
||||
|
||||
return {
|
||||
clearSelectAllState: clearSelectAllState
|
||||
selectAll: selectAll
|
||||
deselectAll: deselectAll
|
||||
}
|
||||
]
|
||||
link: (scope, element, attrs) ->
|
||||
|
||||
|
||||
}
|
||||
|
||||
App.directive "selectAll", () ->
|
||||
return {
|
||||
require: "^selectAllList"
|
||||
link: (scope, element, attrs, selectAllListController) ->
|
||||
scope.$on "select-all:clear", () ->
|
||||
element.prop("checked", false)
|
||||
|
||||
element.change () ->
|
||||
if element.is(":checked")
|
||||
selectAllListController.selectAll()
|
||||
else
|
||||
selectAllListController.deselectAll()
|
||||
return true
|
||||
}
|
||||
|
||||
App.directive "selectIndividual", () ->
|
||||
return {
|
||||
require: "^selectAllList"
|
||||
scope: {
|
||||
ngModel: "="
|
||||
}
|
||||
link: (scope, element, attrs, selectAllListController) ->
|
||||
ignoreChanges = false
|
||||
|
||||
scope.$watch "ngModel", (value) ->
|
||||
if value? and !ignoreChanges
|
||||
selectAllListController.clearSelectAllState()
|
||||
|
||||
scope.$on "select-all:select", () ->
|
||||
ignoreChanges = true
|
||||
scope.$apply () ->
|
||||
scope.ngModel = true
|
||||
ignoreChanges = false
|
||||
|
||||
scope.$on "select-all:deselect", () ->
|
||||
ignoreChanges = true
|
||||
scope.$apply () ->
|
||||
scope.ngModel = false
|
||||
ignoreChanges = false
|
||||
}
|
|
@ -3,12 +3,14 @@ define [
|
|||
"main/user-details"
|
||||
"main/account-settings"
|
||||
"main/plans"
|
||||
"main/group-members"
|
||||
"directives/asyncForm"
|
||||
"directives/stopPropagation"
|
||||
"directives/focus"
|
||||
"directives/equals"
|
||||
"directives/fineUpload"
|
||||
"directives/onEnter"
|
||||
"directives/selectAll"
|
||||
"filters/formatDate"
|
||||
], () ->
|
||||
angular.bootstrap(document.body, ["SharelatexApp"])
|
54
services/web/public/coffee/app/main/group-members.coffee
Normal file
54
services/web/public/coffee/app/main/group-members.coffee
Normal file
|
@ -0,0 +1,54 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
App.controller "GroupMembersController", ($scope, queuedHttp) ->
|
||||
$scope.users = window.users
|
||||
$scope.groupSize = window.groupSize
|
||||
$scope.selectedUsers = []
|
||||
|
||||
$scope.inputs =
|
||||
emails: ""
|
||||
|
||||
parseEmails = (emailsString)->
|
||||
regexBySpaceOrComma = /[\s,]+/
|
||||
emails = emailsString.split(regexBySpaceOrComma)
|
||||
emails = _.map emails, (email)->
|
||||
email = email.trim()
|
||||
emails = _.select emails, (email)->
|
||||
email.indexOf("@") != -1
|
||||
return emails
|
||||
|
||||
$scope.addMembers = () ->
|
||||
emails = parseEmails($scope.inputs.emails)
|
||||
for email in emails
|
||||
queuedHttp
|
||||
.post("/subscription/group/user", {
|
||||
email: email,
|
||||
_csrf: window.csrfToken
|
||||
})
|
||||
.success (data) ->
|
||||
$scope.users.push data.user if data.user?
|
||||
$scope.inputs.emails = ""
|
||||
|
||||
$scope.removeMembers = () ->
|
||||
for user in $scope.selectedUsers
|
||||
do (user) ->
|
||||
queuedHttp({
|
||||
method: "DELETE",
|
||||
url: "/subscription/group/user/#{user._id}"
|
||||
headers:
|
||||
"X-Csrf-Token": window.csrfToken
|
||||
})
|
||||
.success () ->
|
||||
index = $scope.users.indexOf(user)
|
||||
return if index == -1
|
||||
$scope.users.splice(index, 1)
|
||||
$scope.selectedUsers = []
|
||||
|
||||
$scope.updateSelectedUsers = () ->
|
||||
$scope.selectedUsers = $scope.users.filter (user) -> user.selected
|
||||
|
||||
App.controller "GroupMemberListItemController", ($scope) ->
|
||||
$scope.$watch "user.selected", (value) ->
|
||||
if value?
|
||||
$scope.updateSelectedUsers()
|
|
@ -1,71 +1,6 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
App.directive "selectAllList", () ->
|
||||
return {
|
||||
controller: ["$scope", ($scope) ->
|
||||
# Selecting or deselecting all should apply to all projects
|
||||
selectAll = () ->
|
||||
$scope.$broadcast "select-all:select"
|
||||
|
||||
deselectAll = () ->
|
||||
$scope.$broadcast "select-all:deselect"
|
||||
|
||||
clearSelectAllState = () ->
|
||||
$scope.$broadcast "select-all:clear"
|
||||
|
||||
return {
|
||||
clearSelectAllState: clearSelectAllState
|
||||
selectAll: selectAll
|
||||
deselectAll: deselectAll
|
||||
}
|
||||
]
|
||||
link: (scope, element, attrs) ->
|
||||
|
||||
|
||||
}
|
||||
|
||||
App.directive "selectAll", () ->
|
||||
return {
|
||||
require: "^selectAllList"
|
||||
link: (scope, element, attrs, selectAllListController) ->
|
||||
scope.$on "select-all:clear", () ->
|
||||
element.prop("checked", false)
|
||||
|
||||
element.change () ->
|
||||
if element.is(":checked")
|
||||
selectAllListController.selectAll()
|
||||
else
|
||||
selectAllListController.deselectAll()
|
||||
return true
|
||||
}
|
||||
|
||||
App.directive "selectIndividual", () ->
|
||||
return {
|
||||
require: "^selectAllList"
|
||||
scope: {
|
||||
ngModel: "="
|
||||
}
|
||||
link: (scope, element, attrs, selectAllListController) ->
|
||||
ignoreChanges = false
|
||||
|
||||
scope.$watch "ngModel", (value) ->
|
||||
if value? and !ignoreChanges
|
||||
selectAllListController.clearSelectAllState()
|
||||
|
||||
scope.$on "select-all:select", () ->
|
||||
ignoreChanges = true
|
||||
scope.$apply () ->
|
||||
scope.ngModel = true
|
||||
ignoreChanges = false
|
||||
|
||||
scope.$on "select-all:deselect", () ->
|
||||
ignoreChanges = true
|
||||
scope.$apply () ->
|
||||
scope.ngModel = false
|
||||
ignoreChanges = false
|
||||
}
|
||||
|
||||
App.factory "queuedHttp", ["$http", "$q", ($http, $q) ->
|
||||
pendingRequests = []
|
||||
inflight = false
|
||||
|
|
|
@ -68,16 +68,16 @@ form.project-search {
|
|||
}
|
||||
}
|
||||
|
||||
ul.project-list {
|
||||
ul.structured-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
li {
|
||||
border-bottom: 1px solid @gray-lightest;
|
||||
padding: (@line-height-computed / 4) 0;
|
||||
&:first-child {
|
||||
.last-modified, .owner {
|
||||
.header {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +101,11 @@ ul.project-list {
|
|||
.select-item, .select-all {
|
||||
margin-left: @line-height-computed / 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.project-list {
|
||||
li {
|
||||
.last-modified, .owner {
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue