Add existing issue to sprint from taskboard
parent
8e12fd3528
commit
92460e3733
|
@ -567,10 +567,10 @@ $translate, $compile, $currentUserService, avatarService) ->
|
||||||
renderUser = (assignedObject) ->
|
renderUser = (assignedObject) ->
|
||||||
if assignedObject?.assigned_to
|
if assignedObject?.assigned_to
|
||||||
$scope.selected = assignedObject.assigned_to
|
$scope.selected = assignedObject.assigned_to
|
||||||
assignedObject.assigned_to_extra_info = $scope.usersById[$scope.selected]
|
assigned_to_extra_info = $scope.usersById[$scope.selected]
|
||||||
$scope.fullName = assignedObject.assigned_to_extra_info?.full_name_display
|
$scope.fullName = assigned_to_extra_info?.full_name_display
|
||||||
$scope.isUnassigned = false
|
$scope.isUnassigned = false
|
||||||
$scope.avatar = avatarService.getAvatar(assignedObject.assigned_to_extra_info)
|
$scope.avatar = avatarService.getAvatar(assigned_to_extra_info)
|
||||||
$scope.bg = $scope.avatar.bg
|
$scope.bg = $scope.avatar.bg
|
||||||
$scope.isIocaine = assignedObject?.is_iocaine
|
$scope.isIocaine = assignedObject?.is_iocaine
|
||||||
else
|
else
|
||||||
|
|
|
@ -779,7 +779,13 @@ CreateEditDirective = (
|
||||||
$log, $repo, $model, $rs, $rootScope, lightboxService, $loading, $translate,
|
$log, $repo, $model, $rs, $rootScope, lightboxService, $loading, $translate,
|
||||||
$confirm, $q, attachmentsService, $template, $compile) ->
|
$confirm, $q, attachmentsService, $template, $compile) ->
|
||||||
link = ($scope, $el, attrs) ->
|
link = ($scope, $el, attrs) ->
|
||||||
|
schema = null
|
||||||
|
objType = null
|
||||||
form = null
|
form = null
|
||||||
|
|
||||||
|
attachmentsToAdd = Immutable.List()
|
||||||
|
attachmentsToDelete = Immutable.List()
|
||||||
|
|
||||||
schemas = {
|
schemas = {
|
||||||
us: {
|
us: {
|
||||||
objName: 'User Story',
|
objName: 'User Story',
|
||||||
|
@ -851,67 +857,50 @@ $confirm, $q, attachmentsService, $template, $compile) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attachmentsToAdd = Immutable.List()
|
|
||||||
attachmentsToDelete = Immutable.List()
|
|
||||||
|
|
||||||
$scope.$on "genericform:new", (ctx, data) ->
|
$scope.$on "genericform:new", (ctx, data) ->
|
||||||
if beforeMount('new', data, ['project'])
|
getSchema(data)
|
||||||
mountCreateForm(data)
|
$scope.mode = 'new'
|
||||||
afterMount()
|
$scope.getOrCreate = false
|
||||||
|
mount(data)
|
||||||
|
|
||||||
|
$scope.$on "genericform:new-or-existing", (ctx, data) ->
|
||||||
|
getSchema(data)
|
||||||
|
$scope.mode = 'add-existing'
|
||||||
|
$scope.getOrCreate = true
|
||||||
|
$scope.existingFilterText = ''
|
||||||
|
$scope.existingItems = {}
|
||||||
|
$scope.existingOptions = data.existingOptions
|
||||||
|
mount(data)
|
||||||
|
|
||||||
$scope.$on "genericform:edit", (ctx, data) ->
|
$scope.$on "genericform:edit", (ctx, data) ->
|
||||||
if beforeMount('edit', data, ['project', 'obj', 'attachments'])
|
getSchema(data)
|
||||||
mountUpdateForm(data)
|
$scope.mode = 'edit'
|
||||||
afterMount()
|
$scope.getOrCreate = false
|
||||||
|
mount(data)
|
||||||
|
|
||||||
beforeMount = (mode, data, requiredAttrs) ->
|
getSchema = (data) ->
|
||||||
form.reset() if form
|
|
||||||
|
|
||||||
# Get form schema
|
|
||||||
if !data.objType || !schemas[data.objType]
|
|
||||||
return $log.error(
|
|
||||||
"Invalid objType `#{data.objType}` for `genericform:#{mode}` event")
|
|
||||||
$scope.objType = data.objType
|
$scope.objType = data.objType
|
||||||
$scope.schema = schemas[data.objType]
|
if !$scope.objType || !schemas[$scope.objType]
|
||||||
|
return $log.error("Invalid objType `#{$scope.objType}` for `genericform` event")
|
||||||
|
schema = schemas[$scope.objType]
|
||||||
|
|
||||||
# Get required attrs of the directive
|
mount = (data) ->
|
||||||
getAttrs(mode, data, requiredAttrs)
|
$scope.objName = schema.objName
|
||||||
|
if $scope.mode == 'edit'
|
||||||
|
$scope.obj = data.obj
|
||||||
|
$scope.attachments = Immutable.fromJS(data.attachments)
|
||||||
|
else
|
||||||
|
$scope.obj = $model.make_model(schema.model, schema.initialData(data))
|
||||||
|
$scope.attachments = Immutable.List()
|
||||||
|
|
||||||
return true
|
_.map schema.data($scope.project), (value, key) ->
|
||||||
|
$scope[key] = value
|
||||||
|
|
||||||
mountCreateForm = (data) ->
|
form.reset() if form
|
||||||
$scope.obj = $model.make_model($scope.schema.model, $scope.schema.initialData(data))
|
|
||||||
$scope.isNew = true
|
|
||||||
$scope.attachments = Immutable.List()
|
|
||||||
$scope.text = {
|
|
||||||
title: $translate.instant("LIGHTBOX.CREATE_EDIT.NEW", { objName: $scope.schema.objName })
|
|
||||||
action: $translate.instant("COMMON.CREATE")
|
|
||||||
}
|
|
||||||
render()
|
|
||||||
|
|
||||||
mountUpdateForm = (data) ->
|
|
||||||
$scope.isNew = false
|
|
||||||
$scope.attachments = Immutable.fromJS($scope.attachments)
|
|
||||||
$scope.text = {
|
|
||||||
title: $translate.instant("LIGHTBOX.CREATE_EDIT.EDIT", { objName: $scope.schema.objName })
|
|
||||||
action: $translate.instant("COMMON.SAVE")
|
|
||||||
}
|
|
||||||
render()
|
|
||||||
|
|
||||||
afterMount = () ->
|
|
||||||
resetAttachments()
|
resetAttachments()
|
||||||
setStatus($scope.obj?.status)
|
setStatus($scope.obj.status)
|
||||||
|
$scope.lightboxOpen = true
|
||||||
|
lightboxService.open($el)
|
||||||
$scope.createEditOpen = true
|
|
||||||
lightboxService.open $el, () ->
|
|
||||||
$scope.createEditOpen = false
|
|
||||||
|
|
||||||
getAttrs = (mode, data, attrs) ->
|
|
||||||
for attr in attrs
|
|
||||||
if !data[attr]
|
|
||||||
return $log.error "`#{attr}` attribute required in `genericform:#{mode}` event"
|
|
||||||
$scope[attr] = data[attr]
|
|
||||||
|
|
||||||
resetAttachments = () ->
|
resetAttachments = () ->
|
||||||
attachmentsToAdd = Immutable.List()
|
attachmentsToAdd = Immutable.List()
|
||||||
|
@ -929,7 +918,6 @@ $confirm, $q, attachmentsService, $template, $compile) ->
|
||||||
|
|
||||||
$scope.addTag = (tag, color) ->
|
$scope.addTag = (tag, color) ->
|
||||||
value = trim(tag.toLowerCase())
|
value = trim(tag.toLowerCase())
|
||||||
|
|
||||||
tags = $scope.project.tags
|
tags = $scope.project.tags
|
||||||
projectTags = $scope.project.tags_colors
|
projectTags = $scope.project.tags_colors
|
||||||
|
|
||||||
|
@ -940,11 +928,9 @@ $confirm, $q, attachmentsService, $template, $compile) ->
|
||||||
tags.push(value)
|
tags.push(value)
|
||||||
|
|
||||||
projectTags[tag] = color || null
|
projectTags[tag] = color || null
|
||||||
|
|
||||||
$scope.project.tags = tags
|
$scope.project.tags = tags
|
||||||
|
|
||||||
itemtags = _.clone($scope.obj.tags)
|
itemtags = _.clone($scope.obj.tags)
|
||||||
|
|
||||||
inserted = _.find itemtags, (it) -> it[0] == value
|
inserted = _.find itemtags, (it) -> it[0] == value
|
||||||
|
|
||||||
if !inserted
|
if !inserted
|
||||||
|
@ -953,98 +939,117 @@ $confirm, $q, attachmentsService, $template, $compile) ->
|
||||||
|
|
||||||
$scope.deleteTag = (tag) ->
|
$scope.deleteTag = (tag) ->
|
||||||
value = trim(tag[0].toLowerCase())
|
value = trim(tag[0].toLowerCase())
|
||||||
|
|
||||||
tags = $scope.project.tags
|
tags = $scope.project.tags
|
||||||
itemtags = _.clone($scope.obj.tags)
|
itemtags = _.clone($scope.obj.tags)
|
||||||
|
|
||||||
_.remove itemtags, (tag) -> tag[0] == value
|
_.remove itemtags, (tag) -> tag[0] == value
|
||||||
|
|
||||||
$scope.obj.tags = itemtags
|
$scope.obj.tags = itemtags
|
||||||
|
|
||||||
_.pull($scope.obj.tags, value)
|
_.pull($scope.obj.tags, value)
|
||||||
|
|
||||||
|
|
||||||
createAttachments = (obj) ->
|
createAttachments = (obj) ->
|
||||||
promises = _.map attachmentsToAdd.toJS(), (attachment) ->
|
promises = _.map attachmentsToAdd.toJS(), (attachment) ->
|
||||||
attachmentsService.upload(
|
attachmentsService.upload(attachment.file, obj.id, $scope.obj.project, $scope.objType)
|
||||||
attachment.file, obj.id, $scope.obj.project, $scope.objType)
|
|
||||||
|
|
||||||
return $q.all(promises)
|
return $q.all(promises)
|
||||||
|
|
||||||
deleteAttachments = (obj) ->
|
deleteAttachments = (obj) ->
|
||||||
promises = _.map attachmentsToDelete.toJS(), (attachment) ->
|
promises = _.map attachmentsToDelete.toJS(), (attachment) ->
|
||||||
return attachmentsService.delete($scope.objType, attachment.id)
|
return attachmentsService.delete($scope.objType, attachment.id)
|
||||||
|
|
||||||
return $q.all(promises)
|
return $q.all(promises)
|
||||||
|
|
||||||
submit = debounce 2000, (event) ->
|
addExisting = (ref) ->
|
||||||
event.preventDefault()
|
currentLoading = $loading().target($el.find(".add-existing-button")).start()
|
||||||
|
selectedItem = $scope.existingItems[parseInt(ref)]
|
||||||
|
selectedItem.setAttr($scope.existingOptions.targetField, $scope.existingOptions.targetValue)
|
||||||
|
$repo.save(selectedItem, true).then (data) ->
|
||||||
|
currentLoading.finish()
|
||||||
|
lightboxService.close($el)
|
||||||
|
$rootScope.$broadcast("#{$scope.objType}form:add:success", selectedItem)
|
||||||
|
|
||||||
|
$scope.getTargetTitle = (item) ->
|
||||||
|
index = item[$scope.existingOptions.targetField]
|
||||||
|
return $scope.existingOptions.targetsById[index]?.name
|
||||||
|
|
||||||
|
$scope.existingFilterChanged = (value) ->
|
||||||
|
if value?
|
||||||
|
$rs[schema.model].listInAllProjects(
|
||||||
|
{ project: $scope.project.id, q: value }, true
|
||||||
|
).then (data) ->
|
||||||
|
$scope.existingItems = {}
|
||||||
|
_.map(data, (itemModel) ->
|
||||||
|
itemModel.html = itemModel.subject
|
||||||
|
|
||||||
|
targetTitle = $scope.getTargetTitle(itemModel)
|
||||||
|
if targetTitle
|
||||||
|
itemModel.html = "#{itemModel.html} (#{targetTitle})"
|
||||||
|
itemModel.class = 'strong'
|
||||||
|
|
||||||
|
$scope.existingItems[itemModel.ref] = itemModel
|
||||||
|
)
|
||||||
|
|
||||||
|
$scope.addExisting = (selectedItem) ->
|
||||||
|
event.preventDefault()
|
||||||
|
addExisting(selectedItem)
|
||||||
|
|
||||||
|
submit = debounce 2000, (event) ->
|
||||||
form = $el.find("form").checksley()
|
form = $el.find("form").checksley()
|
||||||
if not form.validate()
|
if not form.validate()
|
||||||
return
|
return
|
||||||
|
|
||||||
currentLoading = $loading().target(submitButton).start()
|
currentLoading = $loading().target($el.find(".submit-button")).start()
|
||||||
|
|
||||||
if $scope.isNew
|
if $scope.mode == 'new'
|
||||||
promise = $repo.create($scope.schema.model, $scope.obj)
|
promise = $repo.create(schema.model, $scope.obj)
|
||||||
broadcastEvent = "#{$scope.objType}form:new:success"
|
broadcastEvent = "#{$scope.objType}form:new:success"
|
||||||
else
|
else
|
||||||
|
if ($scope.obj.due_date instanceof moment)
|
||||||
|
prettyDate = $translate.instant("COMMON.PICKERDATE.FORMAT")
|
||||||
|
$scope.obj.due_date = $scope.obj.due_date.format("YYYY-MM-DD")
|
||||||
|
|
||||||
promise = $repo.save($scope.obj, true)
|
promise = $repo.save($scope.obj, true)
|
||||||
broadcastEvent = "#{$scope.objType}form:edit:success"
|
broadcastEvent = "#{$scope.objType}form:edit:success"
|
||||||
|
|
||||||
promise.then (data) ->
|
promise.then (data) ->
|
||||||
deleteAttachments(data)
|
deleteAttachments(data).then () ->
|
||||||
.then () -> createAttachments(data)
|
createAttachments(data).then () ->
|
||||||
.then () ->
|
|
||||||
currentLoading.finish()
|
currentLoading.finish()
|
||||||
lightboxService.close($el)
|
close()
|
||||||
|
$rs[schema.model].getByRef(data.project, data.ref, schema.params).then (obj) ->
|
||||||
$rs[$scope.schema.model].getByRef(
|
$rootScope.$broadcast(broadcastEvent, obj)
|
||||||
data.project, data.ref, $scope.schema.params).then (obj) ->
|
|
||||||
$rootScope.$broadcast(broadcastEvent, obj)
|
|
||||||
|
|
||||||
promise.then null, (data) ->
|
promise.then null, (data) ->
|
||||||
currentLoading.finish()
|
currentLoading.finish()
|
||||||
form.setErrors(data)
|
form.setErrors(data)
|
||||||
if data._error_message
|
if data._error_message
|
||||||
$confirm.notify("error", data._error_message)
|
$confirm.notify("error", data._error_message)
|
||||||
|
|
||||||
submitButton = $el.find(".submit-button")
|
checkClose = () ->
|
||||||
|
|
||||||
close = () ->
|
|
||||||
if !$scope.obj.isModified()
|
if !$scope.obj.isModified()
|
||||||
lightboxService.close($el)
|
close()
|
||||||
$scope.$apply ->
|
$scope.$apply ->
|
||||||
$scope.obj.revert()
|
$scope.obj.revert()
|
||||||
else
|
else
|
||||||
$confirm.ask(
|
$confirm.ask(
|
||||||
$translate.instant("LIGHTBOX.CREATE_EDIT.CONFIRM_CLOSE")).then (result) ->
|
$translate.instant("LIGHTBOX.CREATE_EDIT.CONFIRM_CLOSE")).then (result) ->
|
||||||
lightboxService.close($el)
|
|
||||||
$scope.obj.revert()
|
|
||||||
result.finish()
|
result.finish()
|
||||||
|
close()
|
||||||
|
|
||||||
|
close = () ->
|
||||||
|
delete $scope.objType
|
||||||
|
delete $scope.mode
|
||||||
|
$scope.lightboxOpen = false
|
||||||
|
lightboxService.close($el)
|
||||||
|
|
||||||
$el.on "submit", "form", submit
|
$el.on "submit", "form", submit
|
||||||
|
|
||||||
$el.find('.close').on "click", (event) ->
|
$el.find('.close').on "click", (event) ->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
close()
|
checkClose()
|
||||||
|
|
||||||
$el.keydown (event) ->
|
$el.keydown (event) ->
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
code = if event.keyCode then event.keyCode else event.which
|
code = if event.keyCode then event.keyCode else event.which
|
||||||
if code == 27
|
if code == 27
|
||||||
close()
|
checkClose()
|
||||||
|
|
||||||
$scope.$on "$destroy", ->
|
|
||||||
$el.find('.close').off()
|
|
||||||
$el.off()
|
|
||||||
|
|
||||||
$scope.$watch "obj", ->
|
|
||||||
if !$scope.obj
|
|
||||||
return
|
|
||||||
setStatus($scope.obj.status)
|
|
||||||
|
|
||||||
$el.on "click", ".status-dropdown", (event) ->
|
$el.on "click", ".status-dropdown", (event) ->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
@ -1080,28 +1085,30 @@ $confirm, $q, attachmentsService, $template, $compile) ->
|
||||||
$scope.obj.is_iocaine = not $scope.obj.is_iocaine
|
$scope.obj.is_iocaine = not $scope.obj.is_iocaine
|
||||||
$scope.$broadcast("isiocaine:changed", $scope.obj)
|
$scope.$broadcast("isiocaine:changed", $scope.obj)
|
||||||
|
|
||||||
setStatus = (id) ->
|
|
||||||
$scope.obj.status = id
|
|
||||||
$scope.selectedStatus = _.find $scope.statusList, (item) -> item.id == id
|
|
||||||
|
|
||||||
$scope.isTeamRequirement = () ->
|
$scope.isTeamRequirement = () ->
|
||||||
return $scope.obj?.team_requirement
|
return $scope.obj?.team_requirement
|
||||||
|
|
||||||
$scope.isClientRequirement = () ->
|
$scope.isClientRequirement = () ->
|
||||||
return $scope.obj?.client_requirement
|
return $scope.obj?.client_requirement
|
||||||
|
|
||||||
render = () ->
|
setStatus = (id) ->
|
||||||
templatePath = "common/lightbox/lightbox-create-edit/lb-create-edit-#{$scope.objType}.html"
|
$scope.obj.status = id
|
||||||
template = $template.get(templatePath, true)
|
$scope.selectedStatus = _.find $scope.statusList, (item) -> item.id == id
|
||||||
|
$scope.obj.is_closed = $scope.selectedStatus.is_closed
|
||||||
|
|
||||||
_.map $scope.schema.data($scope.project), (value, key) ->
|
render = () ->
|
||||||
|
# templatePath = "common/lightbox/lightbox-create-edit/lb-create-edit-#{$scope.objType}.html"
|
||||||
|
# template = $template.get(templatePath, true)
|
||||||
|
|
||||||
|
_.map schema.data($scope.project), (value, key) ->
|
||||||
$scope[key] = value
|
$scope[key] = value
|
||||||
|
|
||||||
html = $compile(template($scope))($scope)
|
# html = $compile(template($scope))($scope)
|
||||||
$el.html(html)
|
# $el.html(html)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
link: link
|
link: link
|
||||||
|
templateUrl: "common/lightbox/lightbox-create-edit/lb-create-edit.html"
|
||||||
}
|
}
|
||||||
|
|
||||||
module.directive("tgLbCreateEdit", [
|
module.directive("tgLbCreateEdit", [
|
||||||
|
|
|
@ -107,7 +107,7 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
||||||
|
|
||||||
else if @.zoomLevel > 1 && previousZoomLevel <= 1
|
else if @.zoomLevel > 1 && previousZoomLevel <= 1
|
||||||
@.zoomLoading = true
|
@.zoomLoading = true
|
||||||
@.loadTasks().then () =>
|
@q.all([@.loadTasks(), @.loadIssues()]).then () =>
|
||||||
@.zoomLoading = false
|
@.zoomLoading = false
|
||||||
@taskboardTasksService.resetFolds()
|
@taskboardTasksService.resetFolds()
|
||||||
|
|
||||||
|
@ -320,6 +320,10 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
||||||
|
|
||||||
@analytics.trackEvent("issue", "create", "create issue on taskboard", 1)
|
@analytics.trackEvent("issue", "create", "create issue on taskboard", 1)
|
||||||
|
|
||||||
|
@scope.$on "issueform:add:success", (event, issue) =>
|
||||||
|
@.refreshTagsColors().then () =>
|
||||||
|
@taskboardIssuesService.add(issue)
|
||||||
|
|
||||||
@scope.$on "issueform:edit:success", (event, issue) =>
|
@scope.$on "issueform:edit:success", (event, issue) =>
|
||||||
@.refreshTagsColors().then () =>
|
@.refreshTagsColors().then () =>
|
||||||
@taskboardIssuesService.replaceModel(issue)
|
@taskboardIssuesService.replaceModel(issue)
|
||||||
|
@ -376,6 +380,8 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
||||||
@scope.taskStatusList = _.sortBy(project.task_statuses, "order")
|
@scope.taskStatusList = _.sortBy(project.task_statuses, "order")
|
||||||
@scope.usStatusList = _.sortBy(project.us_statuses, "order")
|
@scope.usStatusList = _.sortBy(project.us_statuses, "order")
|
||||||
@scope.usStatusById = groupBy(project.us_statuses, (e) -> e.id)
|
@scope.usStatusById = groupBy(project.us_statuses, (e) -> e.id)
|
||||||
|
@scope.issueStatusById = groupBy(project.issue_statuses, (e) -> e.id)
|
||||||
|
@scope.milestonesById = groupBy(project.milestones, (e) -> e.id)
|
||||||
|
|
||||||
@scope.$emit('project:loaded', project)
|
@scope.$emit('project:loaded', project)
|
||||||
|
|
||||||
|
@ -417,10 +423,14 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
||||||
|
|
||||||
loadIssues: ->
|
loadIssues: ->
|
||||||
params = {}
|
params = {}
|
||||||
|
|
||||||
|
if @.zoomLevel > 1
|
||||||
|
params.include_attachments = 1
|
||||||
|
|
||||||
params = _.merge params, @location.search()
|
params = _.merge params, @location.search()
|
||||||
|
|
||||||
return @rs.issues.listInProject(@scope.projectId, @scope.sprintId, params).then (issues) =>
|
return @rs.issues.listInProject(@scope.projectId, @scope.sprintId, params).then (issues) =>
|
||||||
@taskboardIssuesService.init(@scope.project, @scope.usersById)
|
@taskboardIssuesService.init(@scope.project, @scope.usersById, @scope.issueStatusById)
|
||||||
@taskboardIssuesService.set(issues)
|
@taskboardIssuesService.set(issues)
|
||||||
|
|
||||||
loadTasks: ->
|
loadTasks: ->
|
||||||
|
@ -544,6 +554,26 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
||||||
askResponse.finish(false)
|
askResponse.finish(false)
|
||||||
@confirm.notify("error")
|
@confirm.notify("error")
|
||||||
|
|
||||||
|
removeIssueFromSprint: (id) ->
|
||||||
|
issue = @.taskboardIssuesService.getIssue(id)
|
||||||
|
issue = issue.set('loading-delete', true)
|
||||||
|
|
||||||
|
@rs.issues.getByRef(issue.getIn(['model', 'project']), issue.getIn(['model', 'ref']))
|
||||||
|
.then (removingIssue) =>
|
||||||
|
issue = issue.set('loading-delete', false)
|
||||||
|
title = @translate.instant("ISSUES.CONFIRM_REMOVE_FROM_SPRINT.TITLE")
|
||||||
|
subtitle = @translate.instant("ISSUES.CONFIRM_REMOVE_FROM_SPRINT.MESSAGE")
|
||||||
|
message = removingIssue.subject
|
||||||
|
@confirm.askOnDelete(title, message, subtitle).then (askResponse) =>
|
||||||
|
removingIssue.milestone = null
|
||||||
|
promise = @repo.save(removingIssue)
|
||||||
|
promise.then =>
|
||||||
|
@.taskboardIssuesService.remove(removingIssue)
|
||||||
|
askResponse.finish()
|
||||||
|
promise.then null, ->
|
||||||
|
askResponse.finish(false)
|
||||||
|
@confirm.notify("error")
|
||||||
|
|
||||||
taskMove: (ctx, task, oldStatusId, usId, statusId, order) ->
|
taskMove: (ctx, task, oldStatusId, usId, statusId, order) ->
|
||||||
task = @taskboardTasksService.getTaskModel(task.get('id'))
|
task = @taskboardTasksService.getTaskModel(task.get('id'))
|
||||||
|
|
||||||
|
@ -587,17 +617,26 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
||||||
|
|
||||||
addNewIssue: (type, us) ->
|
addNewIssue: (type, us) ->
|
||||||
switch type
|
switch type
|
||||||
when "standard" then @rootscope.$broadcast("genericform:new",
|
when "standard" then @rootscope.$broadcast("genericform:new-or-existing",
|
||||||
{
|
{
|
||||||
'objType': 'issue',
|
'objType': 'issue',
|
||||||
'project': @scope.project,
|
'project': @scope.project,
|
||||||
'sprintId': @scope.sprintId
|
'sprintId': @scope.sprintId,
|
||||||
|
'existingOptions': {
|
||||||
|
targetField: 'milestone',
|
||||||
|
targetValue: @scope.sprintId,
|
||||||
|
targetsById: @scope.milestonesById,
|
||||||
|
title: "#{@translate.instant("COMMON.FIELDS.SPRINT")} #{@scope.sprint.name}",
|
||||||
|
}
|
||||||
})
|
})
|
||||||
when "standard" then @rootscope.$broadcast("taskform:new", @scope.sprintId, us?.id)
|
when "standard" then @rootscope.$broadcast("taskform:new", @scope.sprintId, us?.id)
|
||||||
when "bulk" then @rootscope.$broadcast("issueform:bulk", @scope.projectId, @scope.sprintId)
|
when "bulk" then @rootscope.$broadcast("issueform:bulk", @scope.projectId, @scope.sprintId)
|
||||||
|
|
||||||
toggleFold: (id) ->
|
toggleFold: (id, modelName) ->
|
||||||
@taskboardTasksService.toggleFold(id)
|
if modelName == 'issues'
|
||||||
|
@taskboardIssuesService.toggleFold(id)
|
||||||
|
else if modelName == 'tasks'
|
||||||
|
@taskboardTasksService.toggleFold(id)
|
||||||
|
|
||||||
changeTaskAssignedTo: (id) ->
|
changeTaskAssignedTo: (id) ->
|
||||||
task = @taskboardTasksService.getTaskModel(id)
|
task = @taskboardTasksService.getTaskModel(id)
|
||||||
|
|
|
@ -25,16 +25,33 @@ class TaskboardIssuesService extends taiga.Service
|
||||||
@.reset()
|
@.reset()
|
||||||
|
|
||||||
reset: () ->
|
reset: () ->
|
||||||
|
@.foldStatusChanged = {}
|
||||||
@.issuesRaw = []
|
@.issuesRaw = []
|
||||||
|
|
||||||
init: (project, usersById) ->
|
init: (project, usersById, issueStatusById) ->
|
||||||
|
@.issueStatusById = issueStatusById
|
||||||
@.project = project
|
@.project = project
|
||||||
@.usersById = usersById
|
@.usersById = usersById
|
||||||
|
|
||||||
|
resetFolds: () ->
|
||||||
|
@.foldStatusChanged = {}
|
||||||
|
@.refresh()
|
||||||
|
|
||||||
|
toggleFold: (issueId) ->
|
||||||
|
@.foldStatusChanged[issueId] = !@.foldStatusChanged[issueId]
|
||||||
|
@.refresh()
|
||||||
|
|
||||||
add: (issue) ->
|
add: (issue) ->
|
||||||
@.issuesRaw = @.issuesRaw.concat(issue)
|
@.issuesRaw = @.issuesRaw.concat(issue)
|
||||||
@.refresh()
|
@.refresh()
|
||||||
|
|
||||||
|
remove: (issue) ->
|
||||||
|
for key, item of @.issuesRaw
|
||||||
|
if issue.id == item.id
|
||||||
|
@.issuesRaw.splice(key, 1)
|
||||||
|
@.refresh()
|
||||||
|
return
|
||||||
|
|
||||||
set: (issues) ->
|
set: (issues) ->
|
||||||
@.issuesRaw = issues
|
@.issuesRaw = issues
|
||||||
@.refresh()
|
@.refresh()
|
||||||
|
@ -58,14 +75,14 @@ class TaskboardIssuesService extends taiga.Service
|
||||||
issues = []
|
issues = []
|
||||||
for issueModel in @.issuesRaw
|
for issueModel in @.issuesRaw
|
||||||
issue = {}
|
issue = {}
|
||||||
|
issue.foldStatusChanged = @.foldStatusChanged[issueModel.id]
|
||||||
model = issueModel.getAttrs()
|
issue.model = issueModel.getAttrs()
|
||||||
|
issue.modelName = issueModel.getName()
|
||||||
issue.model = model
|
|
||||||
issue.images = _.filter model.attachments, (it) -> return !!it.thumbnail_card_url
|
|
||||||
issue.id = issueModel.id
|
issue.id = issueModel.id
|
||||||
|
issue.status = @.issueStatusById[issueModel.status]
|
||||||
|
issue.images = _.filter issue.model.attachments, (it) -> return !!it.thumbnail_card_url
|
||||||
issue.assigned_to = @.usersById[issueModel.assigned_to]
|
issue.assigned_to = @.usersById[issueModel.assigned_to]
|
||||||
issue.colorized_tags = _.map issue.model.tags, (tag) =>
|
issue.colorized_tags = _.map issue.model.tags, (tag) ->
|
||||||
return {name: tag[0], color: tag[1]}
|
return {name: tag[0], color: tag[1]}
|
||||||
|
|
||||||
issues.push(issue)
|
issues.push(issue)
|
||||||
|
|
|
@ -140,6 +140,9 @@ class TaskboardTasksService extends taiga.Service
|
||||||
return {"task_id": task.id, "order": @.order[task.id], "set_orders": setOrders}
|
return {"task_id": task.id, "order": @.order[task.id], "set_orders": setOrders}
|
||||||
|
|
||||||
refresh: ->
|
refresh: ->
|
||||||
|
if !@.project
|
||||||
|
return
|
||||||
|
|
||||||
@.tasksRaw = _.sortBy @.tasksRaw, (it) => @.order[it.id]
|
@.tasksRaw = _.sortBy @.tasksRaw, (it) => @.order[it.id]
|
||||||
|
|
||||||
tasks = @.tasksRaw
|
tasks = @.tasksRaw
|
||||||
|
|
|
@ -48,7 +48,8 @@
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"ASSIGN_TO": "Assign To",
|
"ASSIGN_TO": "Assign To",
|
||||||
"EDIT": "Edit card",
|
"EDIT": "Edit card",
|
||||||
"DELETE": "Delete card"
|
"DELETE": "Delete card",
|
||||||
|
"REMOVE_ISSUE_FROM_SPRINT": "Remove issue from sprint"
|
||||||
},
|
},
|
||||||
"FORM_ERRORS": {
|
"FORM_ERRORS": {
|
||||||
"DEFAULT_MESSAGE": "This value seems to be invalid.",
|
"DEFAULT_MESSAGE": "This value seems to be invalid.",
|
||||||
|
@ -1097,7 +1098,12 @@
|
||||||
"PLACEHOLDER_DESCRIPTION": "Please add descriptive text to help others better understand this {{ objName }}",
|
"PLACEHOLDER_DESCRIPTION": "Please add descriptive text to help others better understand this {{ objName }}",
|
||||||
"NEW": "New {{ objName }}",
|
"NEW": "New {{ objName }}",
|
||||||
"EDIT": "Edit {{ objName }}",
|
"EDIT": "Edit {{ objName }}",
|
||||||
"CONFIRM_CLOSE": "You have not saved changes.\nAre you sure you want to close the form?"
|
"ADD_EXISTING": "Add {{ objName }} to {{ targetName }}",
|
||||||
|
"CONFIRM_CLOSE": "You have not saved changes.\nAre you sure you want to close the form?",
|
||||||
|
"EXISTING_OBJECT": "Existing {{ objName }}",
|
||||||
|
"NEW_OBJECT": "New {{ objName }}",
|
||||||
|
"CHOOSE_EXISTING": "What's the {{ objName }}?",
|
||||||
|
"NO_ITEMS_FOUND": "It looks like nothing was found with your search criteria"
|
||||||
},
|
},
|
||||||
"DELETE_DUE_DATE": {
|
"DELETE_DUE_DATE": {
|
||||||
"TITLE": "Delete due date",
|
"TITLE": "Delete due date",
|
||||||
|
@ -1351,6 +1357,8 @@
|
||||||
"TITLE_ACTION_ASSIGN": "Assign task",
|
"TITLE_ACTION_ASSIGN": "Assign task",
|
||||||
"PLACEHOLDER_CARD_TITLE": "This could be a task",
|
"PLACEHOLDER_CARD_TITLE": "This could be a task",
|
||||||
"PLACEHOLDER_CARD_TEXT": "Split Stories into tasks to track them separately",
|
"PLACEHOLDER_CARD_TEXT": "Split Stories into tasks to track them separately",
|
||||||
|
"NEW_ISSUE": "New issue",
|
||||||
|
"EXISTING_ISSUE": "Existing issue",
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"COLUMN": "User story",
|
"COLUMN": "User story",
|
||||||
"TITLE_ACTION_FOLD": "Fold column",
|
"TITLE_ACTION_FOLD": "Fold column",
|
||||||
|
@ -1426,6 +1434,10 @@
|
||||||
"SEVERITY": "Severity",
|
"SEVERITY": "Severity",
|
||||||
"TYPE": "Type"
|
"TYPE": "Type"
|
||||||
},
|
},
|
||||||
|
"CONFIRM_REMOVE_FROM_SPRINT": {
|
||||||
|
"TITLE": "Remove issue from sprint",
|
||||||
|
"MESSAGE": "Are you sure you want to remove this issue from the sprint?"
|
||||||
|
},
|
||||||
"CONFIRM_PROMOTE": {
|
"CONFIRM_PROMOTE": {
|
||||||
"TITLE": "Promote this issue to a new user story",
|
"TITLE": "Promote this issue to a new user story",
|
||||||
"MESSAGE": "Are you sure you want to create a new US from this Issue?"
|
"MESSAGE": "Are you sure you want to create a new US from this Issue?"
|
||||||
|
|
|
@ -2,13 +2,21 @@
|
||||||
ng-if="vm.visible('extra_info')"
|
ng-if="vm.visible('extra_info')"
|
||||||
ng-class="{'empty-tasks': !vm.item.getIn(['model', 'tasks']).size}"
|
ng-class="{'empty-tasks': !vm.item.getIn(['model', 'tasks']).size}"
|
||||||
)
|
)
|
||||||
span.card-estimation.not-estimated(
|
span(ng-switch="vm.item.get('modelName') == 'issues'")
|
||||||
ng-if="vm.item.getIn(['model', 'total_points']) === null && vm.visible('empty_extra_info')",
|
span(ng-switch-when="true")
|
||||||
translate="US.NOT_ESTIMATED"
|
span.card-status-tag(
|
||||||
)
|
ng-if="vm.item.get('status')"
|
||||||
span.card-estimation(
|
ng-style="{color: vm.item.getIn(['status', 'color'])}"
|
||||||
ng-if="vm.item.getIn(['model', 'total_points'])"
|
) {{ vm.item.getIn(['status', 'name']) }}
|
||||||
) {{"COMMON.FIELDS.POINTS" | translate}} {{vm.item.getIn(['model', 'total_points'])}}
|
span(ng-switch-when="false")
|
||||||
|
span.card-estimation.not-estimated(
|
||||||
|
ng-if="vm.item.getIn(['model', 'total_points']) === null && vm.visible('empty_extra_info')",
|
||||||
|
translate="US.NOT_ESTIMATED"
|
||||||
|
)
|
||||||
|
span.card-estimation(
|
||||||
|
ng-if="vm.item.getIn(['model', 'total_points'])"
|
||||||
|
) {{"COMMON.FIELDS.POINTS" | translate}} {{vm.item.getIn(['model', 'total_points'])}}
|
||||||
|
|
||||||
.card-statistics
|
.card-statistics
|
||||||
tg-due-date.statistic.card-due-date(
|
tg-due-date.statistic.card-due-date(
|
||||||
due-date="vm.item.getIn(['model', 'due_date'])"
|
due-date="vm.item.getIn(['model', 'due_date'])"
|
||||||
|
|
|
@ -46,7 +46,14 @@
|
||||||
title="{{ 'COMMON.CARD.EDIT' | translate }}"
|
title="{{ 'COMMON.CARD.EDIT' | translate }}"
|
||||||
)
|
)
|
||||||
tg-svg(svg-icon="icon-edit")
|
tg-svg(svg-icon="icon-edit")
|
||||||
|
a.e2e-edit.card-edit(
|
||||||
|
href=""
|
||||||
|
ng-if="vm.item.get('modelName') == 'issues'"
|
||||||
|
ng-click="!$event.ctrlKey && !$event.metaKey && vm.onClickRemove({id: vm.item.get('id')})"
|
||||||
|
tg-loading="vm.item.get('loading-remove-from-sprint')"
|
||||||
|
title="{{ 'COMMON.CARD.REMOVE_ISSUE_FROM_SPRINT' | translate }}"
|
||||||
|
)
|
||||||
|
tg-svg(svg-icon="icon-close")
|
||||||
a.e2e-edit.card-delete(
|
a.e2e-edit.card-delete(
|
||||||
href=""
|
href=""
|
||||||
ng-click="!$event.ctrlKey && !$event.metaKey && vm.onClickDelete({id: vm.item.get('id')})"
|
ng-click="!$event.ctrlKey && !$event.metaKey && vm.onClickDelete({id: vm.item.get('id')})"
|
||||||
|
|
|
@ -87,6 +87,8 @@ class CardController
|
||||||
getNavKey: () ->
|
getNavKey: () ->
|
||||||
if @.type == 'task'
|
if @.type == 'task'
|
||||||
return 'project-tasks-detail'
|
return 'project-tasks-detail'
|
||||||
|
else if @.type == 'issue'
|
||||||
|
return 'project-issues-detail'
|
||||||
else
|
else
|
||||||
return 'project-userstories-detail'
|
return 'project-userstories-detail'
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ cardDirective = () ->
|
||||||
onToggleFold: "&",
|
onToggleFold: "&",
|
||||||
onClickAssignedTo: "&",
|
onClickAssignedTo: "&",
|
||||||
onClickEdit: "&",
|
onClickEdit: "&",
|
||||||
|
onClickRemove: "&",
|
||||||
onClickDelete: "&",
|
onClickDelete: "&",
|
||||||
project: "=",
|
project: "=",
|
||||||
item: "=",
|
item: "=",
|
||||||
|
|
|
@ -125,7 +125,7 @@
|
||||||
.card-actions {
|
.card-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 .5rem;
|
padding: 0 0 0 .5rem;
|
||||||
}
|
}
|
||||||
.card-delete:hover {
|
.card-delete:hover {
|
||||||
color: $red-light;
|
color: $red-light;
|
||||||
|
@ -160,6 +160,12 @@
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 1rem .5rem;
|
padding: 0 1rem .5rem;
|
||||||
|
.card-status-tag {
|
||||||
|
font-size: .75rem;
|
||||||
|
height: .1rem;
|
||||||
|
line-height: .1rem;
|
||||||
|
padding: 0 .5em 0 0;
|
||||||
|
}
|
||||||
.card-estimation.not-estimated {
|
.card-estimation.not-estimated {
|
||||||
font-size: .8125rem;
|
font-size: .8125rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,24 +22,6 @@ module = angular.module("taigaComponents")
|
||||||
dueDatePopoverDirective = ($translate, datePickerConfigService) ->
|
dueDatePopoverDirective = ($translate, datePickerConfigService) ->
|
||||||
return {
|
return {
|
||||||
link: (scope, el, attrs, ctrl) ->
|
link: (scope, el, attrs, ctrl) ->
|
||||||
prettyDate = $translate.instant("COMMON.PICKERDATE.FORMAT")
|
|
||||||
if ctrl.dueDate
|
|
||||||
ctrl.dueDate = moment(ctrl.dueDate, prettyDate)
|
|
||||||
|
|
||||||
el.on "click", ".date-picker-popover-trigger", (event) ->
|
|
||||||
if ctrl.disabled()
|
|
||||||
return
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
el.find(".date-picker-popover").popover().open()
|
|
||||||
|
|
||||||
el.on "click", ".date-picker-clean", (event) ->
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
ctrl.dueDate = null
|
|
||||||
scope.$apply()
|
|
||||||
el.find(".date-picker-popover").popover().close()
|
|
||||||
|
|
||||||
datePickerConfig = datePickerConfigService.get()
|
datePickerConfig = datePickerConfigService.get()
|
||||||
_.merge(datePickerConfig, {
|
_.merge(datePickerConfig, {
|
||||||
field: el.find('input.due-date')[0]
|
field: el.find('input.due-date')[0]
|
||||||
|
@ -50,9 +32,28 @@ dueDatePopoverDirective = ($translate, datePickerConfigService) ->
|
||||||
el.find(".date-picker-popover").popover().close()
|
el.find(".date-picker-popover").popover().close()
|
||||||
scope.$apply()
|
scope.$apply()
|
||||||
})
|
})
|
||||||
|
|
||||||
el.picker = new Pikaday(datePickerConfig)
|
el.picker = new Pikaday(datePickerConfig)
|
||||||
|
|
||||||
|
el.on "click", ".date-picker-popover-trigger", (event) ->
|
||||||
|
if ctrl.disabled()
|
||||||
|
return
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
if !el.picker.getDate()
|
||||||
|
el.picker.setDate(moment(ctrl.dueDate).format('YYYY-MM-DD'))
|
||||||
|
el.find(".date-picker-popover").popover().open()
|
||||||
|
|
||||||
|
el.on "click", ".date-picker-clean", (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
ctrl.dueDate = null
|
||||||
|
el.picker.setDate(ctrl.dueDate)
|
||||||
|
el.find(".date-picker-popover").popover().close()
|
||||||
|
scope.$apply()
|
||||||
|
|
||||||
|
scope.$on "status:changed", (ctx, status) ->
|
||||||
|
ctrl.isClosed = ctrl.item.is_closed
|
||||||
|
|
||||||
controller: "DueDateCtrl",
|
controller: "DueDateCtrl",
|
||||||
controllerAs: "vm",
|
controllerAs: "vm",
|
||||||
bindToController: true,
|
bindToController: true,
|
||||||
|
|
|
@ -1,40 +1,32 @@
|
||||||
extends lb-create-edit
|
section.ticket-assigned-to(
|
||||||
|
tg-assigned-to-inline
|
||||||
block options
|
ng-model="obj"
|
||||||
section.ticket-assigned-to(
|
required-perm="modify_{{ objType }}"
|
||||||
tg-assigned-to-inline
|
)
|
||||||
|
div.ticket-data-container
|
||||||
|
tg-issue-type-button.ticket-status(
|
||||||
|
not-auto-save="true"
|
||||||
ng-model="obj"
|
ng-model="obj"
|
||||||
required-perm="modify_{{ objType }}"
|
|
||||||
)
|
)
|
||||||
div.ticket-data-container
|
tg-issue-severity-button.ticket-status(
|
||||||
tg-issue-type-button.ticket-status(
|
not-auto-save="true"
|
||||||
not-auto-save="true"
|
ng-model="obj"
|
||||||
ng-model="obj"
|
|
||||||
)
|
|
||||||
tg-issue-severity-button.ticket-status(
|
|
||||||
not-auto-save="true"
|
|
||||||
ng-model="obj"
|
|
||||||
)
|
|
||||||
tg-issue-priority-button.ticket-status(
|
|
||||||
not-auto-save="true"
|
|
||||||
ng-model="obj"
|
|
||||||
)
|
|
||||||
|
|
||||||
div.ticket-detail-settings
|
|
||||||
tg-due-date-popover(
|
|
||||||
due-date="obj.due_date"
|
|
||||||
is-closed="obj.is_closed"
|
|
||||||
item="obj"
|
|
||||||
not-auto-save="true"
|
|
||||||
)
|
|
||||||
div
|
|
||||||
label.button-gray.is-blocked(
|
|
||||||
title="{{ 'COMMON.BLOCK_TITLE' | translate }}"
|
|
||||||
ng-class="{ 'button-red item-unblock': obj.is_blocked, 'item-block': !obj.is_blocked }"
|
|
||||||
)
|
|
||||||
tg-svg(svg-icon="icon-lock")
|
|
||||||
|
|
||||||
tg-blocking-message-input(
|
|
||||||
watch="obj.is_blocked"
|
|
||||||
ng-model="obj.blocked_note"
|
|
||||||
)
|
)
|
||||||
|
tg-issue-priority-button.ticket-status(
|
||||||
|
not-auto-save="true"
|
||||||
|
ng-model="obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
div.ticket-detail-settings
|
||||||
|
tg-due-date-popover(
|
||||||
|
due-date="obj.due_date"
|
||||||
|
is-closed="obj.is_closed"
|
||||||
|
item="obj"
|
||||||
|
not-auto-save="true"
|
||||||
|
)
|
||||||
|
div
|
||||||
|
label.button-gray.is-blocked(
|
||||||
|
title="{{ 'COMMON.BLOCK_TITLE' | translate }}"
|
||||||
|
ng-class="{ 'button-red item-unblock': obj.is_blocked, 'item-block': !obj.is_blocked }"
|
||||||
|
)
|
||||||
|
tg-svg(svg-icon="icon-lock")
|
||||||
|
|
|
@ -1,40 +1,32 @@
|
||||||
extends lb-create-edit
|
section.ticket-assigned-to(
|
||||||
|
tg-assigned-to-inline
|
||||||
block options
|
ng-model="obj"
|
||||||
section.ticket-assigned-to(
|
required-perm="modify_{{ objType }}"
|
||||||
tg-assigned-to-inline
|
)
|
||||||
ng-model="obj"
|
div.ticket-detail-settings
|
||||||
required-perm="modify_{{ objType }}"
|
tg-due-date-popover(
|
||||||
|
due-date="obj.due_date"
|
||||||
|
is-closed="obj.is_closed"
|
||||||
|
item="obj"
|
||||||
|
not-auto-save="true"
|
||||||
)
|
)
|
||||||
div.ticket-detail-settings
|
div
|
||||||
tg-due-date-popover(
|
fieldset.iocaine-flag(title="{{ 'TASK.TITLE_ACTION_IOCAINE' | translate }}")
|
||||||
due-date="obj.due_date"
|
label.button-gray.iocaine(
|
||||||
is-closed="obj.is_closed"
|
for="is-iocaine"
|
||||||
item="obj"
|
ng-class="{'active': obj.is_iocaine}"
|
||||||
not-auto-save="true"
|
|
||||||
)
|
|
||||||
div
|
|
||||||
fieldset.iocaine-flag(title="{{ 'TASK.TITLE_ACTION_IOCAINE' | translate }}")
|
|
||||||
label.button-gray.iocaine(
|
|
||||||
for="is-iocaine"
|
|
||||||
ng-class="{'active': obj.is_iocaine}"
|
|
||||||
)
|
|
||||||
tg-svg(svg-icon="icon-iocaine")
|
|
||||||
input(
|
|
||||||
type="checkbox"
|
|
||||||
id="is-iocaine"
|
|
||||||
name="is-iocaine"
|
|
||||||
ng-model="obj.is_iocaine"
|
|
||||||
ng-value="true"
|
|
||||||
)
|
|
||||||
div
|
|
||||||
label.button-gray.is-blocked(
|
|
||||||
title="{{ 'COMMON.BLOCK_TITLE' | translate }}"
|
|
||||||
ng-class="{ 'button-red item-unblock': obj.is_blocked, 'item-block': !obj.is_blocked }"
|
|
||||||
)
|
)
|
||||||
tg-svg(svg-icon="icon-lock")
|
tg-svg(svg-icon="icon-iocaine")
|
||||||
|
input(
|
||||||
tg-blocking-message-input(
|
type="checkbox"
|
||||||
watch="obj.is_blocked"
|
id="is-iocaine"
|
||||||
ng-model="obj.blocked_note"
|
name="is-iocaine"
|
||||||
)
|
ng-model="obj.is_iocaine"
|
||||||
|
ng-value="true"
|
||||||
|
)
|
||||||
|
div
|
||||||
|
label.button-gray.is-blocked(
|
||||||
|
title="{{ 'COMMON.BLOCK_TITLE' | translate }}"
|
||||||
|
ng-class="{ 'button-red item-unblock': obj.is_blocked, 'item-block': !obj.is_blocked }"
|
||||||
|
)
|
||||||
|
tg-svg(svg-icon="icon-lock")
|
||||||
|
|
|
@ -1,44 +1,36 @@
|
||||||
extends lb-create-edit
|
section.ticket-assigned-to.multiple-assign(
|
||||||
|
tg-assigned-users-inline
|
||||||
|
ng-model="obj"
|
||||||
|
required-perm="modify_{{ objType }}"
|
||||||
|
)
|
||||||
|
div.ticket-estimation
|
||||||
|
tg-lb-us-estimation(ng-model="obj")
|
||||||
|
|
||||||
block options
|
div.ticket-detail-settings
|
||||||
section.ticket-assigned-to.multiple-assign(
|
tg-due-date-popover(
|
||||||
tg-assigned-users-inline
|
due-date="obj.due_date"
|
||||||
ng-model="obj"
|
is-closed="obj.is_closed"
|
||||||
required-perm="modify_{{ objType }}"
|
item="obj"
|
||||||
|
not-auto-save="true"
|
||||||
)
|
)
|
||||||
div.ticket-estimation
|
div
|
||||||
tg-lb-us-estimation(ng-model="obj")
|
label.button-gray.team-requirement(
|
||||||
|
for="team-requirement"
|
||||||
div.ticket-detail-settings
|
title="{{ 'COMMON.TEAM_REQUIREMENT' | translate }}"
|
||||||
tg-due-date-popover(
|
ng-class="{ 'active': isTeamRequirement() }"
|
||||||
due-date="obj.due_date"
|
|
||||||
is-closed="obj.is_closed"
|
|
||||||
item="obj"
|
|
||||||
not-auto-save="true"
|
|
||||||
)
|
)
|
||||||
div
|
tg-svg(svg-icon="icon-team-requirement")
|
||||||
label.button-gray.team-requirement(
|
div
|
||||||
for="team-requirement"
|
label.button-gray.client-requirement(
|
||||||
title="{{ 'COMMON.TEAM_REQUIREMENT' | translate }}"
|
for="client-requirement"
|
||||||
ng-class="{ 'active': isTeamRequirement() }"
|
title="{{ 'COMMON.CLIENT_REQUIREMENT' | translate }}"
|
||||||
)
|
ng-class="{ 'active': isClientRequirement() }"
|
||||||
tg-svg(svg-icon="icon-team-requirement")
|
)
|
||||||
div
|
tg-svg(svg-icon="icon-client-requirement")
|
||||||
label.button-gray.client-requirement(
|
|
||||||
for="client-requirement"
|
|
||||||
title="{{ 'COMMON.CLIENT_REQUIREMENT' | translate }}"
|
|
||||||
ng-class="{ 'active': isClientRequirement() }"
|
|
||||||
)
|
|
||||||
tg-svg(svg-icon="icon-client-requirement")
|
|
||||||
|
|
||||||
div
|
div
|
||||||
label.button-gray.is-blocked(
|
label.button-gray.is-blocked(
|
||||||
title="{{ 'COMMON.BLOCK_TITLE' | translate }}"
|
title="{{ 'COMMON.BLOCK_TITLE' | translate }}"
|
||||||
ng-class="{ 'button-red item-unblock': obj.is_blocked, 'item-block': !obj.is_blocked }"
|
ng-class="{ 'button-red item-unblock': obj.is_blocked, 'item-block': !obj.is_blocked }"
|
||||||
)
|
)
|
||||||
tg-svg(svg-icon="icon-lock")
|
tg-svg(svg-icon="icon-lock")
|
||||||
|
|
||||||
tg-blocking-message-input(
|
|
||||||
watch="obj.is_blocked"
|
|
||||||
ng-model="obj.blocked_note"
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,62 +1,139 @@
|
||||||
tg-lightbox-close
|
tg-lightbox-close
|
||||||
|
|
||||||
form
|
form(ng-if="lightboxOpen")
|
||||||
h2.title {{ text.title }}
|
h2.title(ng-switch="mode")
|
||||||
div.form-wrapper
|
span(ng-switch-when="new") {{ 'LIGHTBOX.CREATE_EDIT.NEW' | translate: { objName: objName } }}
|
||||||
main
|
span(ng-switch-when="edit") {{ 'LIGHTBOX.CREATE_EDIT.EDIT' | translate: { objName: objName } }}
|
||||||
fieldset
|
span(ng-switch-when="add-existing") {{ 'LIGHTBOX.CREATE_EDIT.ADD_EXISTING' | translate: { objName: objName, targetName: existingOptions.title } }}
|
||||||
input(
|
|
||||||
type="text"
|
.existing-or-new-selector(ng-show="getOrCreate == true")
|
||||||
name="subject"
|
.existing-or-new-selector-single
|
||||||
ng-model-options="{ debounce: 200 }"
|
input(
|
||||||
ng-model="obj.subject"
|
type="radio"
|
||||||
placeholder="{{'COMMON.FIELDS.SUBJECT' | translate}}"
|
name="related-with-selector"
|
||||||
|
id="add-existing"
|
||||||
|
value="add-existing"
|
||||||
|
ng-model="mode"
|
||||||
|
)
|
||||||
|
label.e2e-existing-user-story-label(for="add-existing")
|
||||||
|
span.name {{ 'LIGHTBOX.CREATE_EDIT.EXISTING_OBJECT' | translate: { objName: objName } }}
|
||||||
|
|
||||||
|
.existing-or-new-selector-single
|
||||||
|
input(
|
||||||
|
type="radio"
|
||||||
|
name="related-with-selector"
|
||||||
|
id="new"
|
||||||
|
value="new"
|
||||||
|
ng-model="mode"
|
||||||
|
)
|
||||||
|
label.e2e-new-userstory-label(for="new")
|
||||||
|
span.name {{ 'LIGHTBOX.CREATE_EDIT.NEW_OBJECT' | translate: { objName: objName } }}
|
||||||
|
|
||||||
|
div(ng-if="mode == 'add-existing'")
|
||||||
|
.existing-item-wrapper
|
||||||
|
label(for="existing-filter") {{ 'LIGHTBOX.CREATE_EDIT.CHOOSE_EXISTING' | translate: { objName: objName } }}
|
||||||
|
input.filter(
|
||||||
|
id="existing-filter"
|
||||||
|
name="existing-filter"
|
||||||
|
type="text"
|
||||||
|
ng-model="existingFilterText"
|
||||||
|
ng-model-options="{ debounce: 200 }"
|
||||||
|
ng-change="existingFilterChanged(existingFilterText)"
|
||||||
|
)
|
||||||
|
|
||||||
|
.existing-item(ng-show="existingItems")
|
||||||
|
select.userstory.e2e-userstories-select(
|
||||||
|
size="5"
|
||||||
|
ng-model="selectedItem"
|
||||||
data-required="true"
|
data-required="true"
|
||||||
data-maxlength="500"
|
)
|
||||||
|
- var hash = "#";
|
||||||
|
option.hidden(value="")
|
||||||
|
option(
|
||||||
|
ng-repeat="(ref, obj) in existingItems"
|
||||||
|
ng-class="obj.class"
|
||||||
|
value="{{ ::ref }}"
|
||||||
|
) #{hash}{{ ref }} {{ obj.html }}
|
||||||
|
|
||||||
|
p.no-stories-found(
|
||||||
|
ng-show="existingFilterText && !existingItems"
|
||||||
|
translate="EPIC.NO_USERSTORIES_FOUND"
|
||||||
|
) {{ 'LIGHTBOX.CREATE_EDIT.NO_ITEMS_FOUND' | translate }}
|
||||||
|
|
||||||
|
button.button-green.add-existing-button(
|
||||||
|
ng-click="addExisting(selectedItem)"
|
||||||
|
ng-disabled="!selectedItem"
|
||||||
|
) {{ 'COMMON.ADD' | translate }} {{ objName }}
|
||||||
|
|
||||||
|
div(ng-if="mode != 'add-existing'")
|
||||||
|
.form-wrapper
|
||||||
|
main
|
||||||
|
fieldset
|
||||||
|
input(
|
||||||
|
type="text"
|
||||||
|
name="subject"
|
||||||
|
ng-model-options="{ debounce: 200 }"
|
||||||
|
ng-model="obj.subject"
|
||||||
|
placeholder="{{ 'COMMON.FIELDS.SUBJECT' | translate }}"
|
||||||
|
data-required="true"
|
||||||
|
data-maxlength="500"
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldset
|
||||||
|
tg-tag-line-common.tags-block(
|
||||||
|
ng-if="project"
|
||||||
|
project="project"
|
||||||
|
tags="obj.tags"
|
||||||
|
permissions="add_{{objType}}"
|
||||||
|
on-add-tag="addTag(name, color)"
|
||||||
|
on-delete-tag="deleteTag(tag)"
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldset
|
||||||
|
textarea.description(
|
||||||
|
rows=7
|
||||||
|
name="description"
|
||||||
|
ng-model="obj.description"
|
||||||
|
ng-model-options="{ debounce: 200 }"
|
||||||
|
ng-attr-placeholder="{{ 'LIGHTBOX.CREATE_EDIT.PLACEHOLDER_DESCRIPTION' | translate }}"
|
||||||
|
)
|
||||||
|
fieldset
|
||||||
|
section
|
||||||
|
tg-attachments-simple(
|
||||||
|
attachments="attachments",
|
||||||
|
on-add="addAttachment(attachment)"
|
||||||
|
on-delete="deleteAttachment(attachment)"
|
||||||
|
)
|
||||||
|
|
||||||
|
sidebar.sidebar.ticket-data
|
||||||
|
fieldset.status-button
|
||||||
|
div.status-dropdown.editable(style="background-color:{{ selectedStatus.color }}")
|
||||||
|
span.status-text {{ selectedStatus.name }}
|
||||||
|
tg-svg(svg-icon="icon-arrow-down")
|
||||||
|
|
||||||
|
ul.pop-status.popover
|
||||||
|
li(ng-repeat="s in statusList")
|
||||||
|
a.status(
|
||||||
|
href=""
|
||||||
|
title="{{ s.name }}"
|
||||||
|
data-status-id="{{ s.id }}"
|
||||||
|
) {{ s.name }}
|
||||||
|
|
||||||
|
div(ng-switch="objType")
|
||||||
|
div(ng-switch-when="issue")
|
||||||
|
include lb-create-edit-issue
|
||||||
|
div(ng-switch-when="task")
|
||||||
|
include lb-create-edit-task
|
||||||
|
div(ng-switch-when="us")
|
||||||
|
include lb-create-edit-us
|
||||||
|
|
||||||
|
tg-blocking-message-input(
|
||||||
|
watch="obj.is_blocked"
|
||||||
|
ng-model="obj.blocked_note"
|
||||||
)
|
)
|
||||||
|
|
||||||
fieldset
|
button.button-green.submit-button(type="submit", ng-switch="mode")
|
||||||
tg-tag-line-common.tags-block(
|
span(ng-switch-when="new") {{ 'COMMON.CREATE' | translate }}
|
||||||
ng-if="project && createEditOpen"
|
span(ng-switch-when="edit") {{ 'COMMON.SAVE' | translate }}
|
||||||
project="project"
|
|
||||||
tags="obj.tags"
|
|
||||||
permissions="add_{{objType}}"
|
|
||||||
on-add-tag="addTag(name, color)"
|
|
||||||
on-delete-tag="deleteTag(tag)"
|
|
||||||
)
|
|
||||||
|
|
||||||
fieldset
|
|
||||||
textarea.description(
|
|
||||||
rows=7
|
|
||||||
name="description"
|
|
||||||
ng-model="obj.description"
|
|
||||||
ng-model-options="{ debounce: 200 }"
|
|
||||||
ng-attr-placeholder="{{'LIGHTBOX.CREATE_EDIT.PLACEHOLDER_DESCRIPTION' | translate}}"
|
|
||||||
)
|
|
||||||
fieldset
|
|
||||||
section
|
|
||||||
tg-attachments-simple(
|
|
||||||
attachments="attachments",
|
|
||||||
on-add="addAttachment(attachment)"
|
|
||||||
on-delete="deleteAttachment(attachment)"
|
|
||||||
)
|
|
||||||
|
|
||||||
sidebar.sidebar.ticket-data
|
|
||||||
fieldset.status-button
|
|
||||||
div.status-dropdown.editable(style="background-color:{{ selectedStatus.color }}")
|
|
||||||
span.status-text {{ selectedStatus.name }}
|
|
||||||
tg-svg(svg-icon="icon-arrow-down")
|
|
||||||
|
|
||||||
ul.pop-status.popover
|
|
||||||
li(ng-repeat="s in statusList")
|
|
||||||
a.status(
|
|
||||||
href=""
|
|
||||||
title="{{ s.name }}"
|
|
||||||
data-status-id="{{ s.id }}"
|
|
||||||
) {{ s.name }}
|
|
||||||
|
|
||||||
block options
|
|
||||||
|
|
||||||
button.button-green.submit-button(type="submit") {{ text.action }}
|
|
||||||
|
|
||||||
div.lightbox.lightbox-select-user(tg-lb-assignedto)
|
div.lightbox.lightbox-select-user(tg-lb-assignedto)
|
|
@ -83,7 +83,7 @@ div.taskboard-table(
|
||||||
ng-class="{'kanban-task-maximized': ctrl.isMaximized(s.id), 'kanban-task-minimized': ctrl.isMinimized(s.id)}"
|
ng-class="{'kanban-task-maximized': ctrl.isMaximized(s.id), 'kanban-task-minimized': ctrl.isMinimized(s.id)}"
|
||||||
tg-class-permission="{'readonly': '!modify_task'}"
|
tg-class-permission="{'readonly': '!modify_task'}"
|
||||||
tg-bind-scope,
|
tg-bind-scope,
|
||||||
on-toggle-fold="ctrl.toggleFold(id)"
|
on-toggle-fold="ctrl.toggleFold(id, 'tasks')"
|
||||||
on-click-edit="ctrl.editTask(id)"
|
on-click-edit="ctrl.editTask(id)"
|
||||||
on-click-delete="ctrl.deleteTask(id)"
|
on-click-delete="ctrl.deleteTask(id)"
|
||||||
on-click-assigned-to="ctrl.changeTaskAssignedTo(id)"
|
on-click-assigned-to="ctrl.changeTaskAssignedTo(id)"
|
||||||
|
@ -129,7 +129,7 @@ div.taskboard-table(
|
||||||
tg-repeat="task in usTasks.getIn(['null', st.id.toString()]) track by task.get('id')"
|
tg-repeat="task in usTasks.getIn(['null', st.id.toString()]) track by task.get('id')"
|
||||||
ng-class="{'kanban-task-maximized': ctrl.isMaximized(s.id), 'kanban-task-minimized': ctrl.isMinimized(s.id)}"
|
ng-class="{'kanban-task-maximized': ctrl.isMaximized(s.id), 'kanban-task-minimized': ctrl.isMinimized(s.id)}"
|
||||||
tg-class-permission="{'readonly': '!modify_task'}"
|
tg-class-permission="{'readonly': '!modify_task'}"
|
||||||
on-toggle-fold="ctrl.toggleFold(id)"
|
on-toggle-fold="ctrl.toggleFold(id, 'tasks')"
|
||||||
on-click-edit="ctrl.editTask(id)"
|
on-click-edit="ctrl.editTask(id)"
|
||||||
on-click-delete="ctrl.deleteTask(id)"
|
on-click-delete="ctrl.deleteTask(id)"
|
||||||
on-click-assigned-to="ctrl.changeTaskAssignedTo(id)"
|
on-click-assigned-to="ctrl.changeTaskAssignedTo(id)"
|
||||||
|
@ -141,22 +141,23 @@ div.taskboard-table(
|
||||||
)
|
)
|
||||||
div.taskboard-row.issues-row(ng-class="{'row-fold':usFolded[0]}")
|
div.taskboard-row.issues-row(ng-class="{'row-fold':usFolded[0]}")
|
||||||
div.taskboard-row-title-box.taskboard-column
|
div.taskboard-row-title-box.taskboard-column
|
||||||
a.vfold(
|
div.task-colum-name
|
||||||
href=""
|
a.toggle-fold.vfold(
|
||||||
title="{{'TASKBOARD.TABLE.TITLE_ACTION_FOLD_ROW' | translate}}"
|
href=""
|
||||||
ng-click='foldUs(0)'
|
title="{{'TASKBOARD.TABLE.TITLE_ACTION_FOLD_ROW' | translate}}"
|
||||||
ng-class="{hidden:usFolded[0]}"
|
ng-click='foldUs(0)'
|
||||||
)
|
ng-class="{hidden:usFolded[0]}"
|
||||||
tg-svg.fold-action(svg-icon="icon-fold-row")
|
)
|
||||||
a.vunfold(
|
tg-svg.fold-action(svg-icon="icon-fold-row")
|
||||||
href=""
|
a.toggle-fold.vunfold(
|
||||||
title="{{'TASKBOARD.TABLE.TITLE_ACTION_UNFOLD_ROW' | translate}}"
|
href=""
|
||||||
ng-click='foldUs(0)'
|
title="{{'TASKBOARD.TABLE.TITLE_ACTION_UNFOLD_ROW' | translate}}"
|
||||||
ng-class="{hidden:!usFolded[0]}"
|
ng-click='foldUs(0)'
|
||||||
)
|
ng-class="{hidden:!usFolded[0]}"
|
||||||
tg-svg.fold-action(svg-icon="icon-unfold-row")
|
)
|
||||||
h3.task-colum-name(translate="TASKBOARD.TABLE.ROW_ISSUES_TITLE")
|
tg-svg.fold-action(svg-icon="icon-unfold-row")
|
||||||
include ../components/addnewissue.jade
|
span.row-title(translate="TASKBOARD.TABLE.ROW_ISSUES_TITLE")
|
||||||
|
include ../components/addnewissue.jade
|
||||||
|
|
||||||
div.taskboard-cards-box
|
div.taskboard-cards-box
|
||||||
tg-card.card.ng-animate-disabled(
|
tg-card.card.ng-animate-disabled(
|
||||||
|
@ -164,8 +165,9 @@ div.taskboard-table(
|
||||||
class="kanban-task-minimized"
|
class="kanban-task-minimized"
|
||||||
tg-class-permission="{'readonly': '!modify_issue'}"
|
tg-class-permission="{'readonly': '!modify_issue'}"
|
||||||
tg-bind-scope,
|
tg-bind-scope,
|
||||||
on-toggle-fold="ctrl.toggleFold(id)"
|
on-toggle-fold="ctrl.toggleFold(id, 'issues')"
|
||||||
on-click-edit="ctrl.editIssue(id)"
|
on-click-edit="ctrl.editIssue(id)"
|
||||||
|
on-click-remove="ctrl.removeIssueFromSprint(id)"
|
||||||
on-click-delete="ctrl.deleteIssue(id)"
|
on-click-delete="ctrl.deleteIssue(id)"
|
||||||
on-click-assigned-to="ctrl.changeIssueAssignedTo(id)"
|
on-click-assigned-to="ctrl.changeIssueAssignedTo(id)"
|
||||||
project="project"
|
project="project"
|
||||||
|
|
|
@ -54,20 +54,7 @@ $column-padding: .5rem 1rem;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.taskboard-table-header {
|
|
||||||
flex-basis: 2.4rem;
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
min-height: 2.4rem;
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
.taskboard-table-inner {
|
|
||||||
display: flex;
|
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.task-colum-name {
|
.task-colum-name {
|
||||||
@include font-size(medium);
|
@include font-size(medium);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -104,6 +91,20 @@ $column-padding: .5rem 1rem;
|
||||||
@include ellipsis(65%);
|
@include ellipsis(65%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.taskboard-table-header {
|
||||||
|
flex-basis: 2.4rem;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
min-height: 2.4rem;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
.taskboard-table-inner {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
tg-svg {
|
tg-svg {
|
||||||
display: block;
|
display: block;
|
||||||
margin-right: .3rem;
|
margin-right: .3rem;
|
||||||
|
@ -184,6 +185,22 @@ $column-padding: .5rem 1rem;
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.taskboard-row-title-box {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.task-colum-name {
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding: .5rem .5rem .5rem 2em;
|
||||||
|
}
|
||||||
|
.row-title {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.toggle-fold {
|
||||||
|
display: block;
|
||||||
|
left: .5rem;
|
||||||
|
position: absolute;
|
||||||
|
top: -.4rem;
|
||||||
|
}
|
||||||
.card {
|
.card {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
|
@ -21,23 +21,40 @@
|
||||||
min-height: 4.5rem;
|
min-height: 4.5rem;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
label {
|
|
||||||
@include font-size(xsmall);
|
.existing-or-new-selector {
|
||||||
background: $mass-white;
|
display: flex;
|
||||||
border: 1px solid $gray-light;
|
margin-bottom: 2rem;
|
||||||
color: $grayer;
|
input {
|
||||||
cursor: pointer;
|
display: none;
|
||||||
display: block;
|
&:checked+label {
|
||||||
padding: 7px 30px;
|
background: $primary-light;
|
||||||
transition: all .2s ease-in;
|
|
||||||
&:hover {
|
|
||||||
span {
|
|
||||||
color: $white;
|
color: $white;
|
||||||
|
transition: background .2s ease-in;
|
||||||
|
}
|
||||||
|
&:checked+label:hover {
|
||||||
|
background: $primary-light;
|
||||||
|
}
|
||||||
|
+label {
|
||||||
|
background: rgba($whitish, .7);
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: background .2s ease-in;
|
||||||
|
}
|
||||||
|
+label:hover {
|
||||||
|
background: rgba($primary-light, .3);
|
||||||
|
transition: background .2s ease-in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span {
|
.existing-or-new-selector-single {
|
||||||
color: $grayer;
|
flex: 1;
|
||||||
vertical-align: middle;
|
&:first-child {
|
||||||
|
margin-right: .5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,14 +639,25 @@
|
||||||
margin-bottom: $spacing * 2;
|
margin-bottom: $spacing * 2;
|
||||||
main {
|
main {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin-right: $spacing;
|
max-width: $width - $sidebar-width;
|
||||||
}
|
}
|
||||||
.sidebar {
|
.sidebar {
|
||||||
border-left: 2px solid $whitish;
|
border-left: 2px solid $whitish;
|
||||||
|
margin-left: $spacing;
|
||||||
padding-left: $spacing;
|
padding-left: $spacing;
|
||||||
|
$min-width: $sidebar-width;
|
||||||
width: $sidebar-width;
|
width: $sidebar-width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.existing-item-wrapper {
|
||||||
|
margin-bottom: $spacing * 2;
|
||||||
|
select .strong {
|
||||||
|
@include font-type(bold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.add-existing-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.status-button {
|
.status-button {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
Loading…
Reference in New Issue