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

[ResponceOps][MaintenanceWindow] MX Pagination #202539

Merged
merged 61 commits into from
Dec 21, 2024

Conversation

guskovaue
Copy link
Contributor

@guskovaue guskovaue commented Dec 2, 2024

Fixes: #198252

In this PR I introduced pagination in MW frontend part and also pass filters(status and search) to the backend. Pagination arguments were passed to backend in another PR: https://github.com/elastic/kibana/pull/197172/files#diff-f375a192a08a6db3fbb6b6e927cecaab89ff401efc4034f00761e8fc4478734c

How to test:
Go to Maintenance Window, create more than 10 MW with different statuses. Try pagination, search on text and filter by status.

Check the PR satisfies following conditions:

@guskovaue guskovaue self-assigned this Dec 2, 2024
@guskovaue guskovaue added release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) v9.0.0 Feature:Alerting/RulesManagement Issues related to the Rules Management UX backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) v8.18.0 labels Dec 3, 2024
Copy link
Member

@cnasikas cnasikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I left some comments. Also, I think we should stick with status instead of statuses in the codebase.

Comment on lines 32 to 37
const fullQuery = statuses
?.slice(1)
.reduce(
(acc, currentStatusFilter) => acc + ` or ${statusToQueryMapping[currentStatusFilter] || ''}`,
statusToQueryMapping[statuses[0]] || ''
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const fullQuery = statuses
?.slice(1)
.reduce(
(acc, currentStatusFilter) => acc + ` or ${statusToQueryMapping[currentStatusFilter] || ''}`,
statusToQueryMapping[statuses[0]] || ''
);
const fullQuery = statuses.map((status) => statusToQueryMapping[status]).filter(Boolean).join('or')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this?


const [inputText, setInputText] = useState<string>('');
const [selectedStatuses, setSelectedStatuses] = useState<MaintenanceWindowStatus[]>([]);
const [searchText, setSearchText] = useState<string>('');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused 🙂. Why do we need the inputText and the searchText. Could we do it only with searchText?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to states here. We do not have incremental search here. We search when Enter key will be pressed. So we need one state for search line and one state for current input.

});
await browser.refresh();

await pageObjects.maintenanceWindows.searchMaintenanceWindows('pagination');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are filtering here because we do not have delete endpoint and all previous MWs are in place.
It was written like this before by Alexi, so I decided to continue like this for now and change, when we introduce delete MW.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then I would suggest moving the state for the input in x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx and keeping only the state for the search in this component. Example

// x-pack/plugins/alerting/public/pages/maintenance_windows/index.tsx

const [search, setSearch] = useState<string>('');

<MaintenanceWindowsList
  onSearchChange={setSearch}
/>

// x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx

const [search, setSearch] = useState<string>('');

<EuiFieldSearch
    incremental={false}
    placeholder={i18n.SEARCH_PLACEHOLDER}
    value={inputText}
    onSearch={onSearchChange} // from props
    onChange={(e) => setSearch(e.target.value)}
/>

@cnasikas
Copy link
Member

I forgot to say that I noticed that when we loading (filtering by status for example) we show a spinner and hide the whole page. What about showing a loading state deeper in the code, for example a progress bar in the table or similar?

Screen.Recording.2024-12-16.at.3.05.56.PM.mov

Copy link
Member

@afharo afharo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SO changes LGTM

Copy link
Member

@cnasikas cnasikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the comments. I think there are some more left.

Comment on lines 12 to 19
// loadTestFile(require.resolve('./home_page'));
// loadTestFile(require.resolve('./rules_list'));
// loadTestFile(require.resolve('./alert_create_flyout'));
// loadTestFile(require.resolve('./details'));
// loadTestFile(require.resolve('./connectors'));
// loadTestFile(require.resolve('./logs_list'));
// loadTestFile(require.resolve('./rules_settings'));
// loadTestFile(require.resolve('./stack_alerts_page'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's umcomment all of them.

Comment on lines 13 to 14
// loadTestFile(require.resolve('./maintenance_window_create_form'));
// loadTestFile(require.resolve('./maintenance_window_update_form'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's umcomment all of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already done. I forgot to do it first

@@ -53,7 +66,7 @@ export const useFindMaintenanceWindows = (props?: UseFindMaintenanceWindowsProps
});

return {
maintenanceWindows: data,
data: data || { maintenanceWindows: [], total: 0 },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is happening because on an error data will be undefined. What if you keep the placeholderData and also do

const { data, ..// other stuff } = useFindMaintenanceWindows({ ...// args })
const { maintenanceWindows, total } = data ?? { maintenanceWindows: [], total: 0 };

Comment on lines 32 to 37
const fullQuery = statuses
?.slice(1)
.reduce(
(acc, currentStatusFilter) => acc + ` or ${statusToQueryMapping[currentStatusFilter] || ''}`,
statusToQueryMapping[statuses[0]] || ''
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this?

[MaintenanceWindowStatus.Upcoming]:
'(not (maintenance-window.attributes.events: "now") and maintenance-window.attributes.events >= "now")',
[MaintenanceWindowStatus.Finished]:
'(not (maintenance-window.attributes.events >= "now" or maintenance-window.attributes.expirationDate < "now"))',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for an archived MW to have events where maintenance-window.attributes.events < "now")?

});
await browser.refresh();

await pageObjects.maintenanceWindows.searchMaintenanceWindows('pagination');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then I would suggest moving the state for the input in x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx and keeping only the state for the search in this component. Example

// x-pack/plugins/alerting/public/pages/maintenance_windows/index.tsx

const [search, setSearch] = useState<string>('');

<MaintenanceWindowsList
  onSearchChange={setSearch}
/>

// x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx

const [search, setSearch] = useState<string>('');

<EuiFieldSearch
    incremental={false}
    placeholder={i18n.SEARCH_PLACEHOLDER}
    value={inputText}
    onSearch={onSearchChange} // from props
    onChange={(e) => setSearch(e.target.value)}
/>

queryKey: ['findMaintenanceWindows'],
const queryKey = ['findMaintenanceWindows', page, perPage, search, selectedStatus];

const { isLoading, isFetching, isInitialLoading, data, refetch } = useQuery({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also add keepPreviousData: true to avoid having the table clear every time we change status.

perPage: number;
total: number;
onPageChange: ({ page: { index, size } }: { page: { index: number; size: number } }) => void;
inputText: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kindly reminder.

[MaintenanceWindowStatus.Upcoming]:
'(not (maintenance-window.attributes.events: "now") and maintenance-window.attributes.events >= "now")',
[MaintenanceWindowStatus.Finished]:
'(not (maintenance-window.attributes.events >= "now" or maintenance-window.attributes.expirationDate < "now"))',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes sorry what I meant was not maintenance-window.attributes.events: > "now" and maintenance-window.attributes.expirationDate > "now"

Copy link
Member

@cnasikas cnasikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work 🚀

@elasticmachine
Copy link
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #20 / alerting api integration security and spaces enabled - Group 2 Alerting and Actions Telemetry test telemetry should retrieve telemetry data in the expected format

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
alerting 247 246 -1

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
alerting 839 841 +2

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
alerting 100.7KB 101.6KB +895.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
alerting 25.6KB 25.8KB +158.0B
Unknown metric groups

API count

id before after diff
alerting 872 874 +2

History

cc @guskovaue

@guskovaue guskovaue merged commit 43abe23 into elastic:main Dec 21, 2024
8 checks passed
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.x

https://github.com/elastic/kibana/actions/runs/12448048216

kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Dec 21, 2024
Fixes: elastic#198252

In this PR I introduced pagination in MW frontend part and also pass
filters(status and search) to the backend. Pagination arguments were
passed to backend in another PR:
https://github.com/elastic/kibana/pull/197172/files#diff-f375a192a08a6db3fbb6b6e927cecaab89ff401efc4034f00761e8fc4478734c

How to test:
Go to Maintenance Window, create more than 10 MW with different
statuses. Try pagination, search on text and filter by status.

Check the PR satisfies following conditions:

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit 43abe23)
@kibanamachine
Copy link
Contributor

💚 All backports created successfully

Status Branch Result
8.x

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Dec 21, 2024
# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponceOps][MaintenanceWindow] MX Pagination
(#202539)](#202539)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT
[{"author":{"name":"Julia","email":"iuliia.guskova@elastic.co"},"sourceCommit":{"committedDate":"2024-12-21T20:01:11Z","message":"[ResponceOps][MaintenanceWindow]
MX Pagination (#202539)\n\nFixes:
https://github.com/elastic/kibana/issues/198252\r\n\r\nIn this PR I
introduced pagination in MW frontend part and also
pass\r\nfilters(status and search) to the backend. Pagination arguments
were\r\npassed to backend in another
PR:\r\nhttps://github.com//pull/197172/files#diff-f375a192a08a6db3fbb6b6e927cecaab89ff401efc4034f00761e8fc4478734c\r\n\r\nHow
to test:\r\nGo to Maintenance Window, create more than 10 MW with
different\r\nstatuses. Try pagination, search on text and filter by
status.\r\n\r\nCheck the PR satisfies following conditions:\r\n\r\n- [x]
Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] [Flaky
Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\r\nused on any tests changed\r\n- [x] The PR description includes
the appropriate Release Notes section,\r\nand the correct
`release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"43abe233d814cb9a5519a63a2f5942f8802879b2","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","v9.0.0","Feature:Alerting/RulesManagement","backport:prev-minor","v8.18.0"],"title":"[ResponceOps][MaintenanceWindow]
MX
Pagination","number":202539,"url":"https://github.com/elastic/kibana/pull/202539","mergeCommit":{"message":"[ResponceOps][MaintenanceWindow]
MX Pagination (#202539)\n\nFixes:
https://github.com/elastic/kibana/issues/198252\r\n\r\nIn this PR I
introduced pagination in MW frontend part and also
pass\r\nfilters(status and search) to the backend. Pagination arguments
were\r\npassed to backend in another
PR:\r\nhttps://github.com//pull/197172/files#diff-f375a192a08a6db3fbb6b6e927cecaab89ff401efc4034f00761e8fc4478734c\r\n\r\nHow
to test:\r\nGo to Maintenance Window, create more than 10 MW with
different\r\nstatuses. Try pagination, search on text and filter by
status.\r\n\r\nCheck the PR satisfies following conditions:\r\n\r\n- [x]
Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] [Flaky
Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\r\nused on any tests changed\r\n- [x] The PR description includes
the appropriate Release Notes section,\r\nand the correct
`release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"43abe233d814cb9a5519a63a2f5942f8802879b2"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/202539","number":202539,"mergeCommit":{"message":"[ResponceOps][MaintenanceWindow]
MX Pagination (#202539)\n\nFixes:
https://github.com/elastic/kibana/issues/198252\r\n\r\nIn this PR I
introduced pagination in MW frontend part and also
pass\r\nfilters(status and search) to the backend. Pagination arguments
were\r\npassed to backend in another
PR:\r\nhttps://github.com//pull/197172/files#diff-f375a192a08a6db3fbb6b6e927cecaab89ff401efc4034f00761e8fc4478734c\r\n\r\nHow
to test:\r\nGo to Maintenance Window, create more than 10 MW with
different\r\nstatuses. Try pagination, search on text and filter by
status.\r\n\r\nCheck the PR satisfies following conditions:\r\n\r\n- [x]
Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] [Flaky
Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\r\nused on any tests changed\r\n- [x] The PR description includes
the appropriate Release Notes section,\r\nand the correct
`release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"43abe233d814cb9a5519a63a2f5942f8802879b2"}},{"branch":"8.x","label":"v8.18.0","branchLabelMappingKey":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Julia <iuliia.guskova@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) Feature:Alerting/RulesManagement Issues related to the Rules Management UX release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) v8.18.0 v9.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ResponseOps][MW] Support pagination for the maintenance windows UI page
5 participants