mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Allow creation of new tags
This commit is contained in:
parent
4494048cd4
commit
290089407d
3 changed files with 160 additions and 47 deletions
|
@ -35,6 +35,7 @@ html(itemscope, itemtype='http://schema.org/Product')
|
||||||
script(src=jsPath+'libs/angular-1.2.17.js')
|
script(src=jsPath+'libs/angular-1.2.17.js')
|
||||||
script(src=jsPath+'libs/moment.js')
|
script(src=jsPath+'libs/moment.js')
|
||||||
script(src=jsPath+'libs/bootstrap.js')
|
script(src=jsPath+'libs/bootstrap.js')
|
||||||
|
script(src=jsPath+'libs/ui-bootstrap-0.11.0.js')
|
||||||
block scripts
|
block scripts
|
||||||
|
|
||||||
- if (typeof(bodyClasses) == "undefined")
|
- if (typeof(bodyClasses) == "undefined")
|
||||||
|
|
|
@ -10,10 +10,6 @@ block scripts
|
||||||
script(src=jsPath+'project-list.js')
|
script(src=jsPath+'project-list.js')
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
|
||||||
script(type="text/x-handlebars", data-template-name="projects")
|
|
||||||
|
|
||||||
|
|
||||||
.content.content-alt(ng-app="ProjectPageApp", ng-controller="ProjectPageController")
|
.content.content-alt(ng-app="ProjectPageApp", ng-controller="ProjectPageController")
|
||||||
.container
|
.container
|
||||||
.row
|
.row
|
||||||
|
@ -53,9 +49,15 @@ block content
|
||||||
//- a.menu-indent(href="#") Shared with you
|
//- a.menu-indent(href="#") Shared with you
|
||||||
li
|
li
|
||||||
h2 Folders
|
h2 Folders
|
||||||
li(ng-repeat="tag in tags", ng-controller="TagListItemController", ng-class="{active: tag.selected}")
|
li(
|
||||||
|
ng-repeat="tag in tags",
|
||||||
|
ng-controller="TagListItemController",
|
||||||
|
ng-class="{active: tag.selected}"
|
||||||
|
)
|
||||||
a.menu-indent(href="#", ng-click="selectTag()")
|
a.menu-indent(href="#", ng-click="selectTag()")
|
||||||
i.icon.fa(ng-class="{'fa-folder-open-o': tag.selected, 'fa-folder-o': !tag.selected}")
|
i.icon.fa(
|
||||||
|
ng-class="{'fa-folder-open-o': tag.selected, 'fa-folder-o': !tag.selected}"
|
||||||
|
)
|
||||||
| {{tag.name}}
|
| {{tag.name}}
|
||||||
span.small ({{tag.project_ids.length}})
|
span.small ({{tag.project_ids.length}})
|
||||||
|
|
||||||
|
@ -76,29 +78,61 @@ block content
|
||||||
.col-md-12
|
.col-md-12
|
||||||
form.project-search.form-horizontal(role="form")
|
form.project-search.form-horizontal(role="form")
|
||||||
.form-group.has-feedback.col-md-7
|
.form-group.has-feedback.col-md-7
|
||||||
input(placeholder='Search projects…', autofocus='autofocus', ng-model="searchText").form-control.col-md-7
|
input.form-control.col-md-7(
|
||||||
|
placeholder='Search projects…',
|
||||||
|
autofocus='autofocus',
|
||||||
|
ng-model="searchText"
|
||||||
|
)
|
||||||
i.fa.fa-search.form-control-feedback
|
i.fa.fa-search.form-control-feedback
|
||||||
//- i.fa.fa-remove
|
//- i.fa.fa-remove
|
||||||
|
|
||||||
.project-tools.js-toggle-tools
|
.project-tools.js-toggle-tools
|
||||||
.btn-toolbar
|
.btn-toolbar
|
||||||
.btn-group
|
.btn-group
|
||||||
a.btn.btn-default(href='#', data-toggle="tooltip", data-placement="bottom", title="", data-original-title="Download")
|
a.btn.btn-default(
|
||||||
|
href='#',
|
||||||
|
data-original-title="Download",
|
||||||
|
data-toggle="tooltip",
|
||||||
|
data-placement="bottom",
|
||||||
|
title=""
|
||||||
|
)
|
||||||
i.fa.fa-cloud-download
|
i.fa.fa-cloud-download
|
||||||
a.btn.btn-default(href='#', data-toggle="tooltip", data-placement="bottom", title="", data-original-title="Delete")
|
a.btn.btn-default(
|
||||||
|
href='#',
|
||||||
|
data-original-title="Delete",
|
||||||
|
data-toggle="tooltip",
|
||||||
|
data-placement="bottom",
|
||||||
|
title=""
|
||||||
|
)
|
||||||
i.fa.fa-trash-o
|
i.fa.fa-trash-o
|
||||||
|
|
||||||
.btn-group
|
.btn-group
|
||||||
a.btn.btn-default.dropdown-toggle(href="#", data-toggle="dropdown")
|
a.btn.btn-default.dropdown-toggle(
|
||||||
|
href="#",
|
||||||
|
data-toggle="dropdown"
|
||||||
|
)
|
||||||
i.fa.fa-folder-open-o
|
i.fa.fa-folder-open-o
|
||||||
|
|
|
|
||||||
span.caret
|
span.caret
|
||||||
ul.dropdown-menu.dropdown-menu-right(role="menu")
|
ul.dropdown-menu.dropdown-menu-right.js-tags-dropdown-menu(
|
||||||
|
role="menu"
|
||||||
|
)
|
||||||
li.dropdown-header Add to folder
|
li.dropdown-header Add to folder
|
||||||
li(ng-repeat="tag in tags", ng-controller="TagDropdownItemController")
|
li(
|
||||||
a.menu-indent(href="#", ng-click="addOrRemoveProjectsFromTag()")
|
ng-repeat="tag in tags | orderBy:'name'",
|
||||||
i.fa.fa-check(ng-if="areSelectedProjectsInTag")
|
ng-controller="TagDropdownItemController"
|
||||||
|
)
|
||||||
|
a(href="#", ng-click="addOrRemoveProjectsFromTag()")
|
||||||
|
i.fa(
|
||||||
|
ng-class="{\
|
||||||
|
'fa-check-square-o': areSelectedProjectsInTag,\
|
||||||
|
'fa-square-o': !areSelectedProjectsInTag\
|
||||||
|
}"
|
||||||
|
)
|
||||||
| {{tag.name}}
|
| {{tag.name}}
|
||||||
|
li.divider
|
||||||
|
li
|
||||||
|
a(href="#", ng-click="openNewTagModal()") Create New Folder
|
||||||
|
|
||||||
.btn-group
|
.btn-group
|
||||||
a.btn.btn-default.dropdown-toggle(data-toggle="dropdown", href="#") More
|
a.btn.btn-default.dropdown-toggle(data-toggle="dropdown", href="#") More
|
||||||
|
@ -126,7 +160,10 @@ block content
|
||||||
span.owner OWNER
|
span.owner OWNER
|
||||||
.col-md-4
|
.col-md-4
|
||||||
span.last-modified LAST MODIFIED
|
span.last-modified LAST MODIFIED
|
||||||
li.project_entry.container-fluid(ng-repeat="project in visibleProjects", ng-controller="ProjectListItemController")
|
li.project_entry.container-fluid(
|
||||||
|
ng-repeat="project in visibleProjects | orderBy:'lastUpdated':true",
|
||||||
|
ng-controller="ProjectListItemController"
|
||||||
|
)
|
||||||
.row
|
.row
|
||||||
.col-md-6
|
.col-md-6
|
||||||
input.select-item(type="checkbox", ng-model="project.selected", ng-change="onSelectedChange()")
|
input.select-item(type="checkbox", ng-model="project.selected", ng-change="onSelectedChange()")
|
||||||
|
@ -148,3 +185,19 @@ block content
|
||||||
| or
|
| or
|
||||||
a(href="/learn") help guides
|
a(href="/learn") help guides
|
||||||
| .
|
| .
|
||||||
|
|
||||||
|
script(type='text/ng-template', id='newTagModalTemplate')
|
||||||
|
.modal-header
|
||||||
|
h3 Create New Folder
|
||||||
|
.modal-body
|
||||||
|
div {{inputs.newTagName}}
|
||||||
|
input.form-control(
|
||||||
|
type="text",
|
||||||
|
placeholder="New Folder Name",
|
||||||
|
ng-model="inputs.newTagName",
|
||||||
|
ng-enter="create()",
|
||||||
|
ng-focus-on="open"
|
||||||
|
)
|
||||||
|
.modal-footer
|
||||||
|
button.btn.btn-default(ng-click="cancel()") Cancel
|
||||||
|
button.btn.btn-primary(ng-click="create()") Create
|
|
@ -1,10 +1,30 @@
|
||||||
window.ProjectPageApp = angular.module("ProjectPageApp", [])
|
window.ProjectPageApp = angular.module("ProjectPageApp", ['ui.bootstrap'])
|
||||||
|
|
||||||
|
$ () ->
|
||||||
|
$(".js-tags-dropdown-menu input, .js-tags-dropdown-menu a").click (e) ->
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
|
ProjectPageApp.directive 'ngEnter', () ->
|
||||||
|
return (scope, element, attrs) ->
|
||||||
|
element.bind "keydown keypress", (event) ->
|
||||||
|
if event.which == 13
|
||||||
|
scope.$apply () ->
|
||||||
|
scope.$eval(attrs.ngEnter, event: event)
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
ProjectPageApp.directive 'ngFocusOn', ($timeout) ->
|
||||||
|
return {
|
||||||
|
restrict: 'AC'
|
||||||
|
link: (scope, element, attrs) ->
|
||||||
|
scope.$on attrs.ngFocusOn, () ->
|
||||||
|
element.focus()
|
||||||
|
}
|
||||||
|
|
||||||
ProjectPageApp.filter "formatDate", () ->
|
ProjectPageApp.filter "formatDate", () ->
|
||||||
(date, format = "Do MMM YYYY, h:mm a") ->
|
(date, format = "Do MMM YYYY, h:mm a") ->
|
||||||
moment(date).format(format)
|
moment(date).format(format)
|
||||||
|
|
||||||
ProjectPageApp.controller "ProjectPageController", ($scope) ->
|
ProjectPageApp.controller "ProjectPageController", ($scope, $modal, $http) ->
|
||||||
$scope.projects = window.data.projects
|
$scope.projects = window.data.projects
|
||||||
$scope.visibleProjects = $scope.projects
|
$scope.visibleProjects = $scope.projects
|
||||||
$scope.tags = window.data.tags
|
$scope.tags = window.data.tags
|
||||||
|
@ -45,7 +65,6 @@ ProjectPageApp.controller "ProjectPageController", ($scope) ->
|
||||||
visible = false
|
visible = false
|
||||||
if visible
|
if visible
|
||||||
$scope.visibleProjects.push project
|
$scope.visibleProjects.push project
|
||||||
console.log "visible", $scope.visibleProjects
|
|
||||||
$scope.clearProjectSelections()
|
$scope.clearProjectSelections()
|
||||||
|
|
||||||
$scope.getSelectedProjects = () ->
|
$scope.getSelectedProjects = () ->
|
||||||
|
@ -59,6 +78,58 @@ ProjectPageApp.controller "ProjectPageController", ($scope) ->
|
||||||
return tag if tag.selected
|
return tag if tag.selected
|
||||||
return null
|
return null
|
||||||
|
|
||||||
|
$scope.removeSelectedProjectsFromTag = (tag) ->
|
||||||
|
selected_project_ids = $scope.getSelectedProjectIds()
|
||||||
|
remaining_project_ids = []
|
||||||
|
removed_project_ids = []
|
||||||
|
for project_id in tag.project_ids
|
||||||
|
if project_id not in selected_project_ids
|
||||||
|
remaining_project_ids.push project_id
|
||||||
|
else
|
||||||
|
removed_project_ids.push project_id
|
||||||
|
tag.project_ids = remaining_project_ids
|
||||||
|
|
||||||
|
for project_id in removed_project_ids
|
||||||
|
$http.post "/project/#{project_id}/tag", {
|
||||||
|
deletedTag: tag.name
|
||||||
|
_csrf: window.csrfToken
|
||||||
|
}
|
||||||
|
|
||||||
|
# If we're filtering by this tag then we need to remove
|
||||||
|
# the projects from view
|
||||||
|
$scope.updateVisibleProjects()
|
||||||
|
|
||||||
|
$scope.addSelectedProjectsToTag = (tag) ->
|
||||||
|
added_project_ids = []
|
||||||
|
for project_id in $scope.getSelectedProjectIds()
|
||||||
|
unless project_id in tag.project_ids
|
||||||
|
tag.project_ids.push project_id
|
||||||
|
added_project_ids.push project_id
|
||||||
|
|
||||||
|
for project_id in added_project_ids
|
||||||
|
# TODO Factor this out into another provider?
|
||||||
|
$http.post "/project/#{project_id}/tag", {
|
||||||
|
tag: tag.name
|
||||||
|
_csrf: window.csrfToken
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.createTag = (name) ->
|
||||||
|
$scope.tags.push {
|
||||||
|
name: name
|
||||||
|
project_ids: []
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.openNewTagModal = () ->
|
||||||
|
modalInstance = $modal.open(
|
||||||
|
templateUrl: "newTagModalTemplate"
|
||||||
|
controller: "NewTagModalController"
|
||||||
|
)
|
||||||
|
|
||||||
|
modalInstance.result.then(
|
||||||
|
(newTagName) ->
|
||||||
|
$scope.createTag(newTagName)
|
||||||
|
)
|
||||||
|
|
||||||
ProjectPageApp.controller "ProjectListItemController", ($scope) ->
|
ProjectPageApp.controller "ProjectListItemController", ($scope) ->
|
||||||
$scope.onSelectedChange = () ->
|
$scope.onSelectedChange = () ->
|
||||||
$scope.$emit "selected:on-change"
|
$scope.$emit "selected:on-change"
|
||||||
|
@ -85,9 +156,8 @@ ProjectPageApp.controller "TagListItemController", ($scope) ->
|
||||||
$scope.setActiveItem("tag")
|
$scope.setActiveItem("tag")
|
||||||
$scope.updateVisibleProjects()
|
$scope.updateVisibleProjects()
|
||||||
|
|
||||||
ProjectPageApp.controller "TagDropdownItemController", ($scope, $http) ->
|
ProjectPageApp.controller "TagDropdownItemController", ($scope) ->
|
||||||
$scope.$on "selection:change", (e, newValue, oldValue) ->
|
$scope.$on "selection:change", (e, newValue, oldValue) ->
|
||||||
console.log "selected watch listen"
|
|
||||||
$scope.recalculateProjectsInTag()
|
$scope.recalculateProjectsInTag()
|
||||||
|
|
||||||
$scope.recalculateProjectsInTag = () ->
|
$scope.recalculateProjectsInTag = () ->
|
||||||
|
@ -98,35 +168,24 @@ ProjectPageApp.controller "TagDropdownItemController", ($scope, $http) ->
|
||||||
|
|
||||||
$scope.addOrRemoveProjectsFromTag = () ->
|
$scope.addOrRemoveProjectsFromTag = () ->
|
||||||
if $scope.areSelectedProjectsInTag
|
if $scope.areSelectedProjectsInTag
|
||||||
$scope.removeSelectedProjectsFromTag()
|
$scope.removeSelectedProjectsFromTag($scope.tag)
|
||||||
else
|
|
||||||
$scope.addSelectedProjectsToTag()
|
|
||||||
|
|
||||||
$scope.removeSelectedProjectsFromTag = () ->
|
|
||||||
selected_project_ids = $scope.getSelectedProjectIds()
|
|
||||||
remaining_project_ids = []
|
|
||||||
removed_project_ids = []
|
|
||||||
for project_id in $scope.tag.project_ids
|
|
||||||
if project_id not in selected_project_ids
|
|
||||||
remaining_project_ids.push project_id
|
|
||||||
else
|
|
||||||
removed_project_ids.push project_id
|
|
||||||
$scope.tag.project_ids = remaining_project_ids
|
|
||||||
|
|
||||||
for project_id in removed_project_ids
|
|
||||||
$http.post "/project/#{project_id}/tag", { deletedTag: $scope.tag.name, _csrf: window.csrfToken }
|
|
||||||
|
|
||||||
$scope.areSelectedProjectsInTag = false
|
$scope.areSelectedProjectsInTag = false
|
||||||
|
else
|
||||||
$scope.addSelectedProjectsToTag = () ->
|
$scope.addSelectedProjectsToTag($scope.tag)
|
||||||
added_project_ids = []
|
|
||||||
for project_id in $scope.getSelectedProjectIds()
|
|
||||||
unless project_id in $scope.tag.project_ids
|
|
||||||
$scope.tag.project_ids.push project_id
|
|
||||||
added_project_ids.push project_id
|
|
||||||
|
|
||||||
for project_id in added_project_ids
|
|
||||||
# TODO Factor this out into another provider?
|
|
||||||
$http.post "/project/#{project_id}/tag", {tag: $scope.tag.name, _csrf: window.csrfToken}
|
|
||||||
|
|
||||||
$scope.areSelectedProjectsInTag = true
|
$scope.areSelectedProjectsInTag = true
|
||||||
|
|
||||||
|
ProjectPageApp.controller 'NewTagModalController', ($scope, $modalInstance, $timeout) ->
|
||||||
|
$scope.inputs =
|
||||||
|
newTagName: "original"
|
||||||
|
|
||||||
|
$modalInstance.opened.then () ->
|
||||||
|
$timeout () ->
|
||||||
|
$scope.$broadcast "open"
|
||||||
|
, 700
|
||||||
|
|
||||||
|
$scope.create = () ->
|
||||||
|
console.log $scope.inputs.newTagName
|
||||||
|
$modalInstance.close($scope.inputs.newTagName)
|
||||||
|
|
||||||
|
$scope.cancel = () ->
|
||||||
|
$modalInstance.dismiss('cancel')
|
||||||
|
|
Loading…
Reference in a new issue