commit
102bdc1e80
|
@ -5,8 +5,9 @@
|
|||
### Features
|
||||
- Contact with the project: if the projects have this module enabled Taiga users can contact them.
|
||||
- Velocity forecasting. Create sprints according to team velocity.
|
||||
- Remove bower
|
||||
- Remove bower, now use only npm packages.
|
||||
- Add new wysiwyg editor (like the Medunm editor) with emojis, local storage changes, mentions...
|
||||
- Add rich text custom fields (with a wysiwyg editor like descreption or comments).
|
||||
|
||||
### Misc
|
||||
- Lots of small and not so small bugfixes.
|
||||
|
|
|
@ -406,6 +406,7 @@ module.directive("tgColorSelection", ColorSelectionDirective)
|
|||
# Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py)
|
||||
TEXT_TYPE = "text"
|
||||
MULTILINE_TYPE = "multiline"
|
||||
RICHTEXT_TYPE = "richtext"
|
||||
DATE_TYPE = "date"
|
||||
URL_TYPE = "url"
|
||||
|
||||
|
@ -419,6 +420,10 @@ TYPE_CHOICES = [
|
|||
key: MULTILINE_TYPE,
|
||||
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI"
|
||||
},
|
||||
{
|
||||
key: RICHTEXT_TYPE,
|
||||
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_RICHTEXT"
|
||||
},
|
||||
{
|
||||
key: DATE_TYPE,
|
||||
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE"
|
||||
|
|
|
@ -32,6 +32,7 @@ module = angular.module("taigaCommon")
|
|||
|
||||
# Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py)
|
||||
TEXT_TYPE = "text"
|
||||
RICHTEXT_TYPE = "url"
|
||||
MULTILINE_TYPE = "multiline"
|
||||
DATE_TYPE = "date"
|
||||
URL_TYPE = "url"
|
||||
|
@ -53,6 +54,10 @@ TYPE_CHOICES = [
|
|||
{
|
||||
key: URL_TYPE,
|
||||
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_URL"
|
||||
},
|
||||
{
|
||||
key: RICHTEXT_TYPE,
|
||||
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_RICHTEXT"
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -193,6 +198,15 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
|
|||
requiredEditionPerm = $attrs.requiredEditionPerm
|
||||
return permissions.indexOf(requiredEditionPerm) > -1
|
||||
|
||||
$scope.saveCustomRichText = (markdown, callback) =>
|
||||
attributeValue.value = markdown
|
||||
$ctrl.updateAttributeValue(attributeValue).then ->
|
||||
callback()
|
||||
render(attributeValue, false)
|
||||
|
||||
$scope.cancelCustomRichText= () =>
|
||||
render(attributeValue, false)
|
||||
|
||||
submit = debounce 2000, (event) =>
|
||||
event.preventDefault()
|
||||
|
||||
|
@ -214,6 +228,9 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
|
|||
|
||||
# Bootstrap
|
||||
attributeValue = $scope.$eval($attrs.tgCustomAttributeValue)
|
||||
if attributeValue.value == null or attributeValue.value == undefined
|
||||
attributeValue.value = ""
|
||||
$scope.customAttributeValue = attributeValue
|
||||
render(attributeValue)
|
||||
|
||||
## Actions (on view mode)
|
||||
|
|
|
@ -573,6 +573,7 @@
|
|||
"ISSUE_DESCRIPTION": "Issues custom fields",
|
||||
"ISSUE_ADD": "Add a custom field in issues",
|
||||
"FIELD_TYPE_TEXT": "Text",
|
||||
"FIELD_TYPE_RICHTEXT": "Rich text",
|
||||
"FIELD_TYPE_MULTI": "Multi-line",
|
||||
"FIELD_TYPE_DATE": "Date",
|
||||
"FIELD_TYPE_URL": "Url"
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
###
|
||||
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
|
||||
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# File: modules/components/wysiwyg/comment-edit-wysiwyg.directive.coffee
|
||||
###
|
||||
|
||||
CustomFieldEditWysiwyg = (attachmentsFullService) ->
|
||||
link = ($scope, $el, $attrs) ->
|
||||
types = {
|
||||
userstories: "us",
|
||||
issues: "issue",
|
||||
tasks: "task"
|
||||
}
|
||||
|
||||
uploadFile = (file, cb) ->
|
||||
return attachmentsFullService.addAttachment($scope.vm.projectId, $scope.vm.comment.comment.id, types[$scope.vm.comment.comment._name], file).then (result) ->
|
||||
cb(result.getIn(['file', 'name']), result.getIn(['file', 'url']))
|
||||
|
||||
$scope.uploadFiles = (files, cb) ->
|
||||
for file in files
|
||||
uploadFile(file, cb)
|
||||
|
||||
return {
|
||||
scope: true,
|
||||
link: link,
|
||||
template: """
|
||||
<div>
|
||||
<tg-wysiwyg
|
||||
editonly
|
||||
content='customAttributeValue.value'
|
||||
on-save="saveCustomRichText(text, cb)"
|
||||
on-cancel="cancelCustomRichText()"
|
||||
on-upload-file='uploadFiles(files, cb)'>
|
||||
</tg-wysiwyg>
|
||||
</div>
|
||||
"""
|
||||
}
|
||||
|
||||
angular.module("taigaComponents")
|
||||
.directive("tgCustomFieldEditWysiwyg", ["tgAttachmentsFullService", CustomFieldEditWysiwyg])
|
|
@ -1,19 +1,29 @@
|
|||
.diff-custom-new(
|
||||
.diff-status-wrapper(
|
||||
ng-if="vm.diff.new.length"
|
||||
ng-repeat="newCustom in vm.diff.new"
|
||||
)
|
||||
span.key(translate="ACTIVITY.CREATED_CUSTOM_ATTRIBUTE")
|
||||
span.diff ({{newCustom.name}})
|
||||
span.diff {{newCustom.value}}
|
||||
|
||||
.diff-custom-new(
|
||||
|
||||
span(ng-if="newCustom.type == 'richtext'")
|
||||
p.diff(tg-bo-html="newCustom.value_diff")
|
||||
|
||||
span(ng-if="newCustom.type != 'richtext'")
|
||||
span.diff {{newCustom.value}}
|
||||
|
||||
.diff-status-wrapper(
|
||||
ng-if="vm.diff.changed.length"
|
||||
ng-repeat="changeCustom in vm.diff.changed"
|
||||
)
|
||||
span.key(translate="ACTIVITY.UPDATED_CUSTOM_ATTRIBUTE")
|
||||
span.diff ({{changeCustom.name}})
|
||||
span.diff {{changeCustom.changes.value[0]}}
|
||||
tg-svg(
|
||||
svg-icon="icon-arrow-right"
|
||||
)
|
||||
span.diff {{changeCustom.changes.value[1]}}
|
||||
|
||||
span(ng-if="changeCustom.type == 'richtext'")
|
||||
p.diff(tg-bo-html="changeCustom.value_diff")
|
||||
|
||||
span(ng-if="changeCustom.type != 'richtext'")
|
||||
span.diff {{changeCustom.changes.value[0]}}
|
||||
tg-svg(
|
||||
svg-icon="icon-arrow-right"
|
||||
)
|
||||
span.diff {{changeCustom.changes.value[1]}}
|
||||
|
|
|
@ -13,6 +13,8 @@ form.custom-field-single.editable
|
|||
input#custom-field-value(name="value", type="text", value!="<%- value %>")
|
||||
<% } else if (type=="multiline") { %>
|
||||
textarea#custom-field-value(name="value") <%- value %>
|
||||
<% } else if (type=="richtext") { %>
|
||||
tg-custom-field-edit-wysiwyg()
|
||||
<% } else if (type=="date") { %>
|
||||
input#custom-field-value(name="value", type="text", data-pikaday, value!="<%- value %>")
|
||||
<% } else if (type=="url") { %>
|
||||
|
@ -21,6 +23,8 @@ form.custom-field-single.editable
|
|||
input#custom-field-value(name="value", type="text", value!="<%- value %>")
|
||||
<% } %>
|
||||
|
||||
<% if (type != "richtext") { %>
|
||||
div.custom-field-options
|
||||
a.js-save-description(href="", title="{{'COMMON.CUSTOM_ATTRIBUTES.SAVE' | translate}}")
|
||||
tg-svg(svg-icon="icon-save")
|
||||
<% } %>
|
||||
|
|
|
@ -7,14 +7,19 @@
|
|||
<%- description %>
|
||||
<% } %>
|
||||
|
||||
<% if (type=="url") { %>
|
||||
.custom-field-value.js-value-view-mode
|
||||
span
|
||||
<% if (type=="url") { %>
|
||||
a(href!="<%- value %>")
|
||||
<%- value %>
|
||||
<% } else { %>
|
||||
<% } else if (type=="richtext") { %>
|
||||
.custom-field-value.js-value-view-mode.wysiwyg
|
||||
div(ng-bind-html!="\'<%- value %>\'|markdownToHTML")
|
||||
<% } else { %>
|
||||
.custom-field-value.js-value-view-mode
|
||||
span
|
||||
<%- value %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
<% if (isEditable) { %>
|
||||
.custom-field-options
|
||||
|
|
|
@ -30,6 +30,10 @@ section.custom-fields-table.basic-table
|
|||
ng-switch-default
|
||||
translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT"
|
||||
)
|
||||
span(
|
||||
ng-switch-when="richtext"
|
||||
translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_RICHTEXT"
|
||||
)
|
||||
span(
|
||||
ng-switch-when="multiline"
|
||||
translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI"
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
padding: 0 1rem 0 2rem;
|
||||
&.js-value-view-mode {
|
||||
white-space: pre-line;
|
||||
&.wysiwyg {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
form {
|
||||
|
|
Loading…
Reference in New Issue