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"],