diff --git a/dashboards-observability/.cypress/integration/event_analytics.spec.js b/dashboards-observability/.cypress/integration/event_analytics.spec.js index 5aeb98057..46b03b715 100644 --- a/dashboards-observability/.cypress/integration/event_analytics.spec.js +++ b/dashboards-observability/.cypress/integration/event_analytics.spec.js @@ -227,9 +227,7 @@ describe('Click actions', () => { describe('Saves a query on explorer page', () => { it('Saves a query on event tab of explorer page', () => { landOnEventExplorer(); - - cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[0].query); - cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click(); + querySearch(TEST_QUERIES[0].query, TEST_QUERIES[0].dateRangeDOM); cy.wait(delay); cy.get('.tab-title').contains('Events').click(); @@ -248,13 +246,13 @@ describe('Saves a query on explorer page', () => { it('Saves a visualization on visualization tab of explorer page', () => { landOnEventExplorer(); - - cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[1].query); - cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click(); + querySearch(TEST_QUERIES[1].query, TEST_QUERIES[1].dateRangeDOM); cy.wait(delay); supressResizeObserverIssue(); cy.get('button[id="main-content-vis"]').contains('Visualizations').click(); cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click(); + cy.wait(delay * 2); + cy.get('[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]').click(); cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY2); cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click(); cy.wait(delay * 2); @@ -277,14 +275,14 @@ describe('Saves a query on explorer page', () => { cy.wait(delay); landOnEventExplorer(); - - cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[1].query); - cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click(); + querySearch(TEST_QUERIES[1].query, TEST_QUERIES[1].dateRangeDOM); cy.wait(delay); supressResizeObserverIssue(); cy.get('button[id="main-content-vis"]').contains('Visualizations').click(); cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click(); + cy.wait(delay * 2); + cy.get('[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]').click(); cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY3); cy.get('[data-test-subj="eventExplorer__querySaveComboBox"]').type(TESTING_PANEL); cy.get(`input[value="${TESTING_PANEL}"]`).click(); diff --git a/dashboards-observability/.cypress/utils/event_constants.js b/dashboards-observability/.cypress/utils/event_constants.js index 7e3b5b8bc..130d32590 100644 --- a/dashboards-observability/.cypress/utils/event_constants.js +++ b/dashboards-observability/.cypress/utils/event_constants.js @@ -14,7 +14,8 @@ export const TEST_QUERIES = [ dateRangeDOM: YEAR_TO_DATE_DOM_ID }, { - query: 'source = opensearch_dashboards_sample_data_flights | stats avg(FlightDelayMin) by Carrier' + query: 'source = opensearch_dashboards_sample_data_flights | stats avg(FlightDelayMin) by Carrier', + dateRangeDOM: YEAR_TO_DATE_DOM_ID }, { query: 'source = opensearch_dashboards_sample_data_logs' @@ -38,6 +39,7 @@ export const SAVE_QUERY4 = 'Mock Flight peek'; export const querySearch = (query, rangeSelected) => { cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(query); cy.get('[data-test-subj="superDatePickerToggleQuickMenuButton"]').click(); + cy.wait(delay); cy.get(rangeSelected).click(); cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click(); }; diff --git a/dashboards-observability/package.json b/dashboards-observability/package.json index 279e9b8b3..4a3077bf9 100644 --- a/dashboards-observability/package.json +++ b/dashboards-observability/package.json @@ -22,11 +22,12 @@ "react-plotly.js": "^2.5.1" }, "devDependencies": { + "@cypress/skip-test": "^2.6.1", "@types/enzyme-adapter-react-16": "^1.0.6", "@types/react-plotly.js": "^2.5.0", "@types/react-test-renderer": "^16.9.1", - "@cypress/skip-test": "^2.6.1", "cypress": "^5.0.0", + "eslint": "^6.8.0", "jest-dom": "^4.0.0", "performance-now": "^2.1.0" }, diff --git a/dashboards-observability/server/routes/event_analytics/event_analytics_router.ts b/dashboards-observability/server/routes/event_analytics/event_analytics_router.ts index 211aa2a60..4040e7e66 100644 --- a/dashboards-observability/server/routes/event_analytics/event_analytics_router.ts +++ b/dashboards-observability/server/routes/event_analytics/event_analytics_router.ts @@ -25,13 +25,39 @@ export const registerEventAnalyticsRouter = ({ router: IRouter; savedObjectFacet: SavedObjectFacet; }) => { + router.get( { path: `${OBSERVABILITY_BASE}${EVENT_ANALYTICS}${SAVED_OBJECTS}`, - validate: false, + validate: {}, }, async (context, req, res): Promise> => { - const savedRes = await savedObjectFacet.getSavedQuery(req); + const savedRes = await savedObjectFacet.getSavedObject(req); + const result: any = { + body: { + ...savedRes.data, + }, + }; + + if (savedRes.success || savedRes?.data?.statusCode === 404) return res.ok(result); + + result.statusCode = savedRes?.data?.statusCode || 500; + result.message = savedRes?.data || ''; + return res.custom(result); + } + ); + + router.get( + { + path: `${OBSERVABILITY_BASE}${EVENT_ANALYTICS}${SAVED_OBJECTS}/{objectId}`, + validate: { + params: schema.object({ + objectId: schema.string(), + }), + }, + }, + async (context, req, res): Promise> => { + const savedRes = await savedObjectFacet.getSavedObjectById(req, req.params.objectId); const result: any = { body: { ...savedRes.data, diff --git a/dashboards-observability/server/services/facets/saved_objects.ts b/dashboards-observability/server/services/facets/saved_objects.ts index 148883259..30286d21b 100644 --- a/dashboards-observability/server/services/facets/saved_objects.ts +++ b/dashboards-observability/server/services/facets/saved_objects.ts @@ -14,15 +14,12 @@ export default class SavedObjectFacet { this.client = client; } - fetch = async (request: any, format: string) => { + fetch = async (request: any, params: any, format: string) => { const res = { success: false, data: {}, }; try { - const params = { - ...request.url.query, - }; const savedQueryRes = await this.client.asScoped(request).callAsCurrentUser(format, params); res.success = true; res.data = savedQueryRes; @@ -191,12 +188,18 @@ export default class SavedObjectFacet { return res; }; - getSavedQuery = async (request: any) => { - return this.fetch(request, 'observability.getObject'); - }; - - getSavedVisualization = async (request: any) => { - return this.fetch(request, 'observability.getObject'); + getSavedObject = async (request: any) => { + const params = {}; + for (const [param, value] of request.url.searchParams.entries()) { + params[param] = value; + } + return this.fetch( + request, + { + ...params + }, + 'observability.getObject' + ); }; createSavedQuery = async (request: any) => { diff --git a/dashboards-observability/yarn.lock b/dashboards-observability/yarn.lock index f41e80060..475dee487 100644 --- a/dashboards-observability/yarn.lock +++ b/dashboards-observability/yarn.lock @@ -294,7 +294,17 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== -ajv@^6.12.3: +acorn-jsx@^5.2.0: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -356,6 +366,13 @@ arch@^2.1.2: resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -976,6 +993,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + get-intrinsic@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" @@ -1174,6 +1196,25 @@ ini@1.3.7: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== +inquirer@^7.0.0: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + is-alphabetical@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" @@ -1731,6 +1772,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -2043,6 +2089,23 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.1.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -2384,6 +2447,13 @@ warning@^4.0.2, warning@^4.0.3: dependencies: loose-envify "^1.0.0" +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"