workflows: include varname for field options with duplicated labels (#60315) #1050

Merged
fpeters merged 1 commits from wip/60315-field-select-varname into main 2024-01-26 08:46:24 +01:00
4 changed files with 107 additions and 8 deletions

View File

@ -2353,6 +2353,29 @@ def test_workflows_backoffice_fields_backlinks_to_actions(pub):
}
def test_workflows_backoffice_fields_with_same_label(pub):
create_superuser(pub)
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow)
workflow.backoffice_fields_formdef.fields = [
fields.StringField(id='bo1', varname='bo1', label='variable'),
fields.StringField(id='bo2', varname='bo2', label='variable'),
]
status = workflow.add_status(name='baz')
action1 = status.add_action('set-backoffice-fields')
workflow.store()
app = login(get_app(pub))
resp = app.get(action1.get_admin_url())
assert resp.form['fields$element0$field_id'].options == [
('', False, ''),
('bo1', False, 'variable - Text (line) (bo1)'),
('bo2', False, 'variable - Text (line) (bo2)'),
]
def test_workflows_fields_labels(pub):
create_superuser(pub)
@ -3141,11 +3164,62 @@ def test_workflows_create_formdata_deleted_field(pub):
resp = app.get('/backoffice/workflows/%s/status/%s/items/_create_formdata/' % (wf.id, st2.id))
assert resp.form['mappings$element1$field_id'].options == [
('', False, '---'),
('1', False, 'string2'),
('1', False, 'string2 - Text (line)'),
('0', True, '❗ string1 (deleted field)'),
]
def test_workflows_create_formdata_fields_with_same_label(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'Test Block'
block.fields = [fields.StringField(id='123', required=True, label='Test')]
block.store()
FormDef.wipe()
target_formdef = FormDef()
target_formdef.name = 'target form'
target_formdef.enable_tracking_codes = True
target_formdef.fields = [
fields.StringField(id='0', label='string1', varname='foo'),
fields.StringField(id='1', label='string1', varname='bar'),
fields.BlockField(id='2', label='block1', varname='foo2', block_slug=block.slug),
fields.BlockField(id='3', label='block1', varname='bar2', block_slug=block.slug),
fields.BlockField(id='4', label='block2', varname='xxx', block_slug=block.slug),
]
target_formdef.store()
Workflow.wipe()
wf = Workflow(name='create-formdata')
st2 = wf.add_status('Resubmit')
create_formdata = st2.add_action('create_formdata', id='_create_formdata')
create_formdata.formdef_slug = target_formdef.url_name
create_formdata.mappings = [
Mapping(field_id='0', expression='{{ "a" }}'),
Mapping(field_id='1', expression='{{ "b" }}'),
]
wf.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/%s/status/%s/items/_create_formdata/' % (wf.id, st2.id))
assert resp.form['mappings$element1$field_id'].options == [
('', False, '---'),
('0', False, 'string1 - Text (line) (foo)'),
('1', True, 'string1 - Text (line) (bar)'),
('2', False, 'block1 - Field Block (Test Block) (foo2)'),
('2$123', False, 'block1 (foo2) - Test - Text (line)'),
('3', False, 'block1 - Field Block (Test Block) (bar2)'),
('3$123', False, 'block1 (bar2) - Test - Text (line)'),
('4', False, 'block2 - Field Block (Test Block)'),
('4$123', False, 'block2 - Test - Text (line)'),
]
def test_workflows_create_carddata_action_config(pub):
create_superuser(pub)

View File

@ -1262,10 +1262,10 @@ def test_edit_carddata_partial_block_field(pub, admin_user):
resp = login(get_app(pub), username='admin', password='admin').get(edit.get_admin_url())
assert resp.form['mappings$element1$field_id'].options == [
('', False, '---'),
('0', False, 'foo'),
('1', False, 'block field'),
('1$123', True, 'block field - Test'),
('1$234', False, 'block field - Test2'),
('0', False, 'foo - Text (line)'),
('1', False, 'block field - Field Block (foobar)'),
('1$123', True, 'block field - Test - Text (line)'),
('1$234', False, 'block field - Test2 - Text (line)'),
]
resp = resp.form.submit('submit')

View File

@ -40,11 +40,24 @@ class SetBackofficeFieldRowWidget(CompositeWidget):
if not value:
value = {}
label_counters = {}
for field in workflow.get_backoffice_fields():
if not issubclass(field.__class__, WidgetField):
continue
label = f'{field.label} - {field.get_type_label()}'
label_counters.setdefault(label, 0)
label_counters[label] += 1
repeated_labels = {x for x, y in label_counters.items() if y > 1}
fields = [('', '', '')]
for field in workflow.get_backoffice_fields():
if not issubclass(field.__class__, WidgetField):
continue
fields.append((field.id, f'{field.label} - {field.get_type_label()}', field.id))
label = f'{field.label} - {field.get_type_label()}'
if label in repeated_labels and field.varname:
label = f'{field.label} - {field.get_type_label()} ({field.varname})'

Ajout de l’identifiant uniquement s’il a des doublons sur les libellés, ça devrait laisser l’interface identique à l’actuelle la plupart du temps.

Ajout de l’identifiant uniquement s’il a des doublons sur les libellés, ça devrait laisser l’interface identique à l’actuelle la plupart du temps.
fields.append((field.id, label, field.id))
self.add(
SingleSelectWidget,
name='field_id',

View File

@ -74,15 +74,27 @@ class MappingWidget(CompositeWidget):
)
def _fields_to_options(self, formdef):
label_counters = {}
for field in formdef.get_widget_fields():
label = f'{field.label} - {field.get_type_label()}'
label_counters.setdefault(label, 0)
label_counters[label] += 1
repeated_labels = {x for x, y in label_counters.items() if y > 1}
options = [(None, '---', '')]
for field in formdef.get_widget_fields():
options.append((field.id, field.label, str(field.id)))
label = f'{field.label} - {field.get_type_label()}'

Dans les actions de création de demande/fiche, on n’avait pas encore fait la modification pour afficher le type de champ, c’est intégré ici.

Dans les actions de création de demande/fiche, on n’avait pas encore fait la modification pour afficher le type de champ, c’est intégré ici.
block_label = field.label
if label in repeated_labels and field.varname:
label = f'{field.label} - {field.get_type_label()} ({field.varname})'
block_label = f'{field.label} ({field.varname})' # do not repeat block type

Puis on fait la même affaire, s’il y a des doublons, ajouter l’identifiant.

Puis on fait la même affaire, s’il y a des doublons, ajouter l’identifiant.
options.append((field.id, label, str(field.id)))
if field.key == 'block':
for subfield in field.block.get_widget_fields():
options.append(
(
f'{field.id}${subfield.id}',
f'{field.label} - {subfield.label}',
f'{block_label} - {subfield.label} - {subfield.get_type_label()}',

Pour les blocs j’ai aussi expérimenté avec un <optgroup> mais le résultat n’était pas terrible, donc je laisse juste ainsi.

Pour les blocs j’ai aussi expérimenté avec un `<optgroup>` mais le résultat n’était pas terrible, donc je laisse juste ainsi.
f'{field.id}${subfield.id}',
)
)