Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIO-8389 Update package.json with core changes #5623

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d44c1b9
Updated jsdocs for addMessages
ZenMasterJacob20011 May 23, 2024
897529c
Added apiKey error to translations
ZenMasterJacob20011 May 23, 2024
77144cc
setCustomValidity translates api key errors, removed unncessary error…
ZenMasterJacob20011 May 23, 2024
ae40c77
tests for api key error and translation
ZenMasterJacob20011 May 24, 2024
3476921
Ran test:updateRenders to add uniqueApiKeysTranslation.html files to …
ZenMasterJacob20011 May 24, 2024
1d1490d
[Snyk] Upgrade dompurify from 3.1.0 to 3.1.1 (#5605)
heather-formio May 24, 2024
c21885d
FIO-7195: Fixes an issue where Select, Radio and SelectBoxes componen…
alexandraRamanenka May 27, 2024
fd05635
FIO-8302 Fixed issue with wizard api key overriding window.property o…
ZenMasterJacob20011 May 27, 2024
aa31247
Recaptcha now requires type of event to be selected (#5595)
ZenMasterJacob20011 May 27, 2024
2f14fbf
Update Changelog.md
TanyaGashtold May 27, 2024
e4e42ba
FIO-8234: Fixes an issue where Select with Resource data source rende…
alexandraRamanenka May 29, 2024
5df7842
Update Changelog.md
TanyaGashtold May 29, 2024
5038ad4
Merge pull request #5613 from formio/FIO-8366-API-Key-is-not-unique-t…
brendanbond May 30, 2024
b12e8f5
Update Changelog.md
lane-formio May 30, 2024
493bed9
FIO-8389 Update package.json with core changes
lane-formio May 31, 2024
07d0300
Add yarn.lock to FIO-8389
lane-formio May 31, 2024
25fff14
Merge remote-tracking branch 'origin/master' into FIO-8389-update-pac…
lane-formio May 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,12 @@ Formio.createForm(document.getElementById('formio'), 'https://examples.form.io/e
- FIO-7595: fixed incorrect value for conditionally hidden Checkbox
- FIO-8342: fixed triggering saveDraft after submitting the form
- FIO-8240: fixed skipDraftRestore effect for the nested Forms
- FIO-8360 fixed submission state for nested form

- FIO-8360 fixed submission state for nested form
- FIO-7195: Fixes an issue where Select, Radio and SelectBoxes components with URL DataSource show values instead of labels in modal preview
- FIO-8302: Fixed issue with wizard api key overriding window.property objects
- FIO-8326: Recaptcha now requires type of event to be selected
- FIO-8234: Fixes an issue where Select with Resource data source renders values instead of labels in the read only mode
- FIO-8366: API key is not unique translation

## 5.0.0-rc.37
### Fixed
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"dependencies": {
"@formio/bootstrap": "^3.0.0-rc.22",
"@formio/choices.js": "^10.2.1",
"@formio/core": "^2.1.0-dev.tt.2",
"@formio/core": "2.0.0-dev.98.36bb01e",
"@formio/text-mask-addons": "^3.8.0-formio.2",
"@formio/vanilla-text-mask": "^5.1.1-formio.1",
"abortcontroller-polyfill": "^1.7.5",
Expand All @@ -89,7 +89,7 @@
"core-js": "^3.37.0",
"dialog-polyfill": "^0.5.6",
"dom-autoscroller": "^2.3.4",
"dompurify": "^3.1.0",
"dompurify": "^3.1.1",
"downloadjs": "^1.4.7",
"dragula": "^3.7.3",
"eventemitter3": "^5.0.1",
Expand Down
66 changes: 64 additions & 2 deletions src/Webform.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
formWithCollapsedPanel,
formWithCustomFormatDate,
tooltipActivateCheckbox,
formWithObjectValueSelect
formWithObjectValueSelect,
} from '../test/formtest';
import UpdateErrorClassesWidgets from '../test/forms/updateErrorClasses-widgets';
import nestedModalWizard from '../test/forms/nestedModalWizard';
Expand Down Expand Up @@ -78,7 +78,9 @@ import formWithDeeplyNestedConditionalComps from '../test/forms/formWithDeeplyNe
import formWithValidation from '../test/forms/formWithValidation';
import formWithNotAllowedTags from '../test/forms/formWithNotAllowedTags';
import formWithValidateWhenHidden from '../test/forms/formWithValidateWhenHidden';
import formWithSelectRadioUrlDataSource from '../test/forms/selectRadioUrlDataSource';
const SpySanitize = sinon.spy(FormioUtils, 'sanitize');

global.requestAnimationFrame = (cb) => cb();
global.cancelAnimationFrame = () => {};

Expand Down Expand Up @@ -1270,7 +1272,7 @@ describe('Webform tests', function() {
.catch((err) => done(err));
});

it('Should show validation errors and update validation errors list when opening and editing edit grid rows in draft modal mode after pushing submit btn', function(done) {
it('Should show validation errors and update validation errors list when opening and editing edit grid rows in draft modal mode after pushing submit btn',function(done) {
const formElement = document.createElement('div');
const formWithDraftModals = new Webform(formElement, { sanitize: true });

Expand Down Expand Up @@ -4847,6 +4849,66 @@ describe('Webform tests', function() {
});
});

it('Should render labels for Select, Radio and selectBoxes components when Data Source is URL', (done) => {
const element = document.createElement('div');
const form = new Webform(element);
const originalMakeRequest = Formio.makeRequest;

Formio.makeRequest = function() {
return new Promise(resolve => {
const values = [
{ name : 'Alabama', abbreviation : 'AL' },
{ name : 'Alaska', abbreviation: 'AK' },
{ name: 'American Samoa', abbreviation: 'AS' }
];
resolve(values);
});
};

form.setForm(formWithSelectRadioUrlDataSource).then(() => {
const selectBoxes = form.getComponent('selectBoxes');
const select = form.getComponent('select');
const radio = form.getComponent('radio');

selectBoxes.componentModal.openModal();
select.componentModal.openModal();
radio.componentModal.openModal();

setTimeout(() => {
form.setSubmission({
data: {
selectBoxes: { AL: false, AK: true, AS: true },
select: 'AL',
radio: 'AL',
}
});

setTimeout(() => {
selectBoxes.componentModal.closeModal();
select.componentModal.closeModal();
radio.componentModal.closeModal();

setTimeout(() => {
const previewSelectBoxes = selectBoxes.element.querySelector('[ref="openModal"]');
const previewSelect = select.element.querySelector('[ref="openModal"]');
const previewRadio = radio.element.querySelector('[ref="openModal"]');

assert.equal(previewSelectBoxes.innerHTML, '\n <span>Alaska</span>, <span>American Samoa</span>\n', 'Should show labels as a selected value' +
' for SelectBoxes component');
assert.equal(previewRadio.innerHTML, '\n <span>Alabama</span>\n', 'Should show label as a selected value' +
' for Radio component');
assert.equal(previewSelect.innerHTML, '\n <span>Alabama</span>\n', 'Should show label as a selected value' +
' for Select component');

Formio.makeRequest = originalMakeRequest;
done();
}, 300);
}, 300);
}, 300);
})
.catch((err) => done(err));
});

for (const formTest of FormTests) {
const useDoneInsteadOfPromise = formTest.useDone;

Expand Down
6 changes: 1 addition & 5 deletions src/WebformBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -1285,14 +1285,10 @@ export default class WebformBuilder extends Component {

this.webform.everyComponent((comp) => {
const path = comp.path;
const errors = comp.visibleErrors || [];
if (repeatablePaths.includes(path)) {
comp.setCustomValidity(`API Key is not unique: ${comp.key}`);
comp.setCustomValidity(this.t('apiKey', { key: comp.key }));
hasInvalidComponents = true;
}
else if (errors.length && errors[0].message?.startsWith('API Key is not unique')) {
comp.setCustomValidity('');
}
});

this.emit('builderFormValidityChange', hasInvalidComponents);
Expand Down
23 changes: 22 additions & 1 deletion src/WebformBuilder.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Harness from '../test/harness';
import WebformBuilder from './WebformBuilder';
import Builders from './builders';
import { Formio } from './Formio';
import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCase } from '../test/formtest';
import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCase, uniqueApiKeysTranslation } from '../test/formtest';
import sameApiKeysLayoutComps from '../test/forms/sameApiKeysLayoutComps';
import testApiKeysUniquifying from '../test/forms/testApiKeysUniquifying';
import formBasedOnWizard from '../test/forms/formBasedOnWizard';
Expand Down Expand Up @@ -32,6 +32,27 @@ describe('WebformBuilder tests', function() {
done();
}, 500);
});
it('Should show API Key is not unique: {{key}} error when api keys are the same', (done) => {
const builder = Harness.getBuilder();
builder.i18next.currentLanguage = { apiKey: 'translated api key error {{key}}' };
builder.webform.setForm(uniqueApiKeysTranslation).then(()=>{
builder.highlightInvalidComponents();
const component = builder.webform.getComponent(['textField']);
assert.equal(component.visibleErrors.length, 1);
done();
}).catch(done);
});

it('Should show translated api key error {{key}} when apiKey is overridden in i18next translations', (done) => {
const builder = Harness.getBuilder();
builder.i18next.currentLanguage = { apiKey: 'translated api key error {{key}}' };
builder.webform.setForm(uniqueApiKeysTranslation).then(() => {
builder.highlightInvalidComponents();
const component = builder.webform.getComponent(['textField']);
assert.equal(component.visibleErrors[0].message,'translated api key error textField');
done();
}).catch(done);
});

it('Should not show unique API error when components with same keys are inside and outside of the Data component', (done) => {
const builder = Harness.getBuilder();
Expand Down
9 changes: 4 additions & 5 deletions src/components/_classes/component/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { processOne, processOneSync, validateProcessInfo } from '@formio/core/pr
import { Formio } from '../../../Formio';
import * as FormioUtils from '../../../utils/utils';
import {
fastCloneDeep, boolValue, getComponentPath, isInsideScopingComponent, currentTimezone
fastCloneDeep, boolValue, getComponentPath, isInsideScopingComponent, currentTimezone, getScriptPlugin
} from '../../../utils/utils';
import Element from '../../../Element';
import ComponentModal from '../componentModal/ComponentModal';
Expand Down Expand Up @@ -2133,8 +2133,7 @@ export default class Component extends Element {
/**
* Add a new input error to this element.
*
* @param message
* @param dirty
* @param {{level: string, message: string}[]} messages
*/
addMessages(messages) {
if (!messages) {
Expand Down Expand Up @@ -3750,7 +3749,7 @@ Component.requireLibrary = function(name, property, src, polling) {
}.bind(Component.externalLibraries[name]);
}
// See if the plugin already exists.
const plugin = _.get(window, property);
const plugin = getScriptPlugin(property);
if (plugin) {
Component.externalLibraries[name].resolve(plugin);
}
Expand Down Expand Up @@ -3795,7 +3794,7 @@ Component.requireLibrary = function(name, property, src, polling) {
// if no callback is provided, then check periodically for the script.
if (polling) {
setTimeout(function checkLibrary() {
const plugin = _.get(window, property);
const plugin = getScriptPlugin(property);
if (plugin) {
Component.externalLibraries[name].resolve(plugin);
}
Expand Down
9 changes: 6 additions & 3 deletions src/components/radio/Radio.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,18 +261,21 @@ export default class RadioComponent extends ListComponent {
return false;
}

getValueAsString(value) {
getValueAsString(value, options = {}) {
if (_.isObject(value)) {
value = JSON.stringify(value);
}
else if (!_.isString(value)) {
value = _.toString(value);
}
if (this.component.dataSrc !== 'values') {

const isModalPreviewWithUrlDataSource = options.modalPreview && this.component.dataSrc === 'url';
if (this.component.dataSrc !== 'values' && !isModalPreviewWithUrlDataSource) {
return value;
}

const option = _.find(this.component.values, (v) => v.value === value);
const values = isModalPreviewWithUrlDataSource ? this.loadedOptions : this.component.values;
const option = _.find(values, (v) => v.value === value);

if (!value) {
return _.get(option, 'label', '');
Expand Down
3 changes: 3 additions & 0 deletions src/components/recaptcha/editForm/ReCaptcha.edit.display.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export default [
value: 'buttonClick'
}
],
validate: {
required: true
},
weight: 650
},
{
Expand Down
8 changes: 7 additions & 1 deletion src/components/select/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,10 @@ export default class SelectComponent extends ListComponent {

selectValueAndLabel(data) {
const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));
const readOnlyResourceLabelData = this.options.readOnly && (this.component.dataSrc === 'resource' || this.component.dataSrc === 'url') && this.selectData;
return {
value,
label: this.itemTemplate((this.isEntireObjectDisplay() && !_.isObject(data.data)) ? { data: data } : data, value)
label: this.itemTemplate((this.isEntireObjectDisplay() && !_.isObject(data.data)) ? { data: data } : readOnlyResourceLabelData || data, value)
};
}

Expand Down Expand Up @@ -1752,6 +1753,11 @@ export default class SelectComponent extends ListComponent {

asString(value, options = {}) {
value = value ?? this.getValue();

if (options.modalPreview && this.selectData) {
const { label } = this.selectValueAndLabel(value);
return label;
}
//need to convert values to strings to be able to compare values with available options that are strings
const convertToString = (data, valueProperty) => {
if (valueProperty) {
Expand Down
65 changes: 65 additions & 0 deletions src/components/select/Select.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
comp20,
comp21,
comp22,
comp23,
} from './fixtures';

// eslint-disable-next-line max-statements
Expand Down Expand Up @@ -1276,5 +1277,69 @@ describe('Select Component with Entire Object Value Property', () => {
done();
});
});

it('Should render label for Select components when Data Source is Resource in read only mode', (done) => {
const element = document.createElement('div');
Formio.createForm(element, comp23, { readOnly: true }).then((form) => {
const select = form.getComponent('select');
form.setSubmission({
metadata: {
selectData: {
select: {
data: {
textField1: 'A',
},
},
},
timezone: 'Europe/Kiev',
offset: 180,
origin: 'http://localhost:3001',
referrer: '',
browserName: 'Netscape',
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
pathName: '/',
onLine: true,
headers: {
host: 'qvecgdgwpwujbpi.localhost:3000',
connection: 'keep-alive',
'content-length': '457',
'sec-ch-ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
accept: 'application/json',
'content-type': 'application/json',
'sec-ch-ua-mobile': '?0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
'sec-ch-ua-platform': '"Windows"',
origin: 'http://localhost:3001',
'sec-fetch-site': 'cross-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
referer: 'http://localhost:3001/',
'accept-encoding': 'gzip, deflate, br, zstd',
'accept-language': 'en-US,en;q=0.9,ru-RU;q=0.8,ru;q=0.7',
},
},
data: {
select: 1,
select1: {
textField1: 'A',
textField2: '1',
submit: true,
},
submit: true,
},
state: 'submitted',
});

setTimeout(() => {
const previewSelect = select.element.querySelector('[aria-selected="true"] span');

assert.equal(previewSelect.innerHTML, 'A', 'Should show label as a selected value' +
' for Select component');

done();
}, 300);
})
.catch((err) => done(err));
});
});

38 changes: 38 additions & 0 deletions src/components/select/fixtures/comp23.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export default {
title: 'FIO-8234',
name: 'fio8234',
path: 'fio8234',
type: 'form',
display: 'form',
components: [
{
label: 'Select',
widget: 'choicesjs',
tableView: true,
dataSrc: 'resource',
data: {
resource: '665446284c9b0163c3e0c7e6',
},
template: '<span>{{ item.data.textField1 }}</span>',
validate: {
select: false,
},
key: 'select',
type: 'select',
searchField: 'data.textField2__regex',
input: true,
noRefreshOnScroll: false,
addResource: false,
reference: false,
valueProperty: 'data.textField2',
},
{
type: 'button',
label: 'Submit',
key: 'submit',
disableOnInvalid: true,
input: true,
tableView: false,
},
],
};
Loading
Loading