diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3670fbcb..67620f95 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@
## 2.0.0 ??? (unreleased)
### Features
-- ...
+- Ability to create url custom fields. (thanks to [@astagi](https://github.com/astagi)).
### Misc
- Lots of small and not so small bugfixes.
diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee
index 0e8b6f37..5d782823 100644
--- a/app/coffee/app.coffee
+++ b/app/coffee/app.coffee
@@ -510,16 +510,6 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
$httpProvider.interceptors.push("versionCheckHttpIntercept")
- window.checksley.updateValidators({
- linewidth: (val, width) ->
- lines = taiga.nl2br(val).split("
")
-
- valid = _.every lines, (line) ->
- line.length < width
-
- return valid
- })
-
$compileProvider.debugInfoEnabled(window.taigaConfig.debugInfo || false)
if localStorage.userInfo
@@ -577,6 +567,8 @@ i18nInit = (lang, $translate) ->
maxcheck: $translate.instant("COMMON.FORM_ERRORS.MAX_CHECK")
rangecheck: $translate.instant("COMMON.FORM_ERRORS.RANGE_CHECK")
equalto: $translate.instant("COMMON.FORM_ERRORS.EQUAL_TO")
+ linewidth: $translate.instant("COMMON.FORM_ERRORS.LINEWIDTH") # Extra validator
+ pikaday: $translate.instant("COMMON.FORM_ERRORS.PIKADAY") # Extra validator
}
checksley.updateMessages('default', messages)
@@ -584,6 +576,21 @@ i18nInit = (lang, $translate) ->
init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $navUrls, appMetaService, projectService, loaderService, navigationBarService) ->
$log.debug("Initialize application")
+ # Checksley - Extra validators
+ validators = {
+ linewidth: (val, width) ->
+ lines = taiga.nl2br(val).split("
")
+
+ valid = _.every lines, (line) ->
+ line.length < width
+
+ return valid
+ pikaday: (val) ->
+ prettyDate = $translate.instant("COMMON.PICKERDATE.FORMAT")
+ return moment(val, prettyDate).isValid()
+ }
+ checksley.updateValidators(validators)
+
# Taiga Plugins
$rootscope.contribPlugins = @.taigaContribPlugins
$rootscope.adminPlugins = _.filter(@.taigaContribPlugins, {"type": "admin"})
diff --git a/app/coffee/modules/admin/project-values.coffee b/app/coffee/modules/admin/project-values.coffee
index dff5ae07..de031bdc 100644
--- a/app/coffee/modules/admin/project-values.coffee
+++ b/app/coffee/modules/admin/project-values.coffee
@@ -381,6 +381,7 @@ module.directive("tgColorSelection", ColorSelectionDirective)
TEXT_TYPE = "text"
MULTILINE_TYPE = "multiline"
DATE_TYPE = "date"
+URL_TYPE = "url"
TYPE_CHOICES = [
@@ -395,6 +396,10 @@ TYPE_CHOICES = [
{
key: DATE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE"
+ },
+ {
+ key: URL_TYPE,
+ name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_URL"
}
]
@@ -555,7 +560,6 @@ ProjectCustomAttributesDirective = ($log, $confirm, animationFrame, $translate)
$el.on "click", ".js-add-custom-field-button", (event) ->
event.preventDefault()
-
showCreateForm()
$el.on "click", ".js-create-custom-field-button", debounce 2000, (event) ->
@@ -567,7 +571,6 @@ ProjectCustomAttributesDirective = ($log, $confirm, animationFrame, $translate)
$el.on "click", ".js-cancel-new-custom-field-button", (event) ->
event.preventDefault()
-
cancelCreate()
$el.on "keyup", ".js-new-custom-field input", (event) ->
diff --git a/app/coffee/modules/common/custom-field-values.coffee b/app/coffee/modules/common/custom-field-values.coffee
index ad748350..8568cae5 100644
--- a/app/coffee/modules/common/custom-field-values.coffee
+++ b/app/coffee/modules/common/custom-field-values.coffee
@@ -34,6 +34,7 @@ module = angular.module("taigaCommon")
TEXT_TYPE = "text"
MULTILINE_TYPE = "multiline"
DATE_TYPE = "date"
+URL_TYPE = "url"
TYPE_CHOICES = [
@@ -48,6 +49,10 @@ TYPE_CHOICES = [
{
key: DATE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE"
+ },
+ {
+ key: URL_TYPE,
+ name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_URL"
}
]
@@ -100,6 +105,7 @@ class CustomAttributesValuesController extends taiga.Controller
CustomAttributesValuesDirective = ($templates, $storage) ->
template = $templates.get("custom-attributes/custom-attributes-values.html", true)
+
collapsedHash = (type) ->
return generateHash(["custom-attributes-collapsed", type])
@@ -198,12 +204,14 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
submit = debounce 2000, (event) =>
event.preventDefault()
- attributeValue.value = $el.find("input[name=value], textarea[name='value']").val()
+ form = $el.find("form").checksley()
+ return if not form.validate()
+
+ input = $el.find("input[name=value], textarea[name='value']")
+ attributeValue.value = input.val()
if attributeValue.type is DATE_TYPE
if moment(attributeValue.value, prettyDate).isValid()
attributeValue.value = moment(attributeValue.value, prettyDate).format("YYYY-MM-DD")
- else
- attributeValue.value = ""
$scope.$apply ->
$ctrl.updateAttributeValue(attributeValue).then ->
@@ -217,6 +225,10 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
render(attributeValue)
## Actions (on view mode)
+
+ $el.on "click", ".js-value-view-mode span a", (event) ->
+ event.stopPropagation()
+
$el.on "click", ".js-value-view-mode", ->
return if not isEditable()
return if $selectedText.get().length
diff --git a/app/locales/taiga/locale-en.json b/app/locales/taiga/locale-en.json
index 8480026f..3ab75a0d 100644
--- a/app/locales/taiga/locale-en.json
+++ b/app/locales/taiga/locale-en.json
@@ -65,7 +65,8 @@
"MIN_CHECK": "You must select at least %s choices.",
"MAX_CHECK": "You must select %s choices or less.",
"RANGE_CHECK": "You must select between %s and %s choices.",
- "EQUAL_TO": "This value should be the same."
+ "EQUAL_TO": "This value should be the same.",
+ "PIKADAY": "Invalid date format, use DD MMM YYYY (like 23 Mar 1984)"
},
"PICKERDATE": {
"FORMAT": "DD MMM YYYY",
@@ -494,7 +495,8 @@
"ISSUE_ADD": "Add a custom field in issues",
"FIELD_TYPE_TEXT": "Text",
"FIELD_TYPE_MULTI": "Multi-line",
- "FIELD_TYPE_DATE": "Date"
+ "FIELD_TYPE_DATE": "Date",
+ "FIELD_TYPE_URL": "Url"
},
"PROJECT_VALUES": {
"PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}",
diff --git a/app/partials/custom-attributes/custom-attribute-value-edit.jade b/app/partials/custom-attributes/custom-attribute-value-edit.jade
index f6869cba..1f90518e 100644
--- a/app/partials/custom-attributes/custom-attribute-value-edit.jade
+++ b/app/partials/custom-attributes/custom-attribute-value-edit.jade
@@ -14,7 +14,9 @@ form.custom-field-single.editable
<% } else if (type=="multiline") { %>
textarea#custom-field-value(name="value") <%- value %>
<% } else if (type=="date") { %>
- input#custom-field-value(name="value", type="text", value!="<%- value %>")
+ input#custom-field-value(name="value", type="text", data-pikaday, value!="<%- value %>")
+ <% } else if (type=="url") { %>
+ input#custom-field-value(name="value", type="url", data-type="url", value!="<%- value %>")
<% } else { %>
input#custom-field-value(name="value", type="text", value!="<%- value %>")
<% } %>
diff --git a/app/partials/custom-attributes/custom-attribute-value.jade b/app/partials/custom-attributes/custom-attribute-value.jade
index f7ac5620..c89dbd06 100644
--- a/app/partials/custom-attributes/custom-attribute-value.jade
+++ b/app/partials/custom-attributes/custom-attribute-value.jade
@@ -9,7 +9,12 @@ div.custom-field-single
div.custom-field-value.js-value-view-mode
span
+ <% if (type=="url") { %>
+ a(href!="<%- value %>")
+ <%- value %>
+ <% } else { %>
<%- value %>
+ <% } %>
<% if (isEditable) { %>
div.custom-field-options
diff --git a/app/partials/includes/modules/admin/admin-custom-attributes.jade b/app/partials/includes/modules/admin/admin-custom-attributes.jade
index 353ea45e..bb03c36c 100644
--- a/app/partials/includes/modules/admin/admin-custom-attributes.jade
+++ b/app/partials/includes/modules/admin/admin-custom-attributes.jade
@@ -32,6 +32,7 @@ section.custom-fields-table.basic-table
span(ng-switch-default, translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT")
span(ng-switch-when="multiline", translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI")
span(ng-switch-when="date", translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE")
+ span(ng-switch-when="url", translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_URL")
div.custom-options
div.custom-options-wrapper
a.js-edit-custom-field-button.icon.icon-edit(
diff --git a/app/styles/core/forms.scss b/app/styles/core/forms.scss
index 1ef309d3..238bdbd8 100644
--- a/app/styles/core/forms.scss
+++ b/app/styles/core/forms.scss
@@ -8,6 +8,7 @@ fieldset {
input[type="text"],
input[type="number"],
input[type="password"],
+input[type="url"],
input[type="email"],
input[type="date"],
input[type="password"],
diff --git a/app/themes/high-contrast/custom.scss b/app/themes/high-contrast/custom.scss
index 0ad07c93..c566bacc 100644
--- a/app/themes/high-contrast/custom.scss
+++ b/app/themes/high-contrast/custom.scss
@@ -78,6 +78,7 @@ a {
input[type="text"],
input[type="number"],
input[type="password"],
+input[type="url"],
input[type="email"],
input[type="date"],
input[type="password"],
diff --git a/app/themes/material-design/custom.scss b/app/themes/material-design/custom.scss
index e37abb23..7ada1f31 100644
--- a/app/themes/material-design/custom.scss
+++ b/app/themes/material-design/custom.scss
@@ -73,6 +73,7 @@ a {
input[type="text"],
input[type="number"],
input[type="password"],
+input[type="url"],
input[type="email"],
input[type="date"],
input[type="password"],
diff --git a/app/themes/taiga/custom.scss b/app/themes/taiga/custom.scss
index 08adf274..7a5ad4d7 100644
--- a/app/themes/taiga/custom.scss
+++ b/app/themes/taiga/custom.scss
@@ -55,6 +55,7 @@ a {
input[type="text"],
input[type="number"],
input[type="password"],
+input[type="url"],
input[type="email"],
input[type="date"],
input[type="password"],