Skip to content

Commit 9762da2

Browse files
committed
refactor tags directive(tags => tag-list, tag-item) & improve search UX
1 parent 8e71091 commit 9762da2

7 files changed

Lines changed: 85 additions & 42 deletions

File tree

src/config/states.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,21 @@ angular.module('codexen')
2929

3030
/* Snippets */
3131
.state('snippets', {
32-
url: '/snippets?search',
32+
url: '/snippets',
3333
views: {
3434
'main-view': {
3535
templateUrl: 'tpls/states/snippets.list.tpl.html',
3636
controller: 'SnippetsListController as vm'
3737
}
38+
},
39+
resolve: {
40+
mySnippets: function (Snippet) {
41+
return Snippet.findMine({
42+
'include': ['Tag']
43+
}).then(function (res) {
44+
return res.data
45+
})
46+
}
3847
}
3948
})
4049
.state('snippets.detail', {
Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,33 @@
11
/* global angular */
22
angular.module('codexen')
3-
.controller('SnippetsListController', function ($auth, Snippet, $scope, $state, $scope) {
3+
.controller('SnippetsListController', function ($auth, Snippet, $scope, $state, $scope, $filter, mySnippets) {
44
var vm = this
55

6-
vm.isLoaded = false
7-
8-
vm.search = $state.params.search
6+
vm.isLoading = false
97

108
vm.snippetId = parseInt($state.params.id)
11-
$scope.$on('$stateChangeStart', function (e, toState, toParams) {
12-
vm.snippetId = parseInt(toParams.id)
13-
})
149

15-
var loadSnippets = function () {
16-
if ($auth.isAuthenticated) {
17-
Snippet.findMine({
18-
'include': ['Tag']
19-
})
20-
.success(function (data) {
21-
console.log('snippets fetched', data)
22-
vm.isLoaded = true
23-
vm.snippets = data
24-
vm.isGuest = false
25-
})
26-
} else {
27-
vm.isLoaded = true
28-
vm.isGuest = true
29-
vm.snippets = void 0
30-
}
31-
}
10+
vm.snippets = mySnippets
3211

33-
loadSnippets()
12+
vm.searchSnippets = searchSnippets
13+
vm.searchSnippets()
3414

35-
$scope.$on('userSignIn', function () {
36-
loadSnippets()
37-
})
15+
// TODO: add Navigation methods
16+
// vm.nextSnippet()
17+
// vm.priorSnippet()
18+
// vm.firstSnippet()
19+
// vm.lastSnippet()
3820

39-
$scope.$on('userSignOut', function () {
40-
loadSnippets()
21+
// TODO: keyboard navigating UX
22+
23+
$scope.$on('$stateChangeStart', function (e, toState, toParams) {
24+
vm.snippetId = parseInt(toParams.id)
25+
if (!vm.snippetId && vm.filtered[0]) {
26+
$state.go('snippets.detail', {id: vm.filtered[0].id})
27+
}
4128
})
4229

30+
4331
$scope.$on('snippetUpdated', function (e, snippet) {
4432
$state.go('snippets.detail', {id: snippet.id})
4533
loadSnippets()
@@ -64,4 +52,32 @@ angular.module('codexen')
6452
loadSnippets()
6553
})
6654

55+
$scope.$on('tagSelected', function (e, tag) {
56+
e.stopPropagation()
57+
$scope.$apply(function () {
58+
vm.search = '#' + tag.name
59+
searchSnippets()
60+
})
61+
})
62+
63+
function loadSnippets() {
64+
if ($auth.isAuthenticated) {
65+
Snippet.findMine({
66+
'include': ['Tag']
67+
})
68+
.success(function (data) {
69+
vm.snippets = data
70+
})
71+
} else {
72+
vm.snippets = void 0
73+
}
74+
}
75+
76+
function searchSnippets() {
77+
vm.filtered = $filter('searchSnippets')(mySnippets, vm.search)
78+
if (vm.search && vm.filtered[0] && (!vm.snippetId || vm.snippetId !== vm.filtered[0].id)) {
79+
$state.go('snippets.detail', {id: vm.filtered[0].id})
80+
}
81+
}
82+
6783
})

src/directives/tag-item.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* global angular */
2+
angular.module('codexen')
3+
.directive('tagItem', function () {
4+
return {
5+
restrict: 'A',
6+
template: '#<span ng-bind="tag.name"></span>',
7+
scope: {
8+
tag: '=tagItem'
9+
},
10+
link: function (scope, el) {
11+
el.on('click', function () {
12+
scope.$emit('tagSelected', scope.tag)
13+
})
14+
}
15+
}
16+
})
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/* global angular */
22
angular.module('codexen')
3-
.directive('tags', function () {
3+
.directive('tagList', function () {
44
return {
55
restrict: 'A',
66
template: '<p class="tags" ng-if="tags.length">' +
77
'<i class="fa fa-tags"></i> ' +
8-
'<a ui-sref="snippets({search:\'tag:\'+tag.name})" ng-repeat="tag in tags" href="#">#<span ng-bind="tag.name"></span></a>' +
8+
'<a tag-item="tag" ng-repeat="tag in tags" href></a>' +
99
'</p>',
1010
scope: {
11-
tags: '='
11+
tags: '=tagList'
1212
},
1313
link: function (scope, el) {
1414
el.ready(function () {

src/filters/search-snippets.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ angular.module('codexen')
88

99
return input.filter(function (snippet) {
1010
return snippet.Tags.some(function (tag) {
11-
return tag.name.match(new RegExp(name))
11+
return tag.name.match(new RegExp('^'+name))
1212
})
1313
})
1414
}

src/tpls/states/snippets.detail.tpl.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121

2222
<div ng-if="vm.isLoaded" class="">
2323
<p ng-bind="vm.snippet.description"></p>
24-
<div tags="vm.snippet.Tags"></div>
24+
25+
<div tag-list="vm.snippet.Tags"></div>
26+
2527
<div ui-ace="{
2628
showGutter: false,
2729
useWrapMode : true,

src/tpls/states/snippets.list.tpl.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,31 @@
22

33
<div class="left-pane">
44
<div class="snippet-search">
5-
<input ng-model="vm.search" type="text" name="name" class="form-control" placeholder="Search ...">
5+
<input ng-model="vm.search" ng-change="vm.searchSnippets()" type="text" name="name" class="form-control" placeholder="Search ..." autocomplete="off">
66
</div>
77
<ul class="snippet-list">
88

9-
<li ng-if="!vm.isLoaded" class="message-item">
9+
<li ng-if="vm.isLoading" class="message-item">
1010
<h4>
1111
Loading
1212
</h4>
1313
</li>
1414

15-
<li ng-if="vm.isLoaded && vm.snippets==0 && !vm.isGuest" class="message-item">
15+
<li ng-if="!vm.isLoading && vm.snippets==0 && !vm.isGuest" class="message-item">
1616
<h4>
1717
Empty List
1818
</h4>
1919
<button btn-new-snippet class="btn btn-default"><i class="fa fa-plus-square-o"></i> New Snippet</button>
2020
</li>
2121

22-
<li ng-if="vm.isLoaded && vm.isGuest" class="message-item">
22+
<li ng-if="!vm.isLoading && vm.isGuest" class="message-item">
2323
<h4>
2424
Sign In to access
2525
</h4>
2626
<a ui-sref="auth.signin" class="btn btn-default"><i class="fa fa-signin"></i> Sign In</a>
2727
</li>
2828

29-
<li ng-repeat="snippet in vm.snippets | searchSnippets:vm.search" ui-sref="snippets.detail({id:snippet.id})" ng-class="{active:vm.snippetId===snippet.id}">
29+
<li ng-repeat="snippet in vm.filtered" ui-sref="snippets.detail({id:snippet.id})" ng-class="{active:vm.snippetId===snippet.id}">
3030
<div class="media">
3131
<div class="media-left">
3232
<img width="25" height="25" class="img-circle" src="http://www.gravatar.com/avatar/ea0b6ad1c11700120d1af08810caa19d" alt="" />
@@ -41,7 +41,7 @@ <h4>
4141
</p>
4242
</div>
4343
</div>
44-
<div tags="snippet.Tags"></div>
44+
<div tag-list="snippet.Tags"></div>
4545
</li>
4646
</ul>
4747
</div>

0 commit comments

Comments
 (0)