Sfoglia il codice sorgente

Allow creation of new tags

James Allen 12 anni fa
parent
commit
290089407d

+ 1 - 0
services/web/app/views/layout.jade

@@ -35,6 +35,7 @@ html(itemscope, itemtype='http://schema.org/Product')
 		script(src=jsPath+'libs/angular-1.2.17.js')
 		script(src=jsPath+'libs/moment.js')
 		script(src=jsPath+'libs/bootstrap.js')
+		script(src=jsPath+'libs/ui-bootstrap-0.11.0.js')
 		block scripts
 		
 	- if (typeof(bodyClasses) == "undefined")

+ 68 - 15
services/web/app/views/project/list.jade

@@ -10,10 +10,6 @@ block scripts
 	script(src=jsPath+'project-list.js')
 
 block content
-
-	script(type="text/x-handlebars", data-template-name="projects")
-
-	
 	.content.content-alt(ng-app="ProjectPageApp", ng-controller="ProjectPageController")
 		.container
 			.row
@@ -53,9 +49,15 @@ block content
 							//- 	a.menu-indent(href="#") Shared with you
 							li 
 								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()")
-									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}} 
 								span.small ({{tag.project_ids.length}})
 
@@ -76,29 +78,61 @@ block content
 							.col-md-12
 								form.project-search.form-horizontal(role="form")
 									.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-remove
 
 								.project-tools.js-toggle-tools
 									.btn-toolbar
 										.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
-											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
 
 										.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
 												|  
 												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(ng-repeat="tag in tags", ng-controller="TagDropdownItemController")
-													a.menu-indent(href="#", ng-click="addOrRemoveProjectsFromTag()")
-														i.fa.fa-check(ng-if="areSelectedProjectsInTag")
+												li(
+													ng-repeat="tag in tags | orderBy:'name'",
+													ng-controller="TagDropdownItemController"
+												)
+													a(href="#", ng-click="addOrRemoveProjectsFromTag()")
+														i.fa(
+															ng-class="{\
+																'fa-check-square-o': areSelectedProjectsInTag,\
+																'fa-square-o': !areSelectedProjectsInTag\
+															}"
+														)
 														|  {{tag.name}}
+												li.divider
+												li
+													a(href="#", ng-click="openNewTagModal()") Create New Folder
 
 										.btn-group
 											a.btn.btn-default.dropdown-toggle(data-toggle="dropdown", href="#") More 
@@ -126,7 +160,10 @@ block content
 														span.owner OWNER
 													.col-md-4
 														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
 													.col-md-6
 														input.select-item(type="checkbox", ng-model="project.selected", ng-change="onSelectedChange()")
@@ -148,3 +185,19 @@ block content
 														|  or
 														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

+ 91 - 32
services/web/public/coffee/project-list.coffee

@@ -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", () ->
 	(date, format = "Do MMM YYYY, h:mm a") ->
 		moment(date).format(format)
 
-ProjectPageApp.controller "ProjectPageController", ($scope) ->
+ProjectPageApp.controller "ProjectPageController", ($scope, $modal, $http) ->
 	$scope.projects = window.data.projects
 	$scope.visibleProjects = $scope.projects
 	$scope.tags = window.data.tags
@@ -45,7 +65,6 @@ ProjectPageApp.controller "ProjectPageController", ($scope) ->
 				visible = false
 			if visible
 				$scope.visibleProjects.push project
-		console.log "visible", $scope.visibleProjects
 		$scope.clearProjectSelections()
 
 	$scope.getSelectedProjects = () ->
@@ -59,6 +78,58 @@ ProjectPageApp.controller "ProjectPageController", ($scope) ->
 			return tag if tag.selected
 		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) ->
 	$scope.onSelectedChange = () ->
 		$scope.$emit "selected:on-change"
@@ -85,9 +156,8 @@ ProjectPageApp.controller "TagListItemController", ($scope) ->
 		$scope.setActiveItem("tag")
 		$scope.updateVisibleProjects()
 
-ProjectPageApp.controller "TagDropdownItemController", ($scope, $http) ->
+ProjectPageApp.controller "TagDropdownItemController", ($scope) ->
 	$scope.$on "selection:change", (e, newValue, oldValue) ->
-		console.log "selected watch listen"
 		$scope.recalculateProjectsInTag()
 
 	$scope.recalculateProjectsInTag = () ->
@@ -98,35 +168,24 @@ ProjectPageApp.controller "TagDropdownItemController", ($scope, $http) ->
 
 	$scope.addOrRemoveProjectsFromTag = () ->
 		if $scope.areSelectedProjectsInTag
-			$scope.removeSelectedProjectsFromTag()
+			$scope.removeSelectedProjectsFromTag($scope.tag)
+			$scope.areSelectedProjectsInTag = false
 		else
-			$scope.addSelectedProjectsToTag()
+			$scope.addSelectedProjectsToTag($scope.tag)
+			$scope.areSelectedProjectsInTag = true
 
-	$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
+ProjectPageApp.controller 'NewTagModalController', ($scope, $modalInstance, $timeout) ->
+	$scope.inputs = 
+		newTagName: "original"
 
-		for project_id in removed_project_ids
-			$http.post "/project/#{project_id}/tag", { deletedTag: $scope.tag.name, _csrf: window.csrfToken }
+	$modalInstance.opened.then () ->
+		$timeout () ->
+			$scope.$broadcast "open"
+		, 700
 
-		$scope.areSelectedProjectsInTag = false
-
-	$scope.addSelectedProjectsToTag = () ->
-		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.create = () ->
+		console.log $scope.inputs.newTagName
+		$modalInstance.close($scope.inputs.newTagName)
 
-		$scope.areSelectedProjectsInTag = true
+	$scope.cancel = () ->
+		$modalInstance.dismiss('cancel')