Adding lost files
parent
bdf97faf50
commit
6815a9c8d0
|
@ -0,0 +1,12 @@
|
||||||
|
class FeedbackService extends taiga.Service
|
||||||
|
@.$inject = ["tgLightboxFactory"]
|
||||||
|
|
||||||
|
constructor: (@lightboxFactory) ->
|
||||||
|
|
||||||
|
|
||||||
|
sendFeedback: ->
|
||||||
|
@lightboxFactory.create("tg-lb-feedback", {
|
||||||
|
"class": "lightbox lightbox-feedback lightbox-generic-form"
|
||||||
|
})
|
||||||
|
|
||||||
|
angular.module("taigaFeedback").service("tgFeedbackService", FeedbackService)
|
|
@ -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", "tgProjectsService", "$translate", DutyDirective])
|
|
@ -0,0 +1,73 @@
|
||||||
|
.working-on,
|
||||||
|
.watching {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
.duty-single {
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid $whitish;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: .5rem;
|
||||||
|
&:last-child {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
&.blocked {
|
||||||
|
background: rgba($red-light, .2);
|
||||||
|
.duty-type,
|
||||||
|
.duty-status {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
flex-basis: 47px;
|
||||||
|
height: 47px;
|
||||||
|
margin-right: .5rem;
|
||||||
|
width: 47px;
|
||||||
|
}
|
||||||
|
.duty-data {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: .5rem;
|
||||||
|
}
|
||||||
|
.duty-type,
|
||||||
|
.duty-status {
|
||||||
|
@extend %small;
|
||||||
|
color: $gray;
|
||||||
|
margin-right: .3rem;
|
||||||
|
}
|
||||||
|
.duty-title {
|
||||||
|
display: block;
|
||||||
|
margin-top: .25rem;
|
||||||
|
}
|
||||||
|
.duty-id {
|
||||||
|
color: $gray-light;
|
||||||
|
margin-right: .3rem;
|
||||||
|
}
|
||||||
|
.duty-project {
|
||||||
|
@extend %small;
|
||||||
|
align-self: flex-start;
|
||||||
|
color: $gray-light;
|
||||||
|
margin-left: auto;
|
||||||
|
text-align: right;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
.see-more {
|
||||||
|
display: block;
|
||||||
|
margin: 2rem 30%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.watching-empty {
|
||||||
|
padding: 5vh;
|
||||||
|
text-align: center;
|
||||||
|
svg {
|
||||||
|
margin: 2rem auto;
|
||||||
|
max-width: 160px;
|
||||||
|
text-align: center;
|
||||||
|
path {
|
||||||
|
fill: $whitish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
@extend %small;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
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 = {
|
||||||
|
templateUrl: "home/home.html"
|
||||||
|
scope: {}
|
||||||
|
link: link
|
||||||
|
}
|
||||||
|
|
||||||
|
return directive
|
||||||
|
|
||||||
|
angular.module("taigaHome").directive("tgHome", ["tgHomeService", HomeDirective])
|
|
@ -0,0 +1,24 @@
|
||||||
|
.home-wrapper {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 2rem;
|
||||||
|
.duty-summary {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 2rem;
|
||||||
|
}
|
||||||
|
.project-list {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
.see-more-projects-btn {
|
||||||
|
display: block;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
.title-bar {
|
||||||
|
@extend %title;
|
||||||
|
@extend %larger;
|
||||||
|
align-content: center;
|
||||||
|
background: $whitish;
|
||||||
|
display: flex;
|
||||||
|
margin: 0 0 .5rem;
|
||||||
|
padding: .9rem 1rem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
|
@ -0,0 +1,18 @@
|
||||||
|
HomeProjectListDirective = (projectsService) ->
|
||||||
|
link = (scope, el, attrs, ctrl) ->
|
||||||
|
scope.vm = {}
|
||||||
|
|
||||||
|
taiga.defineImmutableProperty(scope.vm, "projects", () -> projectsService.projects.get("recents"))
|
||||||
|
|
||||||
|
scope.vm.newProject = ->
|
||||||
|
projectsService.newProject()
|
||||||
|
|
||||||
|
directive = {
|
||||||
|
templateUrl: "home/projects/home-project-list.html"
|
||||||
|
scope: {}
|
||||||
|
link: link
|
||||||
|
}
|
||||||
|
|
||||||
|
return directive
|
||||||
|
|
||||||
|
angular.module("taigaHome").directive("tgHomeProjectList", ["tgProjectsService", HomeProjectListDirective])
|
|
@ -0,0 +1,18 @@
|
||||||
|
ul.home-project-list(ng-show="vm.projects.size")
|
||||||
|
li.home-project-list-single(tg-bind-scope, tg-repeat="project in vm.projects")
|
||||||
|
a(href="#", tg-nav="project:project=project.slug")
|
||||||
|
h2.home-project-list-single-title
|
||||||
|
span.project-name(ng-bind="::project.name", title="{{ ::project.name }}")
|
||||||
|
span.private(ng-if="project.is_private", title="{{'PROJECT.PRIVATE' | translate}}")
|
||||||
|
include ../../../svg/lock.svg
|
||||||
|
p {{ ::project.description | limitTo:150 }}
|
||||||
|
span(ng-if="::project.description.length > 150") ...
|
||||||
|
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.size")
|
||||||
|
include ../../../svg/empty-project.svg
|
||||||
|
p You don't have any projects yet
|
||||||
|
a.create-project-btn.button-green(
|
||||||
|
href="#",
|
||||||
|
ng-click="vm.newProject()",
|
||||||
|
title="{{'PROJECT.NAVIGATION.ACTION_CREATE_PROJECT' | translate}}",
|
||||||
|
translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT")
|
|
@ -0,0 +1,71 @@
|
||||||
|
.home-project-list {
|
||||||
|
li {
|
||||||
|
border-right: 5px solid $whitish;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
padding: .5rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
transition: border-color .3s linear;
|
||||||
|
&:hover {
|
||||||
|
border-color: $fresh-taiga;
|
||||||
|
p {
|
||||||
|
color: $gray;
|
||||||
|
}
|
||||||
|
.private path {
|
||||||
|
fill: $gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
@extend %text;
|
||||||
|
color: $gray;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-bottom: 0;
|
||||||
|
text-transform: none;
|
||||||
|
.project-name {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 90%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.private {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: .3rem;
|
||||||
|
width: .5rem;
|
||||||
|
path {
|
||||||
|
fill: $gray-light;
|
||||||
|
transition: fill .3s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
@extend %text;
|
||||||
|
@extend %small;
|
||||||
|
color: $gray-light;
|
||||||
|
margin: 0;
|
||||||
|
transition: color .3s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.projects-empty {
|
||||||
|
text-align: center;
|
||||||
|
svg {
|
||||||
|
height: 100px;
|
||||||
|
margin: 1rem auto;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
path {
|
||||||
|
fill: $whitish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
@extend %small;
|
||||||
|
}
|
||||||
|
.create-project-btn {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
ProjectsListingDirective = (projectsService) ->
|
||||||
|
link = (scope, el, attrs, ctrl) ->
|
||||||
|
scope.vm = {}
|
||||||
|
itemEl = null
|
||||||
|
tdom = el.find(".js-sortable")
|
||||||
|
|
||||||
|
tdom.sortable({
|
||||||
|
dropOnEmpty: true
|
||||||
|
revert: 200
|
||||||
|
axis: "y"
|
||||||
|
opacity: .95
|
||||||
|
placeholder: 'placeholder'
|
||||||
|
})
|
||||||
|
|
||||||
|
tdom.on "sortstop", (event, ui) ->
|
||||||
|
itemEl = ui.item
|
||||||
|
project = itemEl.scope().project
|
||||||
|
index = itemEl.index()
|
||||||
|
|
||||||
|
sorted_project_ids = _.map(scope.vm.projects.toArray(), (p) -> p.id)
|
||||||
|
sorted_project_ids = _.without(sorted_project_ids, project.id)
|
||||||
|
sorted_project_ids.splice(index, 0, project.id)
|
||||||
|
sortData = []
|
||||||
|
for value, index in sorted_project_ids
|
||||||
|
sortData.push({"project_id": value, "order":index})
|
||||||
|
|
||||||
|
projectsService.bulkUpdateProjectsOrder(sortData)
|
||||||
|
|
||||||
|
taiga.defineImmutableProperty(scope.vm, "projects", () -> projectsService.projects.get("all"))
|
||||||
|
|
||||||
|
scope.vm.newProject = ->
|
||||||
|
projectsService.newProject()
|
||||||
|
|
||||||
|
directive = {
|
||||||
|
templateUrl: "projects/listing/projects-listing.html"
|
||||||
|
scope: {}
|
||||||
|
link: link
|
||||||
|
}
|
||||||
|
|
||||||
|
return directive
|
||||||
|
|
||||||
|
angular.module("taigaProjects").directive("tgProjectsListing", ["tgProjectsService", ProjectsListingDirective])
|
|
@ -0,0 +1,32 @@
|
||||||
|
div.project-list-wrapper.centered
|
||||||
|
div.project-list-title
|
||||||
|
h1(translate="PROJECTS.MY_PROJECTS")
|
||||||
|
div.create-options
|
||||||
|
a.create-project-btn.button-green(href="#", ng-click="vm.newProject()", title="{{'PROJECT.NAVIGATION.ACTION_CREATE_PROJECT' | translate}}", translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT")
|
||||||
|
span(tg-import-project-button)
|
||||||
|
a.button-blackish.import-project-button(href="", title="{{'PROJECT.NAVIGATION.TITLE_ACTION_IMPORT' | translate}}")
|
||||||
|
span.icon.icon-upload
|
||||||
|
input.import-file.hidden(type="file")
|
||||||
|
|
||||||
|
section.project-list-section
|
||||||
|
div.project-list
|
||||||
|
ul.js-sortable
|
||||||
|
li.project-list-single(tg-bind-scope, tg-repeat="project in vm.projects")
|
||||||
|
div.project-list-single-left
|
||||||
|
div.project-list-single-title
|
||||||
|
h1
|
||||||
|
a(href="#", tg-nav="project:project=project.slug")
|
||||||
|
h1.project-name(ng-bind="::project.name", title="{{ ::project.name }}")
|
||||||
|
span.private(ng-if="project.is_private", title="{{'PROJECT.PRIVATE' | translate}}")
|
||||||
|
include ../../../svg/lock.svg
|
||||||
|
p {{ ::project.description | limitTo:300 }}
|
||||||
|
span(ng-if="::project.description.length > 300") ...
|
||||||
|
|
||||||
|
div.project-list-single-tags.tags-container(ng-if="::project.tags")
|
||||||
|
div.tags-block(tg-colorize-tags="project.tags", tg-colorize-tags-type="backlog")
|
||||||
|
|
||||||
|
div.project-list-single-right
|
||||||
|
span.drag.icon.icon-drag-v
|
||||||
|
|
||||||
|
aside.help-area
|
||||||
|
p(translate="PROJECT.HELP")
|
|
@ -0,0 +1,97 @@
|
||||||
|
.project-list-single {
|
||||||
|
border-bottom: 1px solid $whitish;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: .5rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-list-single-left,
|
||||||
|
.project-list-single-right {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-list-single-left {
|
||||||
|
align-content: space-between;
|
||||||
|
flex: 4;
|
||||||
|
h1 {
|
||||||
|
@extend %text;
|
||||||
|
@extend %large;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 0;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
.project-name {
|
||||||
|
@extend %text;
|
||||||
|
@extend %larger;
|
||||||
|
color: $gray;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.private {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: .3rem;
|
||||||
|
width: .5rem;
|
||||||
|
path {
|
||||||
|
fill: $gray-light;
|
||||||
|
transition: fill .3s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
@extend %text;
|
||||||
|
@extend %small;
|
||||||
|
color: $gray;
|
||||||
|
margin-bottom: 0;
|
||||||
|
max-width: 95%;
|
||||||
|
}
|
||||||
|
.project-list-single-tags {
|
||||||
|
align-content: flex-end;
|
||||||
|
display: flex;
|
||||||
|
flex: 3;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-top: .5rem;
|
||||||
|
}
|
||||||
|
.tag {
|
||||||
|
align-self: flex-end;
|
||||||
|
margin-right: .5rem;
|
||||||
|
padding: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-list-single-right {
|
||||||
|
justify-content: space-between;
|
||||||
|
.project-list-single-stats {
|
||||||
|
align-self: flex-end;
|
||||||
|
display: flex;
|
||||||
|
div {
|
||||||
|
color: $gray-light;
|
||||||
|
margin-right: .5rem;
|
||||||
|
.icon {
|
||||||
|
margin-right: .2rem;
|
||||||
|
vertical-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
.icon {
|
||||||
|
color: $star-fill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.project-list-single-members {
|
||||||
|
align-self: flex-end;
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: 1rem;
|
||||||
|
max-width: 160px;
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
margin-right: .3rem;
|
||||||
|
width: 34px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue