diff --git a/jsapp/js/app.es6 b/jsapp/js/app.es6
index d39b8fa678..c1e530ebd2 100644
--- a/jsapp/js/app.es6
+++ b/jsapp/js/app.es6
@@ -8,6 +8,7 @@ import $ from 'jquery';
window.jQuery = $;
window.$ = $;
require('jquery-ui/ui/widgets/sortable');
+require('jquery-ui/ui/widgets/resizable');
import React from 'react';
import ReactDOM from 'react-dom';
diff --git a/jsapp/scss/main.scss b/jsapp/scss/main.scss
index 49cbb662f7..16bda0f38b 100644
--- a/jsapp/scss/main.scss
+++ b/jsapp/scss/main.scss
@@ -6,6 +6,7 @@
@import "~select2/select2.css";
@import "~react-table/react-table.css";
@import "~alertifyjs/build/css/alertify.css";
+@import "~jquery-ui/themes/base/all.css";
@import "./libs/alertify.overrides";
@import "./libs/react-select.overrides";
diff --git a/jsapp/scss/stylesheets/partials/form_builder/_card.scss b/jsapp/scss/stylesheets/partials/form_builder/_card.scss
index b99c432711..2e97712c6f 100644
--- a/jsapp/scss/stylesheets/partials/form_builder/_card.scss
+++ b/jsapp/scss/stylesheets/partials/form_builder/_card.scss
@@ -59,8 +59,25 @@
font-size: 15px;
}
}
+
+ .ui-resizable-handle {
+ color: $cool-gray;
+
+ &:hover {
+ border-top: 1px solid darken($cool-gray, 20%);
+ }
+ }
}
+ .card__header-name {
+ text-align: right;
+ padding-bottom: 10px;
+ color: $cool-gray;
+
+ &:focus {
+ color: $black;
+ }
+ }
.card__header-title {
color: $cool-gray;
@@ -306,11 +323,14 @@ $cardIndicatorIconWidth: 21px;
&.card__buttons__button--blue {
color:$linkColor;
}
- // &.card__buttons__button--add {
- // bottom: 22%;
- // }
+ &.card__buttons__button--delete {
+ top: 32px;
+ }
&.card__buttons__button--copy {
- bottom: 26%;
+ top: 45px;
+ }
+ &.card__buttons__button--add {
+ top: 68px;
}
&.card__buttons__button--activated {
// trying to transition this into %activated-card-button
diff --git a/jsapp/scss/stylesheets/partials/form_builder/_card_settings.scss b/jsapp/scss/stylesheets/partials/form_builder/_card_settings.scss
index 53ee9d34f7..5fc49dd8c3 100644
--- a/jsapp/scss/stylesheets/partials/form_builder/_card_settings.scss
+++ b/jsapp/scss/stylesheets/partials/form_builder/_card_settings.scss
@@ -122,7 +122,8 @@
}
}
- input[type="text"] {
+ input[type="text"],
+ textarea {
width: 85%;
padding: 2px;
font-size: 13px;
@@ -142,7 +143,8 @@
color: $cool-red;
input.text,
- select {
+ select,
+ textarea {
border-color: $cool-red;
}
}
diff --git a/jsapp/scss/stylesheets/partials/form_builder/_misc.scss b/jsapp/scss/stylesheets/partials/form_builder/_misc.scss
index 52af9eecc2..75e6fd8075 100644
--- a/jsapp/scss/stylesheets/partials/form_builder/_misc.scss
+++ b/jsapp/scss/stylesheets/partials/form_builder/_misc.scss
@@ -22,6 +22,7 @@
// inputs in edit-in-place
.card__text input,
+.card__text textarea,
.editable-wrapper input {
font-family: $font;
border: none;
@@ -29,11 +30,15 @@
margin: 0px;
font-weight: 600;
display: inline;
- height: auto !important;
font-size: 13px;
width: 100%;
}
+.card__text input,
+.editable-wrapper input {
+ height: auto !important;
+}
+
code input[type="text"] {
border: none;
padding: 0px;
diff --git a/jsapp/xlform/src/view.row.coffee b/jsapp/xlform/src/view.row.coffee
index 08289cf4da..4aa072aeb7 100644
--- a/jsapp/xlform/src/view.row.coffee
+++ b/jsapp/xlform/src/view.row.coffee
@@ -268,6 +268,7 @@ module.exports = do ->
@
_renderRow: ->
@$el.html $viewTemplates.$$render('row.xlfRowView', @surveyView)
+ @$name = @$('.card__header-name')
@$label = @$('.card__header-title')
@$hint = @$('.card__header-hint')
@$card = @$('.card')
@@ -295,6 +296,9 @@ module.exports = do ->
@is_expanded = true
@listView = new $viewChoices.ListView(model: cl, rowView: @).render()
+ if @model.getValue('name')?
+ @$name.html(@model.getValue('name'))
+
@cardSettingsWrap = @$('.card__settings').eq(0)
@defaultRowDetailParent = @cardSettingsWrap.find('.card__settings__fields--question-options').eq(0)
for [key, val] in @model.attributesArray() when key in ['label', 'hint', 'type']
diff --git a/jsapp/xlform/src/view.row.templates.coffee b/jsapp/xlform/src/view.row.templates.coffee
index 8fbe66cd1c..875e766feb 100644
--- a/jsapp/xlform/src/view.row.templates.coffee
+++ b/jsapp/xlform/src/view.row.templates.coffee
@@ -62,7 +62,8 @@ module.exports = do ->
-
+
+
diff --git a/jsapp/xlform/src/view.rowDetail.coffee b/jsapp/xlform/src/view.rowDetail.coffee
index 6c954fe2e9..7dc431075d 100644
--- a/jsapp/xlform/src/view.rowDetail.coffee
+++ b/jsapp/xlform/src/view.rowDetail.coffee
@@ -70,7 +70,7 @@ module.exports = do ->
# the model's value is reflected in the element and changes
# to the element are reflected in the model (with transformFn
# applied)
- el = opts.el || @$('input').get(0)
+ el = opts.el || @$('input').get(0) || @$('textarea').get(0)
$el = $(el)
transformFn = opts.transformFn || false
@@ -128,7 +128,7 @@ module.exports = do ->
@_insertInDOM rowView.defaultRowDetailParent
makeFieldCheckCondition: (opts={}) ->
- el = opts.el || @$('input').get(0)
+ el = opts.el || @$('input').get(0) || @$('textarea').get(0)
$el = $(el)
fieldClass = opts.fieldClass || 'input-error'
message = opts.message || "This field is required"
@@ -165,7 +165,7 @@ module.exports = do ->
showOrHideCondition()
removeFieldCheckCondition: (opts={}) ->
- el = opts.el || @$('input').get(0)
+ el = opts.el || @$('input').get(0) || @$('textarea').get(0)
$el = $(el)
fieldClass = opts.fieldClass || 'input-error'
@@ -189,6 +189,14 @@ module.exports = do ->
else
@field """""", cid, key_label
+ textarea: (cid, key, key_label = key, input_class = '', placeholder_text='', max_length = '') ->
+ if placeholder_text is not ''
+ placeholder_text = _t(placeholder_text)
+ if max_length is ''
+ @field """""", cid, key_label
+ else
+ @field """""", cid, key_label
+
checkbox: (cid, key, key_label = key, input_label = _t("Yes")) ->
input_label = input_label
@field """ """, cid, key_label
@@ -262,6 +270,25 @@ module.exports = do ->
value = value.replace /\t/g, ' '
return value
})
+ $textarea = $(this.rowView.$label)
+ if @model.get("value")?
+ setTimeout =>
+ textareaScrollHeight = $textarea.prop('scrollHeight')
+ textAreaLineHeight = parseInt($textarea.css('line-height'))
+ maxLine = 3
+ textAreaSetHeight = Math.min(textareaScrollHeight, (textAreaLineHeight * maxLine)) + 7
+ $textarea.css("height", "")
+ $textarea.css("height", textAreaSetHeight)
+ $textarea.resizable({
+ containment: "parent",
+ handles: "s"
+ })
+ , 1
+ else
+ $textarea.resizable({
+ containment: "parent",
+ handles: "s"
+ })
return
viewRowDetail.DetailViewMixins.hint =
@@ -361,9 +388,17 @@ module.exports = do ->
@model.set 'value', value
@model.deduplicate @model.getSurvey(), @model.getSurvey().rowItemNameMaxLength
)
+
+ @model.on 'change:value', () =>
+ @$el.closest('.survey__row__item').find('.card__header-name').html(@model.getValue())
+
update_view = () => @$el.find('input').eq(0).val(@model.get("value") || '')
update_view()
+ setTimeout =>
+ @$el.closest('.survey__row__item').find('.card__header-name').html(@model.getValue())
+ , 1
+
if @model._parent.get('label')?
@model._parent.get('label').on 'change:value', update_view
@makeRequired()
@@ -472,10 +507,30 @@ module.exports = do ->
@fieldTab = "active"
@$el.addClass("card__settings__fields--#{@fieldTab}")
label = if @model.key == 'default' then _t("Default value") else @model.key.replace(/_/g, ' ')
- viewRowDetail.Templates.textbox @cid, @model.key, label, 'text'
+ viewRowDetail.Templates.textarea @cid, @model.key, label, 'text'
+ changeModelValue: () ->
+ $textarea = $(@$('textarea').get(0))
+ $elVal = $textarea.val().replace(/\n/g, "")
+ @model.set('value', $elVal)
afterRender: ->
- @$el.find('input').eq(0).val(@model.get("value"))
- @listenForInputChange()
+ $textarea = $(@$('textarea').get(0))
+ $textarea.val(@model.get("value"))
+ if @model.get("value")?
+ setTimeout =>
+ textareaScrollHeight = $textarea.prop('scrollHeight')
+ $textarea.css("height", "")
+ $textarea.css("height", textareaScrollHeight)
+ , 1
+ $textarea.on 'blur', () =>
+ @changeModelValue()
+ $textarea.on 'change', () =>
+ @changeModelValue()
+ $textarea.on 'keyup', () =>
+ @changeModelValue()
+ $textarea.on 'keypress', (evt) =>
+ if evt.key is 'Enter' or evt.keyCode is 13
+ evt.preventDefault()
+ $textarea.blur()
viewRowDetail.DetailViewMixins._isRepeat =
html: ->
@@ -998,14 +1053,37 @@ module.exports = do ->
html: ->
@fieldTab = "active"
@$el.addClass("card__settings__fields--#{@fieldTab}")
- viewRowDetail.Templates.textbox @cid, @model.key, _t("Calculation"), 'text'
+ viewRowDetail.Templates.textarea @cid, @model.key, _t("Calculation"), 'text'
+ changeModelValue: () ->
+ $textarea = $(@$('textarea').get(0))
+ $elVal = $textarea.val().replace(/\n/g, "")
+ @model.set('value', $elVal)
afterRender: ->
- questionType = @model._parent.get('type').get('typeId')
+ $textarea = $(@$('textarea').get(0))
+ $textarea.val(@model.get("value"))
- @listenForInputChange()
+ if @model.get("value")?
+ setTimeout =>
+ textareaScrollHeight = $textarea.prop('scrollHeight')
+ $textarea.css("height", "")
+ $textarea.css("height", textareaScrollHeight)
+ , 1
+
+ questionType = @model._parent.get('type').get('typeId')
if questionType is 'calculate'
@makeRequired()
+ $textarea.on 'blur', () =>
+ @changeModelValue()
+ $textarea.on 'change', () =>
+ @changeModelValue()
+ $textarea.on 'keyup', () =>
+ @changeModelValue()
+ $textarea.on 'keypress', (evt) =>
+ if evt.key is 'Enter' or evt.keyCode is 13
+ evt.preventDefault()
+ $textarea.blur()
+
viewRowDetail.DetailViewMixins.oc_description =
html: ->
@fieldTab = "active"
diff --git a/kpi/urls.py b/kpi/urls.py
index 13ec580a2b..5b86aff184 100644
--- a/kpi/urls.py
+++ b/kpi/urls.py
@@ -139,5 +139,5 @@
'kobo.apps.superuser_stats.views.user_report'),
url(r'^superuser_stats/user_report/(?P[^/]+)$',
'kobo.apps.superuser_stats.views.retrieve_user_report'),
- url(r'app_info$', app_info, name='app_info'),
+ url(r'app_info/$', app_info, name='app_info'),
]
diff --git a/oc/views.py b/oc/views.py
index a8cb185f95..845540ce60 100644
--- a/oc/views.py
+++ b/oc/views.py
@@ -24,6 +24,7 @@
from kpi.utils.domain import get_subdomain
from kpi.utils.log import logging as kpi_logging
+from kobo.apps.service_health.views import get_response
logger = logging.getLogger(__name__)
@@ -279,18 +280,6 @@ def logout(request, next_page=None):
if next_page:
request.session['next'] = next_page
-class OCAppInfo(object):
- def __init__(self, **kwargs):
- setattr(self, 'name', kwargs.get('name', 'FormDesigner'))
- setattr(self, 'version', kwargs.get('version', None))
-
-class OCAppInfoSerializer(serializers.Serializer):
- name = serializers.CharField(max_length=256)
- version = serializers.CharField(max_length=256)
-
- def create(self, app_info):
- return OCAppInfo(**app_info)
-
@csrf_exempt
def app_info(request):
if request.method == 'GET':
@@ -302,6 +291,22 @@ def app_info(request):
except IOError:
return HttpResponseNotFound()
- appInfo = OCAppInfo(version=package_info['version'])
- serializer = OCAppInfoSerializer(appInfo)
- return JsonResponse(serializer.data)
+ failure, kobocat_message, kobocat_content = get_response(settings.KOBOCAT_INTERNAL_URL + '/app_info/')
+
+ kobocat_data = {}
+ if not failure:
+ kobocat_data = json.loads(kobocat_content)
+ kobocat_data["status"] = "passing"
+ else:
+ kobocat_data["status"] = "failed"
+
+ kpi_data = {
+ "name": package_info["name"],
+ "description": package_info["description"],
+ "version": package_info["version"],
+ "status": "passing"
+ }
+
+ data = [kpi_data, kobocat_data]
+
+ return JsonResponse(data, safe=False)
diff --git a/package.json b/package.json
index 1f0dbd16e2..b7fb70c96d 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "kpi",
- "version": "2.1.3",
- "description": "KoBoToolbox frontend interface.",
+ "version": "2.1.4",
+ "description": "form designer ui",
"devDependencies": {
"@mapbox/leaflet-omnivore": "^0.3.4",
"alertifyjs": "^1.9.0",