mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-16 19:21:52 +00:00
refactor tags directive(tags => tag-list, tag-item) & improve search UX
This commit is contained in:
@@ -29,12 +29,21 @@ angular.module('codexen')
|
|||||||
|
|
||||||
/* Snippets */
|
/* Snippets */
|
||||||
.state('snippets', {
|
.state('snippets', {
|
||||||
url: '/snippets?search',
|
url: '/snippets',
|
||||||
views: {
|
views: {
|
||||||
'main-view': {
|
'main-view': {
|
||||||
templateUrl: 'tpls/states/snippets.list.tpl.html',
|
templateUrl: 'tpls/states/snippets.list.tpl.html',
|
||||||
controller: 'SnippetsListController as vm'
|
controller: 'SnippetsListController as vm'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
mySnippets: function (Snippet) {
|
||||||
|
return Snippet.findMine({
|
||||||
|
'include': ['Tag']
|
||||||
|
}).then(function (res) {
|
||||||
|
return res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.state('snippets.detail', {
|
.state('snippets.detail', {
|
||||||
|
|||||||
@@ -1,44 +1,32 @@
|
|||||||
/* global angular */
|
/* global angular */
|
||||||
angular.module('codexen')
|
angular.module('codexen')
|
||||||
.controller('SnippetsListController', function ($auth, Snippet, $scope, $state, $scope) {
|
.controller('SnippetsListController', function ($auth, Snippet, $scope, $state, $scope, $filter, mySnippets) {
|
||||||
var vm = this
|
var vm = this
|
||||||
|
|
||||||
vm.isLoaded = false
|
vm.isLoading = false
|
||||||
|
|
||||||
vm.search = $state.params.search
|
|
||||||
|
|
||||||
vm.snippetId = parseInt($state.params.id)
|
vm.snippetId = parseInt($state.params.id)
|
||||||
|
|
||||||
|
vm.snippets = mySnippets
|
||||||
|
|
||||||
|
vm.searchSnippets = searchSnippets
|
||||||
|
vm.searchSnippets()
|
||||||
|
|
||||||
|
// TODO: add Navigation methods
|
||||||
|
// vm.nextSnippet()
|
||||||
|
// vm.priorSnippet()
|
||||||
|
// vm.firstSnippet()
|
||||||
|
// vm.lastSnippet()
|
||||||
|
|
||||||
|
// TODO: keyboard navigating UX
|
||||||
|
|
||||||
$scope.$on('$stateChangeStart', function (e, toState, toParams) {
|
$scope.$on('$stateChangeStart', function (e, toState, toParams) {
|
||||||
vm.snippetId = parseInt(toParams.id)
|
vm.snippetId = parseInt(toParams.id)
|
||||||
})
|
if (!vm.snippetId && vm.filtered[0]) {
|
||||||
|
$state.go('snippets.detail', {id: vm.filtered[0].id})
|
||||||
var loadSnippets = function () {
|
|
||||||
if ($auth.isAuthenticated) {
|
|
||||||
Snippet.findMine({
|
|
||||||
'include': ['Tag']
|
|
||||||
})
|
|
||||||
.success(function (data) {
|
|
||||||
console.log('snippets fetched', data)
|
|
||||||
vm.isLoaded = true
|
|
||||||
vm.snippets = data
|
|
||||||
vm.isGuest = false
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
vm.isLoaded = true
|
|
||||||
vm.isGuest = true
|
|
||||||
vm.snippets = void 0
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
loadSnippets()
|
|
||||||
|
|
||||||
$scope.$on('userSignIn', function () {
|
|
||||||
loadSnippets()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
$scope.$on('userSignOut', function () {
|
|
||||||
loadSnippets()
|
|
||||||
})
|
|
||||||
|
|
||||||
$scope.$on('snippetUpdated', function (e, snippet) {
|
$scope.$on('snippetUpdated', function (e, snippet) {
|
||||||
$state.go('snippets.detail', {id: snippet.id})
|
$state.go('snippets.detail', {id: snippet.id})
|
||||||
@@ -64,4 +52,32 @@ angular.module('codexen')
|
|||||||
loadSnippets()
|
loadSnippets()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
$scope.$on('tagSelected', function (e, tag) {
|
||||||
|
e.stopPropagation()
|
||||||
|
$scope.$apply(function () {
|
||||||
|
vm.search = '#' + tag.name
|
||||||
|
searchSnippets()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function loadSnippets() {
|
||||||
|
if ($auth.isAuthenticated) {
|
||||||
|
Snippet.findMine({
|
||||||
|
'include': ['Tag']
|
||||||
|
})
|
||||||
|
.success(function (data) {
|
||||||
|
vm.snippets = data
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
vm.snippets = void 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchSnippets() {
|
||||||
|
vm.filtered = $filter('searchSnippets')(mySnippets, vm.search)
|
||||||
|
if (vm.search && vm.filtered[0] && (!vm.snippetId || vm.snippetId !== vm.filtered[0].id)) {
|
||||||
|
$state.go('snippets.detail', {id: vm.filtered[0].id})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
16
src/directives/tag-item.js
Normal file
16
src/directives/tag-item.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* global angular */
|
||||||
|
angular.module('codexen')
|
||||||
|
.directive('tagItem', function () {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
template: '#<span ng-bind="tag.name"></span>',
|
||||||
|
scope: {
|
||||||
|
tag: '=tagItem'
|
||||||
|
},
|
||||||
|
link: function (scope, el) {
|
||||||
|
el.on('click', function () {
|
||||||
|
scope.$emit('tagSelected', scope.tag)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
/* global angular */
|
/* global angular */
|
||||||
angular.module('codexen')
|
angular.module('codexen')
|
||||||
.directive('tags', function () {
|
.directive('tagList', function () {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
template: '<p class="tags" ng-if="tags.length">' +
|
template: '<p class="tags" ng-if="tags.length">' +
|
||||||
'<i class="fa fa-tags"></i> ' +
|
'<i class="fa fa-tags"></i> ' +
|
||||||
'<a ui-sref="snippets({search:\'tag:\'+tag.name})" ng-repeat="tag in tags" href="#">#<span ng-bind="tag.name"></span></a>' +
|
'<a tag-item="tag" ng-repeat="tag in tags" href></a>' +
|
||||||
'</p>',
|
'</p>',
|
||||||
scope: {
|
scope: {
|
||||||
tags: '='
|
tags: '=tagList'
|
||||||
},
|
},
|
||||||
link: function (scope, el) {
|
link: function (scope, el) {
|
||||||
el.ready(function () {
|
el.ready(function () {
|
||||||
@@ -8,7 +8,7 @@ angular.module('codexen')
|
|||||||
|
|
||||||
return input.filter(function (snippet) {
|
return input.filter(function (snippet) {
|
||||||
return snippet.Tags.some(function (tag) {
|
return snippet.Tags.some(function (tag) {
|
||||||
return tag.name.match(new RegExp(name))
|
return tag.name.match(new RegExp('^'+name))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@
|
|||||||
|
|
||||||
<div ng-if="vm.isLoaded" class="">
|
<div ng-if="vm.isLoaded" class="">
|
||||||
<p ng-bind="vm.snippet.description"></p>
|
<p ng-bind="vm.snippet.description"></p>
|
||||||
<div tags="vm.snippet.Tags"></div>
|
|
||||||
|
<div tag-list="vm.snippet.Tags"></div>
|
||||||
|
|
||||||
<div ui-ace="{
|
<div ui-ace="{
|
||||||
showGutter: false,
|
showGutter: false,
|
||||||
useWrapMode : true,
|
useWrapMode : true,
|
||||||
|
|||||||
@@ -2,31 +2,31 @@
|
|||||||
|
|
||||||
<div class="left-pane">
|
<div class="left-pane">
|
||||||
<div class="snippet-search">
|
<div class="snippet-search">
|
||||||
<input ng-model="vm.search" type="text" name="name" class="form-control" placeholder="Search ...">
|
<input ng-model="vm.search" ng-change="vm.searchSnippets()" type="text" name="name" class="form-control" placeholder="Search ..." autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
<ul class="snippet-list">
|
<ul class="snippet-list">
|
||||||
|
|
||||||
<li ng-if="!vm.isLoaded" class="message-item">
|
<li ng-if="vm.isLoading" class="message-item">
|
||||||
<h4>
|
<h4>
|
||||||
Loading
|
Loading
|
||||||
</h4>
|
</h4>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li ng-if="vm.isLoaded && vm.snippets==0 && !vm.isGuest" class="message-item">
|
<li ng-if="!vm.isLoading && vm.snippets==0 && !vm.isGuest" class="message-item">
|
||||||
<h4>
|
<h4>
|
||||||
Empty List
|
Empty List
|
||||||
</h4>
|
</h4>
|
||||||
<button btn-new-snippet class="btn btn-default"><i class="fa fa-plus-square-o"></i> New Snippet</button>
|
<button btn-new-snippet class="btn btn-default"><i class="fa fa-plus-square-o"></i> New Snippet</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li ng-if="vm.isLoaded && vm.isGuest" class="message-item">
|
<li ng-if="!vm.isLoading && vm.isGuest" class="message-item">
|
||||||
<h4>
|
<h4>
|
||||||
Sign In to access
|
Sign In to access
|
||||||
</h4>
|
</h4>
|
||||||
<a ui-sref="auth.signin" class="btn btn-default"><i class="fa fa-signin"></i> Sign In</a>
|
<a ui-sref="auth.signin" class="btn btn-default"><i class="fa fa-signin"></i> Sign In</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li ng-repeat="snippet in vm.snippets | searchSnippets:vm.search" ui-sref="snippets.detail({id:snippet.id})" ng-class="{active:vm.snippetId===snippet.id}">
|
<li ng-repeat="snippet in vm.filtered" ui-sref="snippets.detail({id:snippet.id})" ng-class="{active:vm.snippetId===snippet.id}">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<img width="25" height="25" class="img-circle" src="http://www.gravatar.com/avatar/ea0b6ad1c11700120d1af08810caa19d" alt="" />
|
<img width="25" height="25" class="img-circle" src="http://www.gravatar.com/avatar/ea0b6ad1c11700120d1af08810caa19d" alt="" />
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div tags="snippet.Tags"></div>
|
<div tag-list="snippet.Tags"></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user