Skip to content

[ResponseOps][Reporting] Add support for deletion of export schedules#238197

Merged
umbopepato merged 21 commits intoelastic:mainfrom
umbopepato:2081-scheduled-exports-delete
Oct 20, 2025
Merged

[ResponseOps][Reporting] Add support for deletion of export schedules#238197
umbopepato merged 21 commits intoelastic:mainfrom
umbopepato:2081-scheduled-exports-delete

Conversation

@umbopepato
Copy link
Member

@umbopepato umbopepato commented Oct 9, 2025

📄 Summary

  • Adds backend support for deleting export schedules
  • Adds client-side delete schedules fetcher and react-query hook
  • Adds delete UI action to Stack Management > Reporting > Schedules table rows

🧪 Verification steps

✅ Happy Path

  1. If you don't have any Dashboard or Discover session to export, install a sample data set from the Kibana home page
  2. Open any dashboard or Discover session
  3. Click on the ⬇️ (Export) button in the app bar
  4. Click on Schedule export
  5. Choose a close schedule time (minutes after)
  6. Repeat from point 2 more times to get more schedules
  7. Navigate to Stack Management > Reporting > Schedules
  8. Click on the actions menu button (•••)
  9. Click Delete schedule
  10. Verify that the schedule item disappeared from the table
  11. Wait for the execution time of the schedules and verify that after that time, no report was created in the Reports tab (refresh if necessary)

📷 Screenshots

image image image

⏪ Backport rationale

Not backporting since this is a new functionality

🔗 References

Closes #2081

Release Notes

Added support for deleting export schedules

Checklist

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed (50 runs passed)
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.
@umbopepato umbopepato added backport:skip This PR does not require backporting Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// release_note:feature Makes this part of the condensed release notes v9.3.0 labels Oct 9, 2025
onCancel,
onConfirm,
}) => {
const ReportDestructiveActionConfirmationModalComponent: React.FC<
Copy link
Member Author

Choose a reason for hiding this comment

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

Made this generic so we can use it both for disable and delete

ids.map((id) => ({ id, type: SCHEDULED_REPORT_SAVED_OBJECT_TYPE }))
);

const scheduledReportSavedObjectsToDelete: Array<SavedObject<ScheduledReportType>> = [];
Copy link
Member Author

@umbopepato umbopepato Oct 9, 2025

Choose a reason for hiding this comment

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

Existence and authorization check should be the same as when disabling, working on a possible abstraction to avoid duplicated code fragments, even though the two loops have small differences that make it difficult (or inefficient) to centralize everything...

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried to extract it to a checkScheduledReportBulkActionAuthorization function, but it is quite impractical since the two endpoints perform slightly different checks in the loop. The common structure is:
For each SO read

  • if there was a read error, add it to bulkErrors to report
  • otherwise check ownership
    • if user is not manager and not author of SO, add error to bulkErrors
    • otherwise add SO id to list of "authorized" ones to operate on
    • audit log event

In the disable case though there is an early return condition on the enabled field, which would require a second iteration pass or some sort of callback passed from the outside.

Since @adcoelho started refactoring the whole factory into a class, I'd address this with the new structure: perhaps we can find a better way to extract this.

};
}

const resultFromRemoveTasks = await taskManager.bulkRemove(taskIdsToRemove);
Copy link
Member Author

Choose a reason for hiding this comment

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

Removing the tasks instead of disabling them since the schedule won't be recoverable

@umbopepato umbopepato marked this pull request as ready for review October 9, 2025 10:10
@umbopepato umbopepato requested a review from a team as a code owner October 9, 2025 10:10
@elasticmachine
Copy link
Contributor

Pinging @elastic/response-ops (Team:ResponseOps)

useGetScheduledList: jest.fn(),
}));
jest.mock('../hooks/use_bulk_disable');
jest.mock('../apis/get_scheduled_reports_list');
Copy link
Member Author

Choose a reason for hiding this comment

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

While I was at it, I switched from mocking the entire react-query hooks to just mocking the underlying fetch functions so we can mock with full type safety and have a more realistic behavior with RQ

@@ -400,5 +413,135 @@ export function scheduledQueryFactory(reportingCore: ReportingCore): ScheduledQu
});
}
},

async bulkDelete(logger, req, res, ids, user) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I have a couple of nits :D

  • If the ids are part of the req, it feels kinda weird to pass both.
  • Passing res also doesn't make sense to me(I know other methods in this file do it too 😬 ). Why not throw Boom.whatever?

I think fundamentally it would make sense to isolate the route logic from the client logic.

If there is time, we(and I'm saying we because I also have a task where I can help 😅), we could refactor this into a class.

  1. We would eliminate a lot of duplication. It would make sense to have a constructor where
this.savedObjectsClient = await reportingCore.getScopedSoClient(req);
this.esClient = await reportingCore.getEsClient();
this.auditLogger = await reportingCore.getAuditLogger(req);
this.taskManager = await reportingCore.getTaskManager();
this.canManageReporting = await reportingCore.canManageReportingForSpace(req);
  1. We could move part of the logic of these big functions into private methods that are more readable. The calls to auditLogger.log(scheduledReportAuditEvent({ are all pretty similar, e.g.
Copy link
Member Author

Choose a reason for hiding this comment

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

I absolutely agree, it would be much simpler and more organized!

Copy link
Contributor

Choose a reason for hiding this comment

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

This has been fixed in #238663

);

const scheduledReportSavedObjectsToDelete: Array<SavedObject<ScheduledReportType>> = [];
for (const so of bulkGetResult.saved_objects) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we maybe add a filter to bulkGet to only return the ones created by this user when !canManageReporting?

We could then check the difference in IDs to build the error array and avoid this loop.

It would avoid this loop

Copy link
Member Author

@umbopepato umbopepato Oct 13, 2025

Choose a reason for hiding this comment

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

I repeated the same structure as the bulkDisable method, I think @ymao1's intention was to loop over all the requested SOs (regardless of authorship) to accumulate errors for the unauthorized ones? Filtering would be fine for me, but I wouldn't want the new endpoint to have a different behavior than the other ones, wdyt?

@kibanamachine
Copy link
Contributor

Flaky Test Runner Stats

🎉 All tests passed! - kibana-flaky-test-suite-runner#9524

[✅] x-pack/platform/test/reporting_api_integration/reporting_and_security.config.ts: 50/50 tests passed.

see run history

adcoelho added a commit that referenced this pull request Oct 14, 2025
## Summary

When I started to work on ["editing scheduled
reports"](elastic/kibana-team#2083), I looked
around in the reporting plugin for something like a
`scheduledReportClient` so I could create an `update` method.

This client does not exist. I was surprised that there isn't a single
"client" to manage `SCHEDULED_REPORT_SAVED_OBJECT_TYPE` SOs. Instead,
that is done in a couple of different places.

- `ScheduleRequestHandler` has the creation logic and schedules the
report generation tasks.
- `ScheduledQueryFactory` handles `list` and `bulkDisable`.

Moreover, these were found in `routes/common` but weren't shared by any
routes. They are each imported in a single place.

I think it makes sense to consolidate this client/service logic, and
move it **outside** of the `routes` folder.

As a first step, I am just moving some code around.

The consolidation of `ScheduleRequestHandler` with
`ScheduledQueryFactory` into a `ScheduledRequestClient` will be done
later.

For now, this PR does the following:
- I will wait for @umbopepato 's PR to be merged first - #238197.
- Just moving code around. Nothing changed(yet), and no tests should
fail.
- `ScheduledQueryFactory` now lives in
`reporting/server/services/scheduled_reports/`.
- the file where `ScheduledQueryFactory` had too much logic, it was
split into:
    - `constants.ts`
    - `transforms.ts`
    - `transforms.test.ts`
- `audit_events.ts` was moved into
`reporting/server/services/audit_events/`.
Copy link
Contributor

@ymao1 ymao1 left a comment

Choose a reason for hiding this comment

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

LGTM. Verified works as described.

Copy link

@joana-cps joana-cps left a comment

Choose a reason for hiding this comment

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

Overall LGTM. Just one thing:

499276511-3e0ce676-6423-4a1e-b8aa-6c5680ec1523

This confirmation button should be specific to the action that the user is performing. Delete or 'Delete schedule' in this case.

I get that you're trying to be generic here, but this goes against our best practices for destructive actions.

Copy link
Contributor

@js-jankisalvi js-jankisalvi left a comment

Choose a reason for hiding this comment

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

Verified locally works as expected 🎉 Added some queries.

onCancel,
onConfirm,
}) => {
const ReportDestructiveActionConfirmationModalComponent: React.FC<
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: could you please add a test file for it?

// scheduled reports for all users in this space
const canManageReporting = await reportingCore.canManageReportingForSpace(req);

const bulkGetResult = await savedObjectsClient.bulkGet<ScheduledReportType>(
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Should we do this bulk operation in batches to handle large number of report schedules in future like we do for rules?

Copy link
Member Author

@umbopepato umbopepato Oct 15, 2025

Choose a reason for hiding this comment

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

Thanks for the heads up! To keep things simple I repeated the same flow as in the disable endpoint that Ying implemented. It would be a nice way to future-proof these actions in case we actually want to start doing bulk operations, but I guess it would probably make sense to do it for the other ops as well (disable and update), so perhaps a dedicated PR is the best thing to do?
@cnasikas let us know what you think about this

Copy link
Member

Choose a reason for hiding this comment

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

Even if the other methods/routes do not impose any limit or do not take into account a large number of reports, we should do it in this PR. I would suggest putting a limit of up to 50 IDs on the schema of the route. At the moment, it is set to 1K, which is too much, I think. Also, we can open a tech debt issue with Janki's suggestion. We should handle this.

Copy link
Contributor

@adcoelho adcoelho left a comment

Choose a reason for hiding this comment

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

LGTM!

@umbopepato
Copy link
Member Author

Overall LGTM. Just one thing:

499276511-3e0ce676-6423-4a1e-b8aa-6c5680ec1523 This confirmation button should be specific to the action that the user is performing. `Delete` or 'Delete schedule' in this case.

I get that you're trying to be generic here, but this goes against our best practices for destructive actions.

Thanks for the heads up! I made the confirmation button action-specific 🙂

// scheduled reports for all users in this space
const canManageReporting = await reportingCore.canManageReportingForSpace(req);

const bulkGetResult = await savedObjectsClient.bulkGet<ScheduledReportType>(
Copy link
Member

Choose a reason for hiding this comment

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

Even if the other methods/routes do not impose any limit or do not take into account a large number of reports, we should do it in this PR. I would suggest putting a limit of up to 50 IDs on the schema of the route. At the moment, it is set to 1K, which is too much, I think. Also, we can open a tech debt issue with Janki's suggestion. We should handle this.

}
},

async bulkDelete(logger, req, res, ids, user) {
Copy link
Member

Choose a reason for hiding this comment

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

I think the function is too large, doing so many things. Could you please refactor a bit to make it easier to read? We can move a lot of the functionality to functions (inside the same folder) and reduce the code to perform a couple of steps. Wdyt?

@umbopepato
Copy link
Member Author

@cnasikas I improved the composition of the bulkDelete method, as discussed offline. FYI this is what I had in mind to improve things at a class-level, building upon @adcoelho's refactor work

mgadewoll pushed a commit to tkajtoch/kibana that referenced this pull request Oct 17, 2025
## Summary

When I started to work on ["editing scheduled
reports"](elastic/kibana-team#2083), I looked
around in the reporting plugin for something like a
`scheduledReportClient` so I could create an `update` method.

This client does not exist. I was surprised that there isn't a single
"client" to manage `SCHEDULED_REPORT_SAVED_OBJECT_TYPE` SOs. Instead,
that is done in a couple of different places.

- `ScheduleRequestHandler` has the creation logic and schedules the
report generation tasks.
- `ScheduledQueryFactory` handles `list` and `bulkDisable`.

Moreover, these were found in `routes/common` but weren't shared by any
routes. They are each imported in a single place.

I think it makes sense to consolidate this client/service logic, and
move it **outside** of the `routes` folder.

As a first step, I am just moving some code around.

The consolidation of `ScheduleRequestHandler` with
`ScheduledQueryFactory` into a `ScheduledRequestClient` will be done
later.

For now, this PR does the following:
- I will wait for @umbopepato 's PR to be merged first - elastic#238197.
- Just moving code around. Nothing changed(yet), and no tests should
fail.
- `ScheduledQueryFactory` now lives in
`reporting/server/services/scheduled_reports/`.
- the file where `ScheduledQueryFactory` had too much logic, it was
split into:
    - `constants.ts`
    - `transforms.ts`
    - `transforms.test.ts`
- `audit_events.ts` was moved into
`reporting/server/services/audit_events/`.
rylnd pushed a commit to rylnd/kibana that referenced this pull request Oct 17, 2025
## Summary

When I started to work on ["editing scheduled
reports"](elastic/kibana-team#2083), I looked
around in the reporting plugin for something like a
`scheduledReportClient` so I could create an `update` method.

This client does not exist. I was surprised that there isn't a single
"client" to manage `SCHEDULED_REPORT_SAVED_OBJECT_TYPE` SOs. Instead,
that is done in a couple of different places.

- `ScheduleRequestHandler` has the creation logic and schedules the
report generation tasks.
- `ScheduledQueryFactory` handles `list` and `bulkDisable`.

Moreover, these were found in `routes/common` but weren't shared by any
routes. They are each imported in a single place.

I think it makes sense to consolidate this client/service logic, and
move it **outside** of the `routes` folder.

As a first step, I am just moving some code around.

The consolidation of `ScheduleRequestHandler` with
`ScheduledQueryFactory` into a `ScheduledRequestClient` will be done
later.

For now, this PR does the following:
- I will wait for @umbopepato 's PR to be merged first - elastic#238197.
- Just moving code around. Nothing changed(yet), and no tests should
fail.
- `ScheduledQueryFactory` now lives in
`reporting/server/services/scheduled_reports/`.
- the file where `ScheduledQueryFactory` had too much logic, it was
split into:
    - `constants.ts`
    - `transforms.ts`
    - `transforms.test.ts`
- `audit_events.ts` was moved into
`reporting/server/services/audit_events/`.
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 my comments! LGTM!

@umbopepato umbopepato enabled auto-merge (squash) October 20, 2025 13:21
@umbopepato umbopepato merged commit 7e40cbb into elastic:main Oct 20, 2025
13 checks passed
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
reporting 229 231 +2

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
@kbn/reporting-common 99 100 +1

Async chunks

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

id before after diff
fleet 2.1MB 2.1MB +39.0B
reporting 181.3KB 183.3KB +2.0KB
total +2.0KB

Page load bundle

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

id before after diff
reporting 41.4KB 41.5KB +39.0B
Unknown metric groups

API count

id before after diff
@kbn/reporting-common 109 110 +1

History

nickpeihl pushed a commit to nickpeihl/kibana that referenced this pull request Oct 23, 2025
## Summary

When I started to work on ["editing scheduled
reports"](elastic/kibana-team#2083), I looked
around in the reporting plugin for something like a
`scheduledReportClient` so I could create an `update` method.

This client does not exist. I was surprised that there isn't a single
"client" to manage `SCHEDULED_REPORT_SAVED_OBJECT_TYPE` SOs. Instead,
that is done in a couple of different places.

- `ScheduleRequestHandler` has the creation logic and schedules the
report generation tasks.
- `ScheduledQueryFactory` handles `list` and `bulkDisable`.

Moreover, these were found in `routes/common` but weren't shared by any
routes. They are each imported in a single place.

I think it makes sense to consolidate this client/service logic, and
move it **outside** of the `routes` folder.

As a first step, I am just moving some code around.

The consolidation of `ScheduleRequestHandler` with
`ScheduledQueryFactory` into a `ScheduledRequestClient` will be done
later.

For now, this PR does the following:
- I will wait for @umbopepato 's PR to be merged first - elastic#238197.
- Just moving code around. Nothing changed(yet), and no tests should
fail.
- `ScheduledQueryFactory` now lives in
`reporting/server/services/scheduled_reports/`.
- the file where `ScheduledQueryFactory` had too much logic, it was
split into:
    - `constants.ts`
    - `transforms.ts`
    - `transforms.test.ts`
- `audit_events.ts` was moved into
`reporting/server/services/audit_events/`.
nickpeihl pushed a commit to nickpeihl/kibana that referenced this pull request Oct 23, 2025
…elastic#238197)

## 📄 Summary

- Adds backend support for deleting export schedules
- Adds client-side delete schedules fetcher and react-query hook
- Adds delete UI action to `Stack Management` > `Reporting` >
`Schedules` table rows

<details>
<summary>

## 🧪 Verification steps

</summary>

### ✅ Happy Path

1. If you don't have any Dashboard or Discover session to export,
install a sample data set from the Kibana home page
2. Open any dashboard or Discover session
3. Click on the ⬇️ (Export) button in the app bar
4. Click on Schedule export
5. Choose a close schedule time (minutes after)
6. Repeat from point 2 more times to get more schedules
7. Navigate to `Stack Management` > `Reporting` > `Schedules`
8. Click on the actions menu button (•••)
9. Click `Delete schedule`
10. Verify that the schedule item disappeared from the table
11. Wait for the execution time of the schedules and verify that after
that time, no report was created in the `Reports` tab (refresh if
necessary)

</details>

<details>
<summary>

## 📷 Screenshots

</summary>

<img width="1015" height="392" alt="image"
src="https://github.com/user-attachments/assets/36296a25-a6c9-4832-b190-54b35d14676d"
/>

<img width="1100" height="583" alt="image"
src="https://github.com/user-attachments/assets/3e0ce676-6423-4a1e-b8aa-6c5680ec1523"
/>

<img width="684" height="447" alt="image"
src="https://github.com/user-attachments/assets/66051f5a-ca38-4d26-996d-ba74a8d6181b"
/>

</details>

## ⏪ Backport rationale

Not backporting since this is a new functionality

## 🔗 References

Closes [elastic#2081](elastic/kibana-team#2081)

## Release Notes

Added support for deleting export schedules

### Checklist

- [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/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [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
- [ ] ~~If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~~
- [ ] ~~This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.~~
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed ([50 runs
passed](elastic#238197 (comment)))
- [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)
- [x] Review the [backport
guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)
and apply applicable `backport:*` labels.
NicholasPeretti pushed a commit to NicholasPeretti/kibana that referenced this pull request Oct 27, 2025
## Summary

When I started to work on ["editing scheduled
reports"](elastic/kibana-team#2083), I looked
around in the reporting plugin for something like a
`scheduledReportClient` so I could create an `update` method.

This client does not exist. I was surprised that there isn't a single
"client" to manage `SCHEDULED_REPORT_SAVED_OBJECT_TYPE` SOs. Instead,
that is done in a couple of different places.

- `ScheduleRequestHandler` has the creation logic and schedules the
report generation tasks.
- `ScheduledQueryFactory` handles `list` and `bulkDisable`.

Moreover, these were found in `routes/common` but weren't shared by any
routes. They are each imported in a single place.

I think it makes sense to consolidate this client/service logic, and
move it **outside** of the `routes` folder.

As a first step, I am just moving some code around.

The consolidation of `ScheduleRequestHandler` with
`ScheduledQueryFactory` into a `ScheduledRequestClient` will be done
later.

For now, this PR does the following:
- I will wait for @umbopepato 's PR to be merged first - elastic#238197.
- Just moving code around. Nothing changed(yet), and no tests should
fail.
- `ScheduledQueryFactory` now lives in
`reporting/server/services/scheduled_reports/`.
- the file where `ScheduledQueryFactory` had too much logic, it was
split into:
    - `constants.ts`
    - `transforms.ts`
    - `transforms.test.ts`
- `audit_events.ts` was moved into
`reporting/server/services/audit_events/`.
NicholasPeretti pushed a commit to NicholasPeretti/kibana that referenced this pull request Oct 27, 2025
…elastic#238197)

## 📄 Summary

- Adds backend support for deleting export schedules
- Adds client-side delete schedules fetcher and react-query hook
- Adds delete UI action to `Stack Management` > `Reporting` >
`Schedules` table rows

<details>
<summary>

## 🧪 Verification steps

</summary>

### ✅ Happy Path

1. If you don't have any Dashboard or Discover session to export,
install a sample data set from the Kibana home page
2. Open any dashboard or Discover session
3. Click on the ⬇️ (Export) button in the app bar
4. Click on Schedule export
5. Choose a close schedule time (minutes after)
6. Repeat from point 2 more times to get more schedules
7. Navigate to `Stack Management` > `Reporting` > `Schedules`
8. Click on the actions menu button (•••)
9. Click `Delete schedule`
10. Verify that the schedule item disappeared from the table
11. Wait for the execution time of the schedules and verify that after
that time, no report was created in the `Reports` tab (refresh if
necessary)

</details>

<details>
<summary>

## 📷 Screenshots

</summary>

<img width="1015" height="392" alt="image"
src="https://github.com/user-attachments/assets/36296a25-a6c9-4832-b190-54b35d14676d"
/>

<img width="1100" height="583" alt="image"
src="https://github.com/user-attachments/assets/3e0ce676-6423-4a1e-b8aa-6c5680ec1523"
/>

<img width="684" height="447" alt="image"
src="https://github.com/user-attachments/assets/66051f5a-ca38-4d26-996d-ba74a8d6181b"
/>

</details>

## ⏪ Backport rationale

Not backporting since this is a new functionality

## 🔗 References

Closes [elastic#2081](elastic/kibana-team#2081)

## Release Notes

Added support for deleting export schedules

### Checklist

- [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/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [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
- [ ] ~~If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~~
- [ ] ~~This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.~~
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed ([50 runs
passed](elastic#238197 (comment)))
- [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)
- [x] Review the [backport
guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)
and apply applicable `backport:*` labels.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:feature Makes this part of the condensed release notes Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// v9.3.0

8 participants