From 3bcf7b0763670c0938f7839657b8b90c1d554d1b Mon Sep 17 00:00:00 2001 From: Gabriel Bernal Date: Tue, 9 Jan 2024 18:42:16 +0100 Subject: [PATCH 1/2] allow dev console to add more namespaces to the default selection --- web/cypress/integration/logs-dev-page.cy.ts | 53 +++++++++++++++++- .../en/plugin__logging-view-plugin.json | 3 +- web/src/attribute-filters.tsx | 9 ++- web/src/components/logs-query-input.tsx | 29 +++++++--- web/src/components/logs-toolbar.tsx | 26 +++++++-- web/src/hooks/useLogs.ts | 19 +++++++ web/src/pages/logs-dev-page.tsx | 56 +++++++++++++------ 7 files changed, 165 insertions(+), 30 deletions(-) diff --git a/web/cypress/integration/logs-dev-page.cy.ts b/web/cypress/integration/logs-dev-page.cy.ts index 3473c529c..a1b3e08b5 100644 --- a/web/cypress/integration/logs-dev-page.cy.ts +++ b/web/cypress/integration/logs-dev-page.cy.ts @@ -290,7 +290,7 @@ describe('Logs Dev Page', () => { cy.wait('@resourceQuery').then(({ request }) => { const url = new URL(request.url); - expect(url.pathname).to.equal('/api/kubernetes/api/v1/namespaces/my-namespace/pods'); + expect(url.pathname).to.equal('/api/kubernetes/api/v1/pods'); }); }); @@ -338,4 +338,55 @@ describe('Logs Dev Page', () => { cy.getByTestId(TestIds.LogsMetrics).should('exist'); }); + + it('loads the current namespace as a filter in the query', () => { + cy.intercept(QUERY_RANGE_STREAMS_URL_MATCH, queryRangeMatrixValidResponse()); + + cy.visit(LOGS_DEV_PAGE_URL); + + cy.getByTestId(TestIds.ShowQueryToggle).click(); + + cy.getByTestId(TestIds.LogsQueryInput).within(() => { + cy.get('textarea').contains('kubernetes_namespace_name="my-namespace"'); + }); + }); + + it('updates the query to include the current selected namespace as a filter', () => { + cy.intercept(QUERY_RANGE_STREAMS_URL_MATCH, queryRangeMatrixValidResponse()); + + cy.visit(LOGS_DEV_PAGE_URL); + + cy.getByTestId(TestIds.ShowQueryToggle).click(); + + cy.getByTestId(TestIds.LogsQueryInput).within(() => { + cy.get('textarea').contains('kubernetes_namespace_name="my-namespace"'); + }); + + cy.getByTestId('namespace-toggle' as TestIds).click(); + cy.getByTestId('namespace-dropdown' as TestIds) + .contains('my-namespace-two') + .click(); + + cy.getByTestId(TestIds.LogsQueryInput).within(() => { + cy.get('textarea').contains('kubernetes_namespace_name="my-namespace-two"'); + }); + }); + + it('disables the run query button when there is no selected namespace', () => { + cy.intercept(QUERY_RANGE_STREAMS_URL_MATCH, queryRangeMatrixValidResponse()); + + cy.visit(LOGS_DEV_PAGE_URL); + + cy.getByTestId(TestIds.ShowQueryToggle).click(); + + cy.getByTestId(TestIds.LogsQueryInput).within(() => { + cy.get('textarea').type('{selectAll}').type('{backspace}').type('{ job = "some_job" }', { + parseSpecialCharSequences: false, + }); + }); + + cy.getByTestId(TestIds.ExecuteQueryButton).should('be.disabled'); + + cy.contains('Please select a namespace'); + }); }); diff --git a/web/locales/en/plugin__logging-view-plugin.json b/web/locales/en/plugin__logging-view-plugin.json index ee0ede454..07728f91d 100644 --- a/web/locales/en/plugin__logging-view-plugin.json +++ b/web/locales/en/plugin__logging-view-plugin.json @@ -72,5 +72,6 @@ "Start streaming": "Start streaming", "See related logs": "See related logs", "Aggregated Logs": "Aggregated Logs", - "Logs": "Logs" + "Logs": "Logs", + "Please select a namespace": "Please select a namespace" } diff --git a/web/src/attribute-filters.tsx b/web/src/attribute-filters.tsx index e7440c321..40189981f 100644 --- a/web/src/attribute-filters.tsx +++ b/web/src/attribute-filters.tsx @@ -113,11 +113,18 @@ export const availableDevConsoleAttributes = (namespace: string): AttributeList id: 'content', valueType: 'text', }, + { + name: 'Namespaces', + label: 'kubernetes_namespace_name', + id: 'namespace', + options: resourceDataSource({ resource: 'namespaces' }), + valueType: 'checkbox-select', + }, { name: 'Pods', label: 'kubernetes_pod_name', id: 'pod', - options: resourceDataSource({ resource: 'pods', namespace }), + options: resourceDataSource({ resource: 'pods' }), valueType: 'checkbox-select', }, { diff --git a/web/src/components/logs-query-input.tsx b/web/src/components/logs-query-input.tsx index b37923e13..f3d454512 100644 --- a/web/src/components/logs-query-input.tsx +++ b/web/src/components/logs-query-input.tsx @@ -10,9 +10,17 @@ interface LogsQueryInputProps { value: string; onChange?: (expression: string) => void; onRun?: () => void; + isDisabled?: boolean; + invalidQueryErrorMessage?: string | null; } -export const LogsQueryInput: React.FC = ({ value = '', onChange, onRun }) => { +export const LogsQueryInput: React.FC = ({ + value = '', + onChange, + onRun, + isDisabled, + invalidQueryErrorMessage, +}) => { const { t } = useTranslation('plugin__logging-view-plugin'); const [internalValue, setInternalValue] = React.useState(value); @@ -39,16 +47,23 @@ export const LogsQueryInput: React.FC = ({ value = '', onCh onChange?.(text); }; + const hasError = + !isValid || (invalidQueryErrorMessage !== undefined && invalidQueryErrorMessage !== null); + return (