+
+
sortedDefinitions.value.length === 0
description: t('profile_fields', 'Select a field from the list, or create a new one.'),
})
const configuredFieldsCountLabel = computed(() => n('profile_fields', 'field configured', 'fields configured', definitions.value.length, { count: definitions.value.length }))
-const saveActionLabel = computed(() => isSaving.value ? t('profile_fields', 'Saving changes…') : (isEditing.value ? t('profile_fields', 'Save changes') : t('profile_fields', 'Create field')))
+// TRANSLATORS "\u00A0" keeps the ellipsis attached to the previous word for correct typography and avoids awkward line breaks.
+const saveActionLabel = computed(() => isSaving.value ? t('profile_fields', 'Saving changes\u00A0…') : (isEditing.value ? t('profile_fields', 'Save changes') : t('profile_fields', 'Create field')))
const editFieldAriaLabel = (label: string) => t('profile_fields', 'Edit field {label}', { label })
const actionsForLabel = (label: string) => t('profile_fields', 'Actions for {label}', { label })
const toggleDefinitionActiveLabel = (definition: FieldDefinition) => definition.active
@@ -628,7 +631,7 @@ const persistDefinition = async() => {
selectedId.value = created.id
populateForm(created)
markJustSaved(created.id)
- setSuccessMessage(t('profile_fields', 'Field created successfully.'))
+ setSuccessMessage(t('profile_fields', 'Field created.'))
} else {
const updated = await updateDefinition(selectedDefinition.value.id, {
label: payload.label,
@@ -642,7 +645,7 @@ const persistDefinition = async() => {
replaceDefinitionInState(updated)
populateForm(updated)
markJustSaved(updated.id)
- setSuccessMessage(t('profile_fields', 'Field updated successfully.'))
+ setSuccessMessage(t('profile_fields', 'Field updated.'))
}
if (isCompactLayout.value) {
closeEditor()
@@ -666,7 +669,7 @@ const removeDefinition = async() => {
removeDefinitionFromState(selectedDefinition.value.id)
isCreatingNew.value = false
resetForm()
- setSuccessMessage(t('profile_fields', 'Field deleted successfully.'))
+ setSuccessMessage(t('profile_fields', 'Field deleted.'))
} catch (error: any) {
errorMessage.value = error?.response?.data?.ocs?.data?.message ?? error?.message ?? t('profile_fields', 'Could not delete this field. Please try again.')
} finally {
diff --git a/src/views/PersonalSettings.vue b/src/views/PersonalSettings.vue
index 7a9e26f..64e8891 100644
--- a/src/views/PersonalSettings.vue
+++ b/src/views/PersonalSettings.vue
@@ -151,7 +151,8 @@ SPDX-License-Identifier: AGPL-3.0-or-later
/>
- {{ isSaving(field.definition.id) ? t('profile_fields', 'Saving changes…') : t('profile_fields', 'Save changes') }}
+
+ {{ isSaving(field.definition.id) ? t('profile_fields', 'Saving changes\u00A0…') : t('profile_fields', 'Save changes') }}
diff --git a/src/workflow.ts b/src/workflow.ts
index 34c925d..4c79c48 100644
--- a/src/workflow.ts
+++ b/src/workflow.ts
@@ -535,8 +535,9 @@ class WorkflowProfileFieldElement extends HTMLElement {
const placeholder = document.createElement('option')
placeholder.value = ''
+ // TRANSLATORS "\u00A0" keeps the ellipsis attached to the previous word for correct typography and avoids awkward line breaks.
placeholder.textContent = definitions.length === 0
- ? t('profile_fields', 'Loading profile fields…')
+ ? t('profile_fields', 'Loading profile fields\u00A0…')
: t('profile_fields', 'Choose a profile field')
fieldSelect.append(placeholder)
diff --git a/tests/php/Unit/Controller/FieldDefinitionApiControllerTest.php b/tests/php/Unit/Controller/FieldDefinitionApiControllerTest.php
index 2369d76..ae8fca0 100644
--- a/tests/php/Unit/Controller/FieldDefinitionApiControllerTest.php
+++ b/tests/php/Unit/Controller/FieldDefinitionApiControllerTest.php
@@ -115,7 +115,7 @@ public function testCreateSelectFieldForwardsOptions(): void {
public function testCreateReturnsBadRequestOnValidationFailure(): void {
$this->service->expects($this->once())
->method('create')
- ->willThrowException(new InvalidArgumentException('field_key already exists'));
+ ->willThrowException(new InvalidArgumentException('"field_key" already exists'));
$response = $this->controller->create(
'cpf',
@@ -128,7 +128,7 @@ public function testCreateReturnsBadRequestOnValidationFailure(): void {
);
$this->assertSame(Http::STATUS_BAD_REQUEST, $response->getStatus());
- $this->assertSame(['message' => 'field_key already exists'], $response->getData());
+ $this->assertSame(['message' => '"field_key" already exists'], $response->getData());
}
public function testUpdateSelectFieldForwardsOptions(): void {
diff --git a/tests/php/Unit/Service/FieldDefinitionServiceTest.php b/tests/php/Unit/Service/FieldDefinitionServiceTest.php
index c0e4793..6c8657a 100644
--- a/tests/php/Unit/Service/FieldDefinitionServiceTest.php
+++ b/tests/php/Unit/Service/FieldDefinitionServiceTest.php
@@ -51,7 +51,7 @@ public function testCreateRejectsDuplicatedFieldKey(): void {
->willReturn(new FieldDefinition());
$this->expectException(InvalidArgumentException::class);
- $this->expectExceptionMessage('field_key already exists');
+ $this->expectExceptionMessage('"field_key" already exists');
$this->service->create([
'field_key' => 'cpf',
@@ -127,7 +127,7 @@ public function testUpdateRejectsFieldKeyRename(): void {
$existing->setExposurePolicy(FieldExposurePolicy::PRIVATE->value);
$this->expectException(InvalidArgumentException::class);
- $this->expectExceptionMessage('field_key cannot be changed');
+ $this->expectExceptionMessage('"field_key" cannot be changed');
$this->service->update($existing, [
'field_key' => 'cpf_new',
@@ -150,7 +150,7 @@ public function testUpdateRejectsTypeChangeWhenValuesExist(): void {
->willReturn(true);
$this->expectException(InvalidArgumentException::class);
- $this->expectExceptionMessage('type cannot be changed after values exist');
+ $this->expectExceptionMessage('Type cannot be changed after values exist');
$this->service->update($existing, [
'label' => 'CPF',