US #2127: Discover section [2]

stable
Alejandro Alonso 2016-01-21 18:38:58 +01:00 committed by David Barragán Merino
parent d19623b4d1
commit 40418839b2
14 changed files with 221 additions and 28 deletions

View File

@ -66,9 +66,8 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
$routeProvider.when("/",
{
templateUrl: "home/home.html",
access: {
requiresLogin: true
},
controller: "Home",
controllerAs: "vm"
loader: true,
title: "HOME.PAGE_TITLE",
loader: true,
@ -77,6 +76,27 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
}
)
$routeProvider.when("/discover",
{
templateUrl: "discover/discover-home/discover-home.html",
controller: "DiscoverHome",
controllerAs: "vm",
title: "PROJECT.NAVIGATION.DISCOVER",
loader: true
}
)
$routeProvider.when("/discover/search",
{
templateUrl: "discover/discover-search/discover-search.html",
title: "PROJECT.NAVIGATION.DISCOVER",
loader: true,
controller: "DiscoverSearch",
controllerAs: "vm",
reloadOnSearch: false
}
)
$routeProvider.when("/projects/",
{
templateUrl: "projects/listing/projects-listing.html",
@ -664,6 +684,7 @@ modules = [
"taigaHome",
"taigaUserTimeline",
"taigaExternalApps",
"taigaDiscover",
# template cache
"templates",

View File

@ -449,3 +449,64 @@ CsvIssueDirective = ($translate) ->
}
module.directive("tgCsvIssue", ["$translate", CsvIssueDirective])
#############################################################################
## Project Logo Directive
#############################################################################
ProjectLogoDirective = ($auth, $model, $rs, $confirm) ->
link = ($scope, $el, $attrs) ->
showSizeInfo = ->
$el.find(".size-info").addClass("active")
onSuccess = (response) ->
project = $model.make_model("projects", response.data)
$scope.project = project
$el.find('.loading-overlay').removeClass('active')
$confirm.notify('success')
onError = (response) ->
showSizeInfo() if response.status == 413
$el.find('.loading-overlay').removeClass('active')
$confirm.notify('error', response.data._error_message)
# Change photo
$el.on "click", ".js-change-logo", ->
$el.find("#logo-field").click()
$el.on "change", "#logo-field", (event) ->
if $scope.logoAttachment
$el.find('.loading-overlay').addClass("active")
$rs.projects.changeLogo($scope.project.id, $scope.logoAttachment).then(onSuccess, onError)
# Use default photo
$el.on "click", "a.js-use-default-logo", (event) ->
$el.find('.loading-overlay').addClass("active")
$rs.projects.removeLogo($scope.project.id).then(onSuccess, onError)
$scope.$on "$destroy", ->
$el.off()
return {link:link}
module.directive("tgProjectLogo", ["$tgAuth", "$tgModel", "$tgResources", "$tgConfirm", ProjectLogoDirective])
#############################################################################
## Project Logo Model Directive
#############################################################################
ProjectLogoModelDirective = ($parse) ->
link = ($scope, $el, $attrs) ->
model = $parse($attrs.tgProjectLogoModel)
modelSetter = model.assign
$el.bind 'change', ->
$scope.$apply ->
modelSetter($scope, $el[0].files[0])
return {link:link}
module.directive('tgProjectLogoModel', ['$parse', ProjectLogoModelDirective])

View File

@ -52,6 +52,9 @@ urls = {
"not-found": "/not-found"
"permission-denied": "/permission-denied"
"discover": "/discover"
"discover-search": "/discover/search"
"login": "/login"
"forgot-password": "/forgot-password"
"change-password": "/change-password/:token"

View File

@ -117,7 +117,7 @@ NavigationUrlsDirective = ($navurls, $auth, $q, $location) ->
$el.on "mouseenter", (event) ->
target = $(event.currentTarget)
if !target.data("fullUrl")
if !target.data("fullUrl") || $attrs.tgNavGetParams != target.data("params")
parseNav($attrs.tgNav, $scope).then (result) ->
[name, options] = result
user = $auth.getUser()
@ -131,6 +131,8 @@ NavigationUrlsDirective = ($navurls, $auth, $q, $location) ->
getURLParamsStr = $.param(getURLParams)
fullUrl = "#{fullUrl}?#{getURLParamsStr}"
target.data("params", $attrs.tgNavGetParams)
target.data("fullUrl", fullUrl)
if target.is("a")

View File

@ -112,7 +112,7 @@ LoadingDirective = ($loading) ->
if showLoading
currentLoading = $loading()
.target($el)
.timeout(50)
.timeout(100)
.template(template)
.scope($scope)
.start()

View File

@ -175,6 +175,9 @@ urls = {
# Application tokens
"applications": "/applications"
"application-tokens": "/application-tokens"
# Stats
"stats-discover": "/stats/discover"
}
# Initialize api urls service

View File

@ -153,6 +153,31 @@ resourceProvider = ($config, $repo, $http, $urls, $auth, $q, $translate) ->
return defered.promise
service.changeLogo = (projectId, file) ->
maxFileSize = $config.get("maxUploadFileSize", null)
if maxFileSize and file.size > maxFileSize
response = {
status: 413,
data: _error_message: "'#{file.name}' (#{sizeFormat(file.size)}) is too heavy for our oompa
loompas, try it with a smaller than (#{sizeFormat(maxFileSize)})"
}
defered = $q.defer()
defered.reject(response)
return defered.promise
data = new FormData()
data.append('logo', file)
options = {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}
url = "#{$urls.resolve("projects")}/#{projectId}/change_logo"
return $http.post(url, data, {}, options)
service.removeLogo = (projectId) ->
url = "#{$urls.resolve("projects")}/#{projectId}/remove_logo"
return $http.post(url)
return (instance) ->
instance.projects = service

View File

@ -148,12 +148,12 @@ UserAvatarDirective = ($auth, $model, $rs, $confirm) ->
$auth.setUser(user)
$scope.user = user
$el.find('.overlay').addClass('hidden')
$el.find('.loading-overlay').removeClass('active')
$confirm.notify('success')
onError = (response) ->
showSizeInfo() if response.status == 413
$el.find('.overlay').addClass('hidden')
$el.find('.loading-overlay').removeClass('active')
$confirm.notify('error', response.data._error_message)
# Change photo
@ -162,12 +162,12 @@ UserAvatarDirective = ($auth, $model, $rs, $confirm) ->
$el.on "change", "#avatar-field", (event) ->
if $scope.avatarAttachment
$el.find('.overlay').removeClass('hidden')
$el.find('.loading-overlay').addClass("active")
$rs.userSettings.changeAvatar($scope.avatarAttachment).then(onSuccess, onError)
# Use gravatar photo
$el.on "click", "a.use-gravatar", (event) ->
$el.find('.overlay').removeClass('hidden')
$el.on "click", "a.js-use-gravatar", (event) ->
$el.find('.loading-overlay').addClass("active")
$rs.userSettings.removeAvatar().then(onSuccess, onError)
$scope.$on "$destroy", ->

View File

@ -195,6 +195,14 @@ _.mixin
delete obj[key]; obj
, obj).value()
cartesianProduct: ->
_.reduceRight(
arguments, (a,b) ->
_.flatten(_.map(a, (x) -> _.map b, (y) -> [y].concat(x)), true)
, [ [] ])
isImage = (name) ->
return name.match(/\.(jpe?g|png|gif|gifv|webm)/i) != null

View File

@ -27,7 +27,8 @@ DropdownUserDirective = (authService, configService, locationService,
scope.vm.logout = ->
authService.logout()
locationService.path(navUrlsService.resolve("login"))
locationService.url(navUrlsService.resolve("discover"))
locationService.search({})
scope.vm.sendFeedback = ->
feedbackService.sendFeedback()

View File

@ -50,8 +50,10 @@ describe "dropdownUserDirective", () ->
_mockTgLocation = () ->
mockTgLocation = {
path: sinon.stub()
url: sinon.stub()
search: sinon.stub()
}
provide.value "$tgLocation", mockTgLocation
_mockTgNavUrls = () ->
@ -97,16 +99,19 @@ describe "dropdownUserDirective", () ->
expect(vm.isFeedbackEnabled).to.be.equal(true)
it "dropdown user log out", () ->
mockTgNavUrls.resolve.withArgs("login").returns("/login")
mockTgNavUrls.resolve.withArgs("discover").returns("/discover")
elm = createDirective()
scope.$apply()
vm = elm.isolateScope().vm
expect(mockTgAuth.logout.callCount).to.be.equal(0)
expect(mockTgLocation.path.callCount).to.be.equal(0)
expect(mockTgLocation.url.callCount).to.be.equal(0)
expect(mockTgLocation.search.callCount).to.be.equal(0)
vm.logout()
expect(mockTgAuth.logout.callCount).to.be.equal(1)
expect(mockTgLocation.path.callCount).to.be.equal(1)
expect(mockTgLocation.path.calledWith("/login")).to.be.true
expect(mockTgLocation.url.callCount).to.be.equal(1)
expect(mockTgLocation.search.callCount).to.be.equal(1)
expect(mockTgLocation.url.calledWith("/discover")).to.be.true
expect(mockTgLocation.search.calledWith({})).to.be.true
it "dropdown user send feedback", () ->
elm = createDirective()

View File

@ -17,12 +17,14 @@
# File: navigation-bar.directive.coffee
###
NavigationBarDirective = (currentUserService, navigationBarService, $location) ->
NavigationBarDirective = (currentUserService, navigationBarService,
locationService, navUrlsService) ->
link = (scope, el, attrs, ctrl) ->
scope.vm = {}
scope.$on "$routeChangeSuccess", () ->
if $location.path() == "/"
if locationService.path() == "/"
scope.vm.active = true
else
scope.vm.active = false
@ -31,6 +33,15 @@ NavigationBarDirective = (currentUserService, navigationBarService, $location) -
taiga.defineImmutableProperty(scope.vm, "isAuthenticated", () -> currentUserService.isAuthenticated())
taiga.defineImmutableProperty(scope.vm, "isEnabledHeader", () -> navigationBarService.isEnabledHeader())
scope.vm.login = ->
nextUrl = encodeURIComponent(locationService.url())
locationService.url(navUrlsService.resolve("login"))
locationService.search({next: nextUrl})
scope.vm.register = ->
nextUrl = encodeURIComponent(locationService.url())
locationService.url(navUrlsService.resolve("register"))
locationService.search({next: nextUrl})
directive = {
templateUrl: "navigation-bar/navigation-bar.html"
@ -42,8 +53,9 @@ NavigationBarDirective = (currentUserService, navigationBarService, $location) -
NavigationBarDirective.$inject = [
"tgCurrentUserService",
"tgNavigationBarService"
"$location"
"tgNavigationBarService",
"$tgLocation",
"$tgNavUrls"
]
angular.module("taigaNavigationBar").directive("tgNavigationBar", NavigationBarDirective)

View File

@ -41,6 +41,19 @@ describe "navigationBarDirective", () ->
provide.value "tgCurrentUserService", mocks.currentUserService
_mocksLocationService = () ->
mocks.locationService = {
url: sinon.stub()
search: sinon.stub()
}
provide.value "$tgLocation", mocks.locationService
_mockTgNavUrls = () ->
mocks.navUrls = {
resolve: sinon.stub()
}
provide.value "$tgNavUrls", mocks.navUrls
_mockTranslateFilter = () ->
mockTranslateFilter = (value) ->
@ -58,6 +71,8 @@ describe "navigationBarDirective", () ->
provide = $provide
_mocksCurrentUserService()
_mocksLocationService()
_mockTgNavUrls( )
_mockTranslateFilter()
_mockTgDropdownProjectListDirective()
_mockTgDropdownUserDirective()
@ -90,3 +105,33 @@ describe "navigationBarDirective", () ->
mocks.currentUserService.isAuthenticated.returns(true)
expect(elm.isolateScope().vm.isAuthenticated).to.be.true
it "navigation bar login", () ->
mocks.navUrls.resolve.withArgs("login").returns("/login")
nextUrl = "/discover/search?order_by=-total_activity_last_month"
mocks.locationService.url.returns(nextUrl)
elm = createDirective()
scope.$apply()
vm = elm.isolateScope().vm
expect(mocks.locationService.url.callCount).to.be.equal(0)
expect(mocks.locationService.search.callCount).to.be.equal(0)
vm.login()
expect(mocks.locationService.url.callCount).to.be.equal(2)
expect(mocks.locationService.search.callCount).to.be.equal(1)
expect(mocks.locationService.url.calledWith("/login")).to.be.true
expect(mocks.locationService.search.calledWith({next: encodeURIComponent(nextUrl)})).to.be.true
it "navigation bar register", () ->
mocks.navUrls.resolve.withArgs("register").returns("/register")
nextUrl = "/discover/search?order_by=-total_activity_last_month"
mocks.locationService.url.returns(nextUrl)
elm = createDirective()
scope.$apply()
vm = elm.isolateScope().vm
expect(mocks.locationService.url.callCount).to.be.equal(0)
expect(mocks.locationService.search.callCount).to.be.equal(0)
vm.register()
expect(mocks.locationService.url.callCount).to.be.equal(2)
expect(mocks.locationService.search.callCount).to.be.equal(1)
expect(mocks.locationService.url.calledWith("/register")).to.be.true
expect(mocks.locationService.search.calledWith({next: encodeURIComponent(nextUrl)})).to.be.true

View File

@ -3,7 +3,7 @@ nav.navbar(ng-if="vm.isEnabledHeader")
a.logo(
href="#",
tg-nav="home",
title="{{'PROJECT.NAVIGATION.DASHBOARD_TITLE' | translate}}")
title="{{'PROJECT.NAVIGATION.HOMEPAGE' | translate}}")
include ../../svg/logo.svg
@ -15,12 +15,12 @@ nav.navbar(ng-if="vm.isEnabledHeader")
div.nav-right(ng-if="!vm.isAuthenticated")
a.login(
tg-nav="login",
ng-click="vm.login()"
href="#",
title="{{ 'LOGIN_COMMON.ACTION_SIGN_IN' | translate }}"
) {{ 'LOGIN_COMMON.ACTION_SIGN_IN' | translate }}
a.register(
tg-nav="register",
ng-click="vm.register()"
href="#",
title="{{ 'REGISTER_FORM.ACTION_SIGN_UP' | translate }}"
) {{ 'REGISTER_FORM.ACTION_SIGN_UP' | translate }}
@ -32,6 +32,13 @@ nav.navbar(ng-if="vm.isEnabledHeader")
include ../../svg/dashboard.svg
a(
href="#",
tg-nav="discover",
title="{{'PROJECT.NAVIGATION.DISCOVER_TITLE' | translate}}",
)
include ../../svg/discover.svg
div.topnav-dropdown-wrapper(ng-show="vm.projects.size", tg-dropdown-project-list)
//div.topnav-dropdown-wrapper(tg-dropdown-organization-list)
//- div.topnav-dropdown-wrapper(tg-dropdown-organization-list)
div.topnav-dropdown-wrapper(tg-dropdown-user)