diff --git a/app/javascript/components/visual-settings-form/index.jsx b/app/javascript/components/visual-settings-form/index.jsx index 39e40c069f8..3785508b0da 100644 --- a/app/javascript/components/visual-settings-form/index.jsx +++ b/app/javascript/components/visual-settings-form/index.jsx @@ -5,21 +5,36 @@ import MiqFormRenderer from '@@ddf'; import createSchema from './visual-settings-form.schema'; const VisualSettingsForm = ({ recordId }) => { - const [{ initialValues, timezoneOptions, isLoading }, setState] = useState({ isLoading: true }); + const [{ + initialValues, shortcuts, timezoneOptions, isLoading, + }, setState] = useState({ isLoading: true }); useEffect(() => { - API.get('/api').then(({ timezones }) => { - const timezoneOptions = []; - timezones.forEach((timezone) => { - timezoneOptions.push({ value: timezone.name, label: timezone.description }); + API.get('/api/shortcuts?expand=resources&attributes=description,url').then(({ resources }) => { + const shortcuts = []; + + resources.forEach((shortcut) => { + shortcuts.push({ value: shortcut.url, label: shortcut.description }); + }); + + return shortcuts; + }).then((shortcuts) => { + API.get('/api').then(({ timezones }) => { + const timezoneOptions = []; + + timezones.forEach((timezone) => { + timezoneOptions.push({ value: timezone.name, label: timezone.description }); + }); + + return timezoneOptions; + }).then((timezoneOptions) => { + API.get(`/api/users/${recordId}?attributes=settings`).then(({ settings }) => setState({ + initialValues: settings, + shortcuts, + timezoneOptions, + isLoading: false, + })); }); - return timezoneOptions; - }).then((timezoneOptions) => { - API.get(`/api/users/${recordId}?attributes=settings`).then(({ settings }) => setState({ - initialValues: settings, - timezoneOptions, - isLoading: false, - })); }); }, [recordId]); @@ -42,7 +57,7 @@ const VisualSettingsForm = ({ recordId }) => { } return ( ({ +const createSchema = (shortcuts, timezoneOptions) => ({ fields: [ { component: componentTypes.SUB_FORM, @@ -98,8 +98,8 @@ const createSchema = (timezoneOptions) => ({ id: 'display.startpage', label: __('Start Page'), isSearchable: true, - loadOptions: () => API.get('/api/shortcuts?expand=resources&attributes=description,url') - .then(({ resources }) => resources.map(({ url, description }) => ({ value: url, label: description }))), + simpleValue: true, + options: shortcuts, }, { component: componentTypes.SELECT, diff --git a/cypress/e2e/ui/settings.cy.js b/cypress/e2e/ui/settings.cy.js index 2d722669db2..419184a0c78 100644 --- a/cypress/e2e/ui/settings.cy.js +++ b/cypress/e2e/ui/settings.cy.js @@ -1,6 +1,37 @@ /* eslint-disable no-undef */ -describe('GTL', () => { +describe('Settings > My Settings', () => { beforeEach(() => { cy.login(); + cy.menu('Settings', 'My Settings'); + }); + + it('Saves the start page setting', () => { + cy.get('#display\\.startpage').then((value) => { + expect(value[0].value).to.be.oneOf(['', 'Overview / Dashboard']); + }); + cy.changeSelect('display\\.startpage', 'Overview / Utilization'); + cy.intercept('PATCH', '/api/users/*').as('settingsUpdate'); + cy.contains('button', 'Save').click(); + cy.wait('@settingsUpdate').its('response.statusCode').should('eq', 200); + + // Wait for page to load before clicking log out to prevent errors + cy.get('[name="general-subform"] > :nth-child(2) > .bx--select'); + cy.get('#menu_item_logout').click(); + cy.login(); + cy.url().should('include', '/utilization'); + + cy.menu('Settings', 'My Settings'); + cy.get('#display\\.startpage').then((value) => { + expect(value[0].value).to.equal('Overview / Utilization'); + }); + cy.changeSelect('display\\.startpage', 'Overview / Dashboard'); + cy.intercept('PATCH', '/api/users/*').as('settingsUpdate'); + cy.contains('button', 'Save').click(); + cy.wait('@settingsUpdate').its('response.statusCode').should('eq', 200); + + cy.get('[name="general-subform"] > :nth-child(2) > .bx--select'); + cy.get('#menu_item_logout').click(); + cy.login(); + cy.url().should('include', '/dashboard'); }); }); diff --git a/cypress/support/commands/select.js b/cypress/support/commands/select.js new file mode 100644 index 00000000000..2001e2b6471 --- /dev/null +++ b/cypress/support/commands/select.js @@ -0,0 +1,29 @@ +/* eslint-disable no-undef */ + +// selectId: String of the ID of the select element to interact with. +// optionToSelect: String of the option to select from the dropdown. +Cypress.Commands.add('changeSelect', (selectId, optionToSelect) => { + // First, get the select element and store its text + let selectElementText = ''; + cy.get(`#${selectId}`).then((selectElement) => { + // Get the currently displayed text in the select element + selectElementText = selectElement.text().trim(); + // Click to open the dropdown + cy.wrap(selectElement).click(); + }).then(() => { + // Now find the options and try to select the requested one + cy.get('.bx--list-box__menu-item__option').then((options) => { + const optionArray = Cypress.$.makeArray(options); + const match = optionArray.find((el) => el.innerText.trim() === optionToSelect); + + if (match) { + cy.wrap(match).click(); + } else { + // Include both the requested option and the select element's text in the error + cy.logAndThrowError( + `Could not find "${optionToSelect}" in select element with text "${selectElementText}"` + ); + } + }); + }); +}); diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index 1fec6ef1477..841e2f49d6d 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -50,6 +50,7 @@ import './commands/menu.js'; import './commands/stub_notifications.js'; import './commands/throttle_response.js'; import './commands/toolbar.js'; +import './commands/select.js'; // Assertions import './assertions/expect_alerts.js';