US #2127: Discover section [2]
parent
d19623b4d1
commit
40418839b2
|
@ -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",
|
||||
|
@ -577,7 +597,7 @@ init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $na
|
|||
$rootscope.$evalAsync(cb)
|
||||
|
||||
$events.setupConnection()
|
||||
|
||||
|
||||
# Load user
|
||||
if $auth.isAuthenticated()
|
||||
user = $auth.getUser()
|
||||
|
@ -664,6 +684,7 @@ modules = [
|
|||
"taigaHome",
|
||||
"taigaUserTimeline",
|
||||
"taigaExternalApps",
|
||||
"taigaDiscover",
|
||||
|
||||
# template cache
|
||||
"templates",
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -112,7 +112,7 @@ LoadingDirective = ($loading) ->
|
|||
if showLoading
|
||||
currentLoading = $loading()
|
||||
.target($el)
|
||||
.timeout(50)
|
||||
.timeout(100)
|
||||
.template(template)
|
||||
.scope($scope)
|
||||
.start()
|
||||
|
|
|
@ -175,6 +175,9 @@ urls = {
|
|||
# Application tokens
|
||||
"applications": "/applications"
|
||||
"application-tokens": "/application-tokens"
|
||||
|
||||
# Stats
|
||||
"stats-discover": "/stats/discover"
|
||||
}
|
||||
|
||||
# Initialize api urls service
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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", ->
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,16 +15,16 @@ 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 }}"
|
||||
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 }}"
|
||||
title="{{ 'REGISTER_FORM.ACTION_SIGN_UP' | translate }}"
|
||||
) {{ 'REGISTER_FORM.ACTION_SIGN_UP' | translate }}
|
||||
|
||||
|
||||
div.nav-right(ng-if="vm.isAuthenticated")
|
||||
a(tg-nav="home",
|
||||
ng-class="{active: vm.active}",
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue