Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/smh/form-submission-notification…
Browse files Browse the repository at this point in the history
…-translation' into autostaging
  • Loading branch information
MartinRiese committed Dec 19, 2023
2 parents da41820 + 77ad5dd commit 490d793
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 10 deletions.
2 changes: 2 additions & 0 deletions corehq/apps/app_manager/app_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ def _create_forms_app_strings(
clean_trans(custom_assertion.text, langs)
)

yield id_strings.form_submit_label_locale(form), form.get_submit_label(lang)
yield id_strings.form_submit_notification_label_locale(form), form.get_submit_notification_label(lang)

def _create_case_list_form_app_strings(
app,
Expand Down
16 changes: 16 additions & 0 deletions corehq/apps/app_manager/id_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,22 @@ def form_custom_icon_locale(form, icon_form):
)


@pattern('forms.m%df%d.submit_label')
def form_submit_label_locale(form):
return "forms.m{module.id}f{form.id}.submit_label".format(
module=form.get_module(),
form=form
)


@pattern('forms.m%df%d.submit_notification_label')
def form_submit_notification_label_locale(form):
return "forms.m{module.id}f{form.id}.submit_notification_label".format(
module=form.get_module(),
form=form
)


@pattern('case_list_form.m%d.icon')
def case_list_form_icon_locale(module):
return "case_list_form.m{module.id}.icon".format(module=module)
Expand Down
13 changes: 13 additions & 0 deletions corehq/apps/app_manager/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,9 @@ class FormBase(DocumentSchema):
# computed datums IDs that are allowed in endpoints
function_datum_endpoints = StringListProperty()

submit_label = LabelProperty(default={})
submit_notification_label = LabelProperty(default={})

def __repr__(self):
return f"{self.doc_type}(id='{self.id}', name='{self.default_name()}', unique_id='{self.unique_id}')"

Expand Down Expand Up @@ -1339,6 +1342,16 @@ def get_save_to_case_updates(self):
updates_by_case_type[case_type].update(save_to_case_update.properties)
return updates_by_case_type

def get_submit_label(self, lang):
if lang in self.submit_label:
return self.submit_label[lang]
return 'Submit'

def get_submit_notification_label(self, lang):
if self.submit_notification_label and lang in self.submit_notification_label:
return self.submit_notification_label[lang]
return ''


class IndexedFormBase(FormBase, IndexedSchema, CommentMixin):

Expand Down
25 changes: 25 additions & 0 deletions corehq/apps/app_manager/tests/test_app_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,28 @@ def test_no_items_text_app_strings(self):
en_app_strings = self._generate_app_strings(app, 'default', build_profile_id='en')
except AttributeError:
self.fail("_generate_app_strings raised AttributeError unexpectedly")

def test_form_submit_label(self):
factory = AppFactory(build_version='2.40.0')
factory.app.langs = ['en', 'es']
module, form = factory.new_basic_module('my_module', 'cases')
form.submit_label = {
'en': 'Submit Button',
'es': 'Botón de Enviar',
}
form.submit_notification_label = {
'en': 'You submitted the form!',
'es': '¡Enviaste el formulario!',
}
en_strings = self._generate_app_strings(factory.app, 'en')
self.assertEqual(en_strings['forms.m0f0.submit_label'], form.submit_label['en'])
self.assertEqual(en_strings['forms.m0f0.submit_notification_label'], form.submit_notification_label['en'])

es_strings = self._generate_app_strings(factory.app, 'es')
self.assertEqual(es_strings['forms.m0f0.submit_label'], form.submit_label['es'])
self.assertEqual(es_strings['forms.m0f0.submit_notification_label'], form.submit_notification_label['es'])

default_strings = self._generate_app_strings(factory.app, 'default')
self.assertEqual(default_strings['forms.m0f0.submit_label'], form.submit_label['en'])
self.assertEqual(default_strings['forms.m0f0.submit_notification_label'],
form.submit_notification_label['en'])
14 changes: 13 additions & 1 deletion corehq/apps/cloudcare/static/cloudcare/js/form_entry/form_ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,11 +461,23 @@ hqDefine("cloudcare/js/form_entry/form_ui", function () {
return !self.isSubmitting() && self.erroredQuestions().length === 0;
});

self.getSubmitTranslation = function () {
var translations = self.translations;
if (translations) {
const result = Object.entries(translations).find(([k]) => k.includes("submit_label"));
if (result) {
const key = result[0];
return ko.toJS(translations[key]);
}
}
return "Submit";
};

self.submitText = ko.computed(function () {
if (self.isSubmitting()) {
return gettext('Submitting...');
}
return gettext('Submit');
return gettext(self.getSubmitTranslation());
});

self.forceRequiredVisible = ko.observable(false);
Expand Down
9 changes: 9 additions & 0 deletions corehq/apps/translations/app_translations/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,12 @@ def get_form_question_label_name_media(langs, form):
value += part
itext_items[text_id][(lang, value_form)] = value

itext_items['submit_label'] = {}
itext_items['submit_notification_label'] = {}
for lang in langs:
itext_items['submit_label'][(lang, 'default')] = form.get_submit_label(lang)
itext_items['submit_notification_label'][(lang, 'default')] = form.get_submit_notification_label(lang)

app = form.get_app()
for text_id, values in itext_items.items():
row = [text_id]
Expand All @@ -396,5 +402,8 @@ def get_form_question_label_name_media(langs, form):
# Don't add empty rows:
if any(row[1:]):
rows.append(row)
# allow empty for submit_notification_label row
if row[0] == 'submit_notification_label' and not any(row[1:]):
rows.append(row)

return rows
15 changes: 15 additions & 0 deletions corehq/apps/translations/app_translations/upload_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ def update(self, rows):
for row in rows:
if row['label'] in label_ids_to_skip:
continue
if row['label'] == 'submit_label':
try:
self.form.submit_label[lang] = row[self._get_col_key('default', lang)]
except KeyError:
pass
continue
if row['label'] == 'submit_notification_label':
notification_value = ''
try:
notification_value = row[self._get_col_key('default', lang)]
except KeyError:
pass
if notification_value:
self.form.submit_notification_label[lang] = notification_value
continue
try:
self._add_or_remove_translations(lang, row)
except BulkAppTranslationsException as e:
Expand Down
43 changes: 37 additions & 6 deletions corehq/apps/translations/tests/test_bulk_app_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@
'jr://file/commcare/image/data/What_does_this_look_like.png', '', ''),
('no_media-label', 'No media', '', '', ''),
('has_refs-label', 'Here is a ref <output value="/data/no_media"/> with some trailing text '
'and "bad" &lt; xml.', '', '', ''))),
'and "bad" &lt; xml.', '', '', ''),
('submit_label', 'Submit', '', '', ''))),
('menu2', (('no_items_text', 'list', 'List is empty.'), ('name', 'list', 'Name'), ('name', 'detail', 'Name'))),
('menu2_form1',
('name_of_series-label', 'Name of series', '', '', '')),
(('name_of_series-label', 'Name of series', '', '', ''),
('submit_label', 'Submit', '', '', ''))),
('menu3',
(('no_items_text', 'list', 'List is empty.'),
('name', 'list', 'Name'),
Expand All @@ -114,7 +116,8 @@
('graph annotation 1', 'detail', 'This is (2, 2)'))),
('menu3_form1',
(('x-label', 'x', '', '' ''),
('y-label', 'y', '', '', ''))),
('y-label', 'y', '', '', ''),
('submit_label', 'Submit', '', '', ''))),
('menu4',
(('no_items_text', 'list', 'List is empty.'),
('x', 'list', 'X'),
Expand All @@ -127,12 +130,13 @@
(('confirm_remove-label',
'Swipe to remove the point at (<output value="instance(\'casedb\')/casedb/case[@case_id = '
'instance(\'commcaresession\')/session/data/case_id]/x"/> ,<output value="instance(\'casedb\')'
'/casedb/case[@case_id = instance(\'commcaresession\')/session/data/case_id]/y"/>).'),
'', '', '')),
'/casedb/case[@case_id = instance(\'commcaresession\')/session/data/case_id]/y"/>).', '', '', ''),
('submit_label', 'Submit', '', '', ''))),
('menu5', ()),
('menu6', (('no_items_text', 'list', 'List is empty.'), ('name', 'list', 'Name'), ('name', 'detail', 'Name'))),
('menu6_form1',
(('this_form_does_nothing-label', 'This form does nothing.', '', '', ''),)),
(('this_form_does_nothing-label', 'This form does nothing.', '', '', ''),
('submit_label', 'Submit', '', '', ''))),
)


Expand Down Expand Up @@ -394,6 +398,8 @@ class BulkAppTranslationBasicTest(BulkAppTranslationTestBaseWithApp):
('remove_markdown-label', 'no longer markdown', 'just plain text', '', '', '', '', '', ''),
('vetoed_markdown-label', '*i just happen to like stars a lot*', '*i just happen to like stars a lot*',
'', '', '', '', '', ''),
("submit_label", "new submit", "nouveau", "", "", "", "", "", ""),
("submit_notification_label", "new submit notification", "nouveau", "", "", "", "", "", ""),
))
)

Expand Down Expand Up @@ -780,6 +786,25 @@ def test_empty_translations(self):
]
)

def test_form_submit_label_on_upload(self):
form = self.app.get_module(0).get_form(0)
form.submit_label = {'en': 'old label', 'fra': 'passé'}
self.assertEqual(form.submit_label, {'en': 'old label', 'fra': 'passé'})

# note changes on upload with new value
self.upload_raw_excel_translations(self.multi_sheet_upload_headers, self.multi_sheet_upload_data)
self.assertEqual(form.submit_label, {'en': 'new submit', 'fra': 'nouveau'})

def test_submit_notification_label_on_upload(self):
form = self.app.get_module(0).get_form(0)
form.submit_notification_label = {'en': 'old submission label', 'fra': 'passé'}
self.assertEqual(form.submit_notification_label, {'en': 'old submission label', 'fra': 'passé'})

# note changes on upload with new value
self.upload_raw_excel_translations(self.multi_sheet_upload_headers, self.multi_sheet_upload_data)
self.assertEqual(form.submit_notification_label, {'en': 'new submit notification', 'fra': 'nouveau'})


def test_case_search_labels_on_upload(self):
module = self.app.get_module(0)

Expand Down Expand Up @@ -1130,6 +1155,7 @@ def test_form_rows(self):
['has_refs-label',
'Here is a ref <output value="/data/no_media"/> with some trailing text and "bad" &lt; xml.',
'', '', ''],
['submit_label', 'Submit', '', '', '']
])

@patch.object(Application, 'supports_empty_case_list_text', lambda: True)
Expand Down Expand Up @@ -1203,13 +1229,15 @@ def test_bulk_app_single_sheet_rows(self):
['menu1_form1', '', '', 'has_refs-label',
'Here is a ref <output value="/data/no_media"/> with some trailing text and "bad" &lt; xml.', '', '',
'', ''],
['menu1_form1', '', '', 'submit_label', 'Submit', '', '', '', ''],

['menu2', '', '', '', 'Register Series', '', '', '', 'b9c25abe21054632a3623199debd7cfa'],
['menu2', 'name', 'list', '', 'Name', '', '', '', ''],
['menu2', 'name', 'detail', '', 'Name', '', '', '', ''],

['menu2_form1', '', '', '', 'Registration Form', None, None, '', '280b1b06d1b442b9bba863453ba30bc3'],
['menu2_form1', '', '', 'name_of_series-label', 'Name of series', '', '', '', ''],
['menu2_form1', '', '', 'submit_label', 'Submit', '', '', '', ''],

['menu3', '', '', '', 'Followup Series', '', '', '', '217e1c8de3dd46f98c7d2806bc19b580'],
['menu3', 'name', 'list', '', 'Name', '', '', '', ''],
Expand All @@ -1227,6 +1255,7 @@ def test_bulk_app_single_sheet_rows(self):
['menu3_form1', '', '', '', 'Add Point to Series', None, None, '', 'a01b55fd2c1a483492c1166029946249'],
['menu3_form1', '', '', 'x-label', 'x', '', '', '', ''],
['menu3_form1', '', '', 'y-label', 'y', '', '', '', ''],
['menu3_form1', '', '', 'submit_label', 'Submit', '', '', '', ''],

['menu4', '', '', '', 'Remove Point', '', '', '', '17195132472446ed94bd91ba19a2b379'],
['menu4', 'x', 'list', '', 'X', '', '', '', ''],
Expand All @@ -1241,6 +1270,7 @@ def test_bulk_app_single_sheet_rows(self):
'(<output value="instance(\'casedb\')/casedb/case[@case_id = instance(\'commcaresession\')/'
'session/data/case_id]/x"/> ,<output value="instance(\'casedb\')/casedb/case[@case_id = '
'instance(\'commcaresession\')/session/data/case_id]/y"/>).', '', '', '', ''],
['menu4_form1', '', '', 'submit_label', 'Submit', '', '', '', ''],

['menu5', '', '', '', 'Empty Reports Module', '', '', '', '703eb807ae584d1ba8bf9457d7ac7590'],

Expand All @@ -1250,6 +1280,7 @@ def test_bulk_app_single_sheet_rows(self):

['menu6_form1', '', '', '', 'Advanced Form', None, None, '', '2b9c856ba2ea4ec1ab8743af299c1627'],
['menu6_form1', '', '', 'this_form_does_nothing-label', 'This form does nothing.', '', '', '', ''],
['menu6_form1', '', '', 'submit_label', 'Submit', '', '', '', ''],
['menu6_form2', '', '', '', 'Shadow Form', '', '', '', 'c42e1a50123c43f2bd1e364f5fa61379']])

def test_bulk_app_single_sheet_blacklisted(self):
Expand Down
32 changes: 29 additions & 3 deletions corehq/form_processor/submission_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,12 @@ def _get_success_message(self, instance, cases=None):
return ' √ '

user = CouchUser.get_by_user_id(instance.user_id)
messages = [_("'{form_name}' successfully saved!")
.format(form_name=self._get_form_name(instance, user))]
notification_text = self._get_form_submission_text(instance, user)
if notification_text:
messages = [notification_text]
else:
messages = [_("'{form_name}' successfully saved!")
.format(form_name=self._get_form_name(instance, user))]
if user and user.is_web_user():
messages.extend(self._success_message_links(user, instance, cases))
return "\n\n".join(messages)
Expand All @@ -182,6 +186,17 @@ def _get_form_name(self, instance, user):
return names[default_language]
return instance.name

def _get_form_submission_text(self, instance, user):
if instance.build_id:
default_language, submission_text_by_lang = _get_form_submit_notification_text_info(instance.domain,
instance.build_id)
submission_text_dict = submission_text_by_lang.get(instance.xmlns, {})
if user and user.language and submission_text_dict.get(user.language):
return submission_text_dict[user.language]
if submission_text_dict.get(default_language):
return submission_text_dict[default_language]
return None

def _success_message_links(self, user, instance, cases):
"""Yield links to reports/exports, if accessible"""
from corehq.apps.export.views.list import CaseExportListView, FormExportListView
Expand Down Expand Up @@ -230,7 +245,6 @@ def _success_message_links(self, user, instance, cases):
elif case_export_link:
yield _("Click to export your [case data]({}).").format(case_export_link)


def run(self):
self.track_load()
with self.timing_context("process_xml"):
Expand Down Expand Up @@ -671,3 +685,15 @@ def _get_form_name_info(domain, build_id):
app_build.default_language,
{form.xmlns: dict(form.name) for form in app_build.get_forms() if form.form_type != 'shadow_form'}
)


@quickcache(['domain', 'build_id'])
def _get_form_submit_notification_text_info(domain, build_id):
try:
app_build = get_current_app(domain, build_id)
except ResourceNotFound:
return 'en', {}
return (
app_build.default_language,
{form.xmlns: dict(form.submit_notification_label) for form in app_build.get_forms()}
)

0 comments on commit 490d793

Please sign in to comment.