Refactoring home

stable
Alejandro Alonso 2015-04-28 09:25:40 +02:00 committed by Juanfran
parent 792d2ae22c
commit 43501892ee
15 changed files with 178 additions and 74 deletions

View File

@ -39,7 +39,7 @@ taiga.sessionId = taiga.generateUniqueSessionIdentifier()
configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, tgLoaderProvider, configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, tgLoaderProvider,
$compileProvider, $translateProvider) -> $compileProvider, $translateProvider) ->
$routeProvider.when("/", $routeProvider.when("/",
{templateUrl: "home/home-page.html"}) {templateUrl: "home/home-page.html", resolve: {loader: tgLoaderProvider.add()}})
$routeProvider.when("/projects/", $routeProvider.when("/projects/",
{templateUrl: "projects/projects-page.html", resolve: {loader: tgLoaderProvider.add()}}) {templateUrl: "projects/projects-page.html", resolve: {loader: tgLoaderProvider.add()}})
@ -320,6 +320,7 @@ modules = [
"taigaEvents", "taigaEvents",
# Specific Modules # Specific Modules
"taigaHome",
"taigaNavigationBar", "taigaNavigationBar",
"taigaProjects", "taigaProjects",
"taigaRelatedTasks", "taigaRelatedTasks",

View File

@ -69,9 +69,7 @@ urls = {
"project-search": "/project/:project/search" "project-search": "/project/:project/search"
"project-userstories-detail": "/project/:project/us/:ref" "project-userstories-detail": "/project/:project/us/:ref"
"project-tasks-detail": "/project/:project/task/:ref" "project-tasks-detail": "/project/:project/task/:ref"
"project-issues-detail": "/project/:project/issue/:ref" "project-issues-detail": "/project/:project/issue/:ref"
"project-wiki": "/project/:project/wiki" "project-wiki": "/project/:project/wiki"

View File

@ -41,6 +41,9 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) ->
params.ref = ref params.ref = ref
return $repo.queryOne("issues", "by_ref", params) return $repo.queryOne("issues", "by_ref", params)
service.listInAllProjects = (filters) ->
return $repo.queryMany("issues", filters)
service.list = (projectId, filters, options) -> service.list = (projectId, filters, options) ->
params = {project: projectId} params = {project: projectId}
params = _.extend({}, params, filters or {}) params = _.extend({}, params, filters or {})

View File

@ -41,6 +41,9 @@ resourceProvider = ($repo, $http, $urls, $storage) ->
params.ref = ref params.ref = ref
return $repo.queryOne("tasks", "by_ref", params) return $repo.queryOne("tasks", "by_ref", params)
service.listInAllProjects = (filters) ->
return $repo.queryMany("tasks", filters)
service.list = (projectId, sprintId=null, userStoryId=null) -> service.list = (projectId, sprintId=null, userStoryId=null) ->
params = {project: projectId} params = {project: projectId}
params.milestone = sprintId if sprintId params.milestone = sprintId if sprintId

View File

@ -38,6 +38,9 @@ resourceProvider = ($repo, $http, $urls, $storage) ->
params.ref = ref params.ref = ref
return $repo.queryOne("userstories", "by_ref", params) return $repo.queryOne("userstories", "by_ref", params)
service.listInAllProjects = (filters) ->
return $repo.queryMany("userstories", filters)
service.listUnassigned = (projectId, filters) -> service.listUnassigned = (projectId, filters) ->
params = {"project": projectId, "milestone": "null"} params = {"project": projectId, "milestone": "null"}
params = _.extend({}, params, filters or {}) params = _.extend({}, params, filters or {})

View File

@ -101,6 +101,9 @@
} }
}, },
"SEE_USER_PROFILE": "See {{username }} profile", "SEE_USER_PROFILE": "See {{username }} profile",
"USER_STORY": "User story",
"TASK": "Task",
"ISSUE": "Issue",
"TAGS": { "TAGS": {
"PLACEHOLDER": "I'm it! Tag me...", "PLACEHOLDER": "I'm it! Tag me...",
"DELETE": "Delete tag", "DELETE": "Delete tag",
@ -241,6 +244,9 @@
"REGISTER": "Register", "REGISTER": "Register",
"CREATE_ACCOUNT": "create your free account here" "CREATE_ACCOUNT": "create your free account here"
}, },
"HOME": {
"EMPTY_WATCHING": "<strong>Follow</strong> the projects, User Stories, Tasks, Issues... that you want to know about :)"
},
"ATTACHMENT": { "ATTACHMENT": {
"SECTION_NAME": "attachments", "SECTION_NAME": "attachments",
"TITLE": "{{ fileName }} uploaded on {{ date }}", "TITLE": "{{ fileName }} uploaded on {{ date }}",

View File

@ -0,0 +1,37 @@
DutyDirective = (navurls, projectsService, $translate) ->
link = (scope, el, attrs, ctrl) ->
scope.vm = {}
scope.vm.duty = scope.duty
scope.vm.getDutyType = () ->
if scope.vm.duty
if scope.vm.duty._name == "userstories"
return $translate.instant("COMMON.USER_STORY")
if scope.vm.duty._name == "tasks"
return $translate.instant("COMMON.TASK")
if scope.vm.duty._name == "issues"
return $translate.instant("COMMON.ISSUE")
scope.vm.getUrl = () ->
if scope.vm.duty
ctx = {
project: projectsService.projectsById.get(String(scope.vm.duty.project)).slug
ref: scope.vm.duty.ref
}
return navurls.resolve("project-#{scope.vm.duty._name}-detail", ctx)
scope.vm.getProjectName = () ->
if scope.vm.duty
return projectsService.projectsById.get(String(scope.vm.duty.project)).name
directive = {
templateUrl: "home/duties/duty.html"
scope: {
"duty": "=tgDuty"
}
link: link
}
return directive
angular.module("taigaHome").directive("tgDuty", ["$tgNavUrls", "tgProjects", "$translate", DutyDirective])

View File

@ -0,0 +1,12 @@
img.avatar(
src="https://s3.amazonaws.com/uifaces/faces/twitter/rem/128.jpg"
title="{{ user.fullname }}")
div.duty-data
div
span.duty-type {{ vm.getDutyType() }}
span.duty-status(ng-style="{'color': vm.duty.status_color}") {{ ::vm.duty.status_name }}
a.duty-title(href="{{ vm.getUrl() }}")
span.duty-id(tg-bo-ref="duty.ref")
span.duty-name {{ ::duty.subject }}
div.duty-project {{ ::vm.getProjectName()}}

View File

@ -1,9 +1,26 @@
HomeDirective = -> HomeDirective = (homeService) ->
link = (scope, el, attrs, ctrl) ->
scope.vm = {}
taiga.defineImmutableProperty(scope.vm, "workInProgress", () -> homeService.workInProgress)
scope.$watch "vm.workInProgress", (workInProgress) ->
if workInProgress.size > 0
userStories = workInProgress.get("assignedTo").get("userStories")
tasks = workInProgress.get("assignedTo").get("tasks")
issues = workInProgress.get("assignedTo").get("issues")
scope.vm.assignedTo = userStories.concat(tasks).concat(issues)
userStories = workInProgress.get("watching").get("userStories")
tasks = workInProgress.get("watching").get("tasks")
issues = workInProgress.get("watching").get("issues")
scope.vm.watching = userStories.concat(tasks).concat(issues)
directive = { directive = {
templateUrl: "home/home.html" templateUrl: "home/home.html"
scope: {} scope: {}
link: link
} }
return directive return directive
angular.module("taigaProjects").directive("tgHome", HomeDirective) angular.module("taigaHome").directive("tgHome", ["tgHomeService", HomeDirective])

View File

@ -12,22 +12,28 @@ class ProjectsPageController extends taiga.Controller
"$tgConfig", "$tgConfig",
"tgLoader", "tgLoader",
"tgProjects", "tgProjects",
"tgHomeService",
"$translate" "$translate"
] ]
constructor: (@scope, @q, @rs, @rootscope, @navUrls, @auth, @location, constructor: (@scope, @q, @rs, @rootscope, @navUrls, @auth, @location,
@appTitle, @projectUrl, @config, tgLoader, @projects, @translate) -> @appTitle, @projectUrl, @config, tgLoader, @projectsService, @homeService,
@translate) ->
@appTitle.set(@translate.instant("PROJECT.WELCOME")) @appTitle.set(@translate.instant("PROJECT.WELCOME"))
if !@auth.isAuthenticated() if !@auth.isAuthenticated()
@location.path(@navUrls.resolve("login")) @location.path(@navUrls.resolve("login"))
#Projects #Projects
promise = @projects.fetchProjects() projectsPromise = @projectsService.fetchProjects()
#In progress work
user = @auth.getUser()
workInProgressPromise = @homeService.fetchWorkInProgress(user.id)
# Finally # Finally
promise.finally tgLoader.pageLoaded @q.all([projectsPromise, workInProgressPromise]).finally tgLoader.pageLoaded
angular.module("taigaHome").controller("HomePage", ProjectsPageController) angular.module("taigaHome").controller("HomePage", ProjectsPageController)

View File

@ -0,0 +1,59 @@
class HomeService extends taiga.Service
@.$inject = ["$q", "$tgResources", "$rootScope", "$projectUrl"]
constructor: (@q, @rs, @rootScope, @projectUrl) ->
@.workInProgress = Immutable.Map()
@.inProgress = false
fetchWorkInProgress: (userId) ->
if not @.inProgress
@.inProgress = true
params = {
status__is_closed: false
assigned_to: userId
}
assignedUserStoriesPromise = @rs.userstories.listInAllProjects(params).then (userstories) =>
@.assignedToUserStories = userstories
assignedTasksPromise = @rs.tasks.listInAllProjects(params).then (tasks) =>
@.assignedToTasks = tasks
assignedIssuesPromise = @rs.issues.listInAllProjects(params).then (issues) =>
@.assignedToIssues = issues
params = {
status__is_closed: false
watchers: userId
}
watchingUserStoriesPromise = @rs.userstories.listInAllProjects(params).then (userstories) =>
@.watchingUserStories = userstories
watchingTasksPromise = @rs.tasks.listInAllProjects(params).then (tasks) =>
@.watchingTasks = tasks
watchingIssuesPromise = @rs.issues.listInAllProjects(params).then (issues) =>
@.watchingIssues = issues
workPromise = @q.all([assignedUserStoriesPromise, assignedTasksPromise,
assignedIssuesPromise, watchingUserStoriesPromise,
watchingUserStoriesPromise, watchingIssuesPromise])
workPromise.then =>
@.workInProgress = Immutable.fromJS({
assignedTo: {
userStories: @.assignedToUserStories
tasks: @.assignedToTasks
issues: @.assignedToIssues
}
watching: {
userStories: @.watchingUserStories
tasks: @.watchingTasks
issues: @.watchingIssues
}
})
@.inProgress = false
return workPromise
angular.module("taigaHome").service("tgHomeService", HomeService)

View File

@ -1,68 +1,22 @@
doctype html doctype html
include ../../partials/includes/components/beta include ../../partials/includes/components/beta
div.home-wrapper.centered(ng-controller="HomePage") div.home-wrapper.centered
div.duty-summary div.duty-summary
// TODO Hide if ASSIGNED TO ==== false // TODO: if not assigned to items?
div.title-bar.working-on-title Working on // TODO: i18n
// TODO Hide if ASSIGNED TO ==== false div.title-bar.working-on-title(ng-show="vm.assignedTo") Working on
section.working-on section.working-on(ng-show="vm.assignedTo")
// TODO Remove and replace for an angular repeat div.duty-single(tg-duty="duty", tg-repeat="duty in vm.assignedTo", ng-class="{blocked: duty.is_blocked}")
- for (var x = 0; x < 2; x++)
div.duty-single
img.avatar(src="https://s3.amazonaws.com/uifaces/faces/twitter/rem/128.jpg", title="{{ user.fullname }}")
div.duty-data
div
// TODO, ADD THEIR COLOR TO THE DUTY TYPE AND STATUS
span.duty-type User Story
span.duty-status New
a.duty-title(href="")
span.duty-id #1504
span.duty-name Documentación III: (notificaciones asíncronas + plugins front/back)
div.duty-project Taiga
div.duty-single.blocked
img.avatar(src="https://s3.amazonaws.com/uifaces/faces/twitter/rem/128.jpg", title="{{ user.fullname }}")
div.duty-data
div
// TODO, ADD THEIR COLOR TO THE DUTY TYPE AND STATUS
span.duty-type User Story
span.duty-status Blocked
a.duty-title(href="")
span.duty-id #1504
span.duty-name Documentación III: (notificaciones asíncronas + plugins front/back) Documentación III: (notificaciones asíncronas + plugins front/back)
div.duty-project Whatever
div.title-bar.watching-title Watching div.title-bar.watching-title Watching
// TODO Show if WATCHERS ==== false section.watching-empty(ng-show="!vm.watching.size")
section.watching-empty.hidden
include ../../svg/hide.svg include ../../svg/hide.svg
p <strong>Follow</strong> the projects, User Stories, Tasks, Issues... that you want to know about :) // TODO: i18n
p(translate="HOME.EMPTY_WATCHING")
section.watching(ng-show="vm.watching")
div.duty-single(tg-duty="duty", tg-repeat="duty in vm.watching", ng-class="{blocked: duty.is_blocked}")
// TODO Show if WATCHERS ==== true
section.watching
- for (var x = 0; x < 20; x++)
div.duty-single
img.avatar(src="https://s3.amazonaws.com/uifaces/faces/twitter/annapickard/128.jpg", title="{{ user.fullname }}")
div.duty-data
div
// TODO, ADD THEIR COLOR TO THE DUTY TYPE AND STATUS
span.duty-type User Story
span.duty-status New
a.duty-title(href="")
span.duty-id #1504
span.duty-name Documentación III: (notificaciones asíncronas + plugins front/back)
div.duty-project Taiga
div.duty-single
img.avatar(src="https://s3.amazonaws.com/uifaces/faces/twitter/sircookieface/128.jpg", title="{{ user.fullname }}")
div.duty-data
div
// TODO, ADD THEIR COLOR TO THE DUTY TYPE AND STATUS
span.duty-type Bug
span.duty-status Ready for test
a.duty-title(href="")
span.duty-id #28
span.duty-name It is not possible to re-order stories in the sprint view .
div.duty-project Teletransportation hubs
a.button-gray.see-more(href="#", title="See more Watching US") See more
aside.project-list(tg-home-project-list) aside.project-list(tg-home-project-list)

View File

@ -1,4 +1,4 @@
ul.home-project-list(ng-show="vm.projects.length") ul.home-project-list(ng-show="vm.projects.size")
li.home-project-list-single(tg-bind-scope, tg-repeat="project in vm.projects") li.home-project-list-single(tg-bind-scope, tg-repeat="project in vm.projects")
a(href="#", tg-nav="project:project=project.slug") a(href="#", tg-nav="project:project=project.slug")
h2.home-project-list-single-title h2.home-project-list-single-title
@ -7,8 +7,8 @@ ul.home-project-list(ng-show="vm.projects.length")
include ../../../svg/lock.svg include ../../../svg/lock.svg
p {{ ::project.description | limitTo:150 }} p {{ ::project.description | limitTo:150 }}
span(ng-if="::project.description.length > 150") ... span(ng-if="::project.description.length > 150") ...
a.see-more-projects-btn.button-gray(ng-show="vm.projects.length", href="#", tg-nav="projects", title="{{'PROJECT.NAVIGATION.SEE_MORE_PROJECTS' | translate}}", translate="PROJECT.NAVIGATION.SEE_MORE_PROJECTS") a.see-more-projects-btn.button-gray(ng-show="vm.projects.size", href="#", tg-nav="projects", title="{{'PROJECT.NAVIGATION.SEE_MORE_PROJECTS' | translate}}", translate="PROJECT.NAVIGATION.SEE_MORE_PROJECTS")
section.projects-empty(ng-hide="vm.projects.length") section.projects-empty(ng-hide="vm.projects.size")
include ../../../svg/empty-project.svg include ../../../svg/empty-project.svg
p You don't have any projects yet p You don't have any projects yet
a.create-project-btn.button-green( a.create-project-btn.button-green(
@ -16,5 +16,3 @@ section.projects-empty(ng-hide="vm.projects.length")
ng-click="vm.newProject()", ng-click="vm.newProject()",
title="{{'PROJECT.NAVIGATION.ACTION_CREATE_PROJECT' | translate}}", title="{{'PROJECT.NAVIGATION.ACTION_CREATE_PROJECT' | translate}}",
translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT") translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT")

View File

@ -11,12 +11,13 @@ class ProjectsPageController extends taiga.Controller
"$projectUrl", "$projectUrl",
"$tgConfig", "$tgConfig",
"tgLoader", "tgLoader",
"tgProjects" "tgProjects",
"$translate"
] ]
constructor: (@scope, @q, @rs, @rootscope, @navUrls, @auth, @location, constructor: (@scope, @q, @rs, @rootscope, @navUrls, @auth, @location,
@appTitle, @projectUrl, @config, tgLoader, @projects) -> @appTitle, @projectUrl, @config, tgLoader, @projects, @translate) ->
@appTitle.set("Projects") @appTitle.set(@translate.instant("PROJECT.SECTION_PROJECTS"))
if !@auth.isAuthenticated() if !@auth.isAuthenticated()
@location.path(@navUrls.resolve("login")) @location.path(@navUrls.resolve("login"))

View File

@ -1,8 +1,12 @@
taiga = @.taiga
groupBy = @.taiga.groupBy
class ProjectsService extends taiga.Service class ProjectsService extends taiga.Service
@.$inject = ["$q", "$tgResources", "$rootScope", "$projectUrl", "tgLightboxFactory"] @.$inject = ["$q", "$tgResources", "$rootScope", "$projectUrl", "tgLightboxFactory"]
constructor: (@q, @rs, @rootScope, @projectUrl, @lightboxFactory) -> constructor: (@q, @rs, @rootScope, @projectUrl, @lightboxFactory) ->
@.projects = Immutable.Map() @.projects = Immutable.Map()
@.projectsById = Immutable.Map()
@.inProgress = false @.inProgress = false
@.projectsPromise = null @.projectsPromise = null
@.fetchProjects() @.fetchProjects()
@ -19,6 +23,8 @@ class ProjectsService extends taiga.Service
recents: projects.slice(0, 10) recents: projects.slice(0, 10)
}) })
@.projectsById = Immutable.fromJS(groupBy(projects, (p) -> p.id))
return @.projects return @.projects
@.projectsPromise.then () => @.projectsPromise.then () =>