Skip to content

Commit 25f6980

Browse files
authored
Merge pull request #136 from NGO-Algorithm-Audit/feature/structural_edits
Feature/structural edits
2 parents 9114121 + 6312a08 commit 25f6980

File tree

4 files changed

+121
-39
lines changed

4 files changed

+121
-39
lines changed

content/nederlands/technical-tools/documentation/classification-quick-scan.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ dynamic_form_engine:
155155
value: yes1
156156
- identifier: output2
157157
title: >-
158-
Uw toepassing is op basis van uw antwoorden waarschijnlijk een
159-
AI-systeem.
158+
Uw toepassing is op basis van uw antwoorden waarschijnlijk een AI
159+
systeem.
160160
content: |
161161
Een AI Act risk assessment moet worden ingevuld.
162162
use_card_style: false
@@ -170,12 +170,13 @@ dynamic_form_engine:
170170
value: option6
171171
compareSign: '!='
172172
- visible_when_and:
173+
- identifier: q2
174+
value: '*'
175+
compareSign: '=='
173176
- identifier: q3
174177
value: yes3
175178
compareSign: '=='
176-
- identifier: q2
177-
value: option6
178-
compareSign: '!='
179+
isOutput: false
179180
- identifier: text1
180181
title: Volgende stap
181182
content: >
@@ -195,15 +196,15 @@ dynamic_form_engine:
195196
value: option6
196197
compareSign: '!='
197198
- visible_when_and:
198-
- identifier: q3
199+
- identifier: q1
199200
value: 'no'
200-
compareSign: '!='
201+
compareSign: '=='
202+
- identifier: q2
203+
value: '*'
204+
compareSign: '=='
201205
- identifier: q3
202206
value: yes1
203207
compareSign: '!='
204-
- identifier: q2
205-
value: option6
206-
compareSign: '!='
207208
- identifier: q4
208209
title: Rol in beslissingproces
209210
content: >
@@ -239,15 +240,15 @@ dynamic_form_engine:
239240
value: option6
240241
compareSign: '!='
241242
- visible_when_and:
242-
- identifier: q3
243+
- identifier: q1
243244
value: 'no'
244-
compareSign: '!='
245+
compareSign: '=='
246+
- identifier: q2
247+
value: '*'
248+
compareSign: '=='
245249
- identifier: q3
246250
value: yes1
247251
compareSign: '!='
248-
- identifier: q2
249-
value: option6
250-
compareSign: '!='
251252
- identifier: q5
252253
title: Soort beslissing
253254
content: >
@@ -274,7 +275,7 @@ dynamic_form_engine:
274275
- id: option4
275276
value: option4
276277
title: >-
277-
Beslissing over aanvragen en verzoeken zonder directe
278+
Beslissing over aanvraag of verzoek zonder directe
278279
financiële gevolgen
279280
content: ''
280281
- id: option5
@@ -387,6 +388,14 @@ dynamic_form_engine:
387388
content: ''
388389
type: radio
389390
visible_when_or:
391+
- visible_when_and:
392+
- identifier: q5
393+
value: option7
394+
compareSign: '=='
395+
- visible_when_and:
396+
- identifier: q5
397+
value: option6
398+
compareSign: '=='
390399
- visible_when_and:
391400
- identifier: q5
392401
value: option5
@@ -416,7 +425,7 @@ dynamic_form_engine:
416425
value: option5
417426
- identifier: output1
418427
title: >-
419-
Uw toepassing is op basis van uw antwoorden geen AI-systeem of
428+
Uw toepassing is op basis van uw antwoorden geen AI systeem of
420429
impactvol algoritme.
421430
content: >
422431
Het zou kunnen dat contact wordt opgenomen met het primair
@@ -433,9 +442,7 @@ dynamic_form_engine:
433442
- visible_when_and:
434443
- identifier: q1
435444
value: 'no'
436-
- identifier: q3
437-
value: 'no'
438-
- visible_when_and:
445+
compareSign: '!='
439446
- identifier: q2
440447
value: option6
441448
- visible_when_and:
@@ -447,6 +454,7 @@ dynamic_form_engine:
447454
- visible_when_and:
448455
- identifier: q7
449456
value: option4
457+
isOutput: true
450458
- identifier: output3
451459
title: >-
452460
Uw toepassing is op basis van uw antwoorden waarschijnlijk een
@@ -467,9 +475,13 @@ dynamic_form_engine:
467475
- visible_when_and:
468476
- identifier: q7
469477
value: option5
478+
isOutput: true
470479
complete_form_options:
471-
type: submit
480+
type: print
472481
button_text: Save as pdf
482+
button_text_csv: Save as csv
483+
file_name: classification_output
484+
onlyShowWithOutput: true
473485
form1:
474486
title: Intake
475487
button_text: Meld aan

layouts/shortcodes/dynamic_form_engine.html

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ <h3>{{.title}}</h3>
4141
{{ end }}
4242

4343

44-
<div class="score-card__question" {{if $visibilityCondition}}data-show-when="{{$visibilityCondition}}" {{end}}>
44+
<div class="score-card__question" {{if $visibilityCondition}}data-show-when="{{$visibilityCondition}}" {{end}}
45+
{{if .isOutput }} data-is-output="true" {{end}}>
4546
<h4>
46-
{{ .title }}
47+
<div class="csv-title d-inline">{{ .title }}</div>
4748
{{if .required}}*{{end}}
4849
{{ if .tooltip }}
4950
<button class="remove-on-pdf information-button mt-0" data-toggle="tooltip" data-placement="right"
@@ -53,7 +54,7 @@ <h4>
5354
{{ end }}
5455
</h4>
5556

56-
<p>
57+
<p class="csv-explanation">
5758
{{ .content | markdownify }}
5859
</p>
5960

@@ -98,8 +99,8 @@ <h6 class="d-inline mb-0 ml-2">{{ .title | markdownify }}</h6>
9899
{{ range .options }}
99100
<div class="col-md-4 col-sm-12">
100101
<label>
101-
<input type="radio" id="{{$input.identifier}}_{{.value}}" name={{$input.identifier}} class="card-input-element" value={{.value}} {{if
102-
$input.required}} required {{end}} />
102+
<input type="radio" id="{{$input.identifier}}_{{.value}}" name={{$input.identifier}}
103+
class="card-input-element" value={{.value}} {{if $input.required}} required {{end}} />
103104
<div class="card card-input">
104105
<div class="card-body {{ if not .content }}d-flex justify-content-center{{end}}">
105106
<h6 class="card-title">{{.title}}</h6>
@@ -115,9 +116,9 @@ <h6 class="card-title">{{.title}}</h6>
115116
{{ range .options }}
116117
<div class="col-12">
117118
<label class="my-2">
118-
<input type="radio" id="{{$input.identifier}}_{{.value}}" name={{$input.identifier}} class="" value={{.value}} {{if
119-
$input.required}} required {{end}} />
120-
<h6 class="d-inline ml-1" >{{.title}}</h6>
119+
<input type="radio" id="{{$input.identifier}}_{{.value}}" name={{$input.identifier}} class=""
120+
value={{.value}} {{if $input.required}} required {{end}} />
121+
<h6 class="d-inline ml-1">{{.title}}</h6>
121122
{{ if .content }}
122123
<p class="mb-0">
123124
{{.content | markdownify}}
@@ -144,7 +145,7 @@ <h6 class="d-inline ml-1" >{{.title}}</h6>
144145

145146
{{ end }}
146147

147-
<div class="row mt-5">
148+
<div class="row mt-5 formSubmissionSection">
148149
<div class="col-xl col-sm-12">
149150

150151
{{ with .complete_form_options }}
@@ -157,6 +158,9 @@ <h6 class="d-inline ml-1" >{{.title}}</h6>
157158
<button id="score-card-print-button" class="btn btn-primary remove-on-pdf"><i class="fas fa-print"></i>
158159
{{ .button_text | markdownify }}
159160
</button>
161+
<button id="score-card-csv-button" class="btn btn-primary remove-on-pdf"><i class="fas fa-file-excel"></i>
162+
{{ .button_text_csv | markdownify }}
163+
</button>
160164
</div>
161165
{{ end }}
162166
{{ end }}
@@ -175,9 +179,13 @@ <h6 class="d-inline ml-1" >{{.title}}</h6>
175179
}
176180

177181
var calculateVisibleFields = function () {
182+
183+
{{ if .complete_form_options.onlyShowWithOutput }}
184+
$('#{{.id}} .formSubmissionSection').addClass('d-none');
185+
{{ end }}
178186
// this is what the data attribute looks like: data-show-when=="||&&data1==medium&&data2=medium||&&data1==low"
179187
// This field should be hidden when no input is selected, and shown if either data 1 and data 2 are medium or data 1 is low.
180-
$('.score-card__question').each(function () {
188+
$('#{{.id}} .score-card__question').each(function () {
181189
const showWhen = $(this).attr('data-show-when');
182190
// check if the attribute is there, otherwise always keep it as is.
183191
if (showWhen) {
@@ -203,14 +211,14 @@ <h6 class="d-inline ml-1" >{{.title}}</h6>
203211
}
204212

205213
// Check for radio button
206-
let input = document.querySelector(`.score-card__question:not(.d-none) input[name=${name}]:checked`);
214+
let input = document.querySelector(`#{{.id}} .score-card__question:not(.d-none) input[name=${name}]:checked`);
207215
// Check for checkbox
208216
if (!input) {
209-
input = document.querySelector(`.score-card__question:not(.d-none) input[id=${name}]:checked`);
217+
input = document.querySelector(`#{{.id}} .score-card__question:not(.d-none) input[id=${name}]:checked`);
210218
}
211-
if (!input
212-
|| (checkForEquals && !valuesAreEqual(input.value, value))
213-
|| (checkForUnequal && valuesAreEqual(input.value, value))) {
219+
if (!input
220+
|| (checkForEquals && !valuesAreEqual(input.value, value))
221+
|| (checkForUnequal && valuesAreEqual(input.value, value))) {
214222
andShow = false;
215223
}
216224
});
@@ -226,6 +234,10 @@ <h6 class="d-inline ml-1" >{{.title}}</h6>
226234
if ($(this).find('textarea').attr('data-required')) {
227235
$(this).find('textarea').prop('required', true);
228236
}
237+
if ($(this).attr('data-is-output')) {
238+
console.log('showing form submission section');
239+
$('#{{.id}} .formSubmissionSection').removeClass('d-none');
240+
}
229241
} else {
230242
$(this).addClass("d-none");
231243
if ($(this).find('input').attr('data-required')) {
@@ -256,7 +268,7 @@ <h6 class="d-inline ml-1" >{{.title}}</h6>
256268
})
257269

258270

259-
$('#score-card-print-button').click(function (event) {
271+
$('#{{.id}} #score-card-print-button').click(function (event) {
260272
event.preventDefault();
261273
window.html2canvas = html2canvas;
262274
var element = document.getElementById("{{.id}}");
@@ -280,6 +292,43 @@ <h6 class="d-inline ml-1" >{{.title}}</h6>
280292

281293
});
282294
});
295+
296+
$('#{{.id}} #score-card-csv-button').click(function (event) {
297+
event.preventDefault();
298+
const csv = [];
299+
csv.push(['Title/Question', 'Explanation', 'Input', 'Input explanation']);
300+
$('#{{.id}} .score-card__question:not(.d-none)').each(function () {
301+
const question = $(this);
302+
let title = question.find('.csv-title').text();
303+
let explanation = question.find('.csv-explanation').text();
304+
let input = question.find('input:checked').siblings('h6').text() || question.find('input').val() || question.find('textarea').val();
305+
let inputExplanation = question.find('input:checked').siblings('p').text() || question.find('input').siblings('p').text() || question.find('textarea').siblings('p').text();
306+
//exception for checkboxes
307+
if (question.find('input:checked').length > 1) {
308+
input = question.find('input:checked').map(function () {
309+
return $(this).siblings('h6').text();
310+
}).get().join('; ');
311+
312+
inputExplanation = question.find('input:checked').map(function () {
313+
return $(this).siblings('p').text();
314+
}).get().join('; ');
315+
}
316+
title = title?.replaceAll(',', ' ').replaceAll('\r\n', ' ')?.replaceAll('\n', ' ')?.replaceAll(' ', ' ')?.trim();
317+
explanation = explanation?.replaceAll(',', ' ').replaceAll('\r\n', ' ')?.replaceAll('\n', ' ')?.replaceAll(' ', ' ')?.trim();
318+
input = input?.replaceAll(',', ' ').replaceAll('\r\n', ' ')?.replaceAll('\n', ' ')?.replaceAll(' ', ' ')?.trim();
319+
inputExplanation = inputExplanation?.replaceAll(',', ' ').replaceAll('\r\n', ' ')?.replaceAll('\n', ' ')?.replaceAll(' ', ' ')?.trim();
320+
csv.push([title ?? '', explanation ?? '', input ?? '', inputExplanation ?? '']);
321+
});
322+
323+
const csvContent = "data:text/csv;charset=utf-8," + csv.map(e => e.join(",")).join("\n");
324+
const encodedUri = encodeURI(csvContent);
325+
const link = document.createElement("a");
326+
link.setAttribute("href", encodedUri);
327+
link.setAttribute("download", "{{.complete_form_options.file_name}}.csv");
328+
document.body.appendChild(link); // Required for FF
329+
330+
link.click(); // This will download the data file named "my_data.csv".
331+
})
283332
});
284333
</script>
285334

tina/collections/shared/page/building_blocks.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,11 @@ const building_blocks: TinaField[] = [
340340
list: true,
341341
ui: {
342342
itemProps: (item) => {
343-
return { label: `${item?.identifier}=${item?.value}` };
343+
return {
344+
label: `${item?.identifier}${
345+
item?.compareSign ?? "=="
346+
}${item?.value}`,
347+
};
344348
},
345349
},
346350
fields: [
@@ -381,6 +385,13 @@ const building_blocks: TinaField[] = [
381385
},
382386
],
383387
},
388+
{
389+
type: "boolean",
390+
name: "isOutput",
391+
label: "Is output",
392+
description:
393+
"Can be used to hide the save button, the button will show when an output field is shown.",
394+
},
384395
],
385396
},
386397
],
@@ -418,6 +429,11 @@ const building_blocks: TinaField[] = [
418429
description: "",
419430
required: true,
420431
},
432+
{
433+
name: "button_text_csv",
434+
label: "Button text for CSV download",
435+
type: "string",
436+
},
421437
{
422438
name: "backend_link",
423439
label: "Back end link (Required if you want to submit the data)",
@@ -431,6 +447,11 @@ const building_blocks: TinaField[] = [
431447
type: "string",
432448
required: false,
433449
},
450+
{
451+
name: "onlyShowWithOutput",
452+
label: "Only show when an output field is shown",
453+
type: "boolean",
454+
},
434455
],
435456
},
436457
],

tina/tina-lock.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)