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

[Content Management] Maps onboard #153304

Merged
merged 27 commits into from
Apr 13, 2023

Conversation

sebelga
Copy link
Contributor

@sebelga sebelga commented Mar 20, 2023

This PR migrates the "map" Saved object type to content management.

Included in the PR

  • removed any usage of the public saved object client
  • registered the map content type in the contentManagement registries (browser and server)
  • created a v1 CM services definition for BWC support
  • created a MapsStorage class on the server to communicate with the saved object client

Not included in this PR

The main focus of the PR was to remove the use of the savedObject public client in the browser. I didn't change other dependency on the @kbn/saved-objects-plugin package like the <SavedObjectSaveModalOrigin /> component.

Notes for reviewer

I've re-written the history of commits to better show how the migration has been done. I would recommend to review "by commit" (read the description of the commit wherever I've added one).

Documentation

In #154453 we have the documentation on how to onboard content into CM.

Fixes #153256

@sebelga sebelga force-pushed the content-management/maps-onboard branch from ebde438 to 6de3442 Compare March 22, 2023 17:07
@sebelga sebelga force-pushed the content-management/maps-onboard branch 2 times, most recently from 10e5f14 to 3bffab5 Compare March 29, 2023 12:18
@sebelga sebelga marked this pull request as ready for review March 29, 2023 12:36
@sebelga sebelga requested review from a team as code owners March 29, 2023 12:36
@sebelga sebelga added release_note:skip Skip the PR/issue when compiling release notes Team:SharedUX Team label for AppEx-SharedUX (formerly Global Experience) Feature:Content Management User generated content (saved objects) management Project:Serverless Work as part of the Serverless project for its initial release Project:BWCA compliance Work effort necessary for Serverless MVP, e.g. HTTP versioning, SO API deprecation work. labels Mar 29, 2023
@elasticmachine
Copy link
Contributor

Pinging @elastic/appex-sharedux (Team:SharedUX)

@sebelga sebelga added Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas Feature:Maps labels Mar 29, 2023
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-presentation (Team:Presentation)

@sebelga
Copy link
Contributor Author

sebelga commented Mar 29, 2023

@elasticmachine merge upstream

@sebelga sebelga marked this pull request as draft March 29, 2023 15:00
@sebelga
Copy link
Contributor Author

sebelga commented Mar 29, 2023

Sorry for the ping to the reviewers. I need to put this back in draft as we are going to make a change to the API before merging this one.

{ unknowns: 'forbid' }
);

const mapSavedObjectSchema = schema.object(
Copy link
Contributor

Choose a reason for hiding this comment

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

Aside from mapAttributesSchema, this looks like a generic saved objects schema

partial: true
): PartialMapSavedObject;

function savedObjectToMapItem(
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 me a bit confused. As best I can tell its changing some object keys from snake case to camel case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is a function that guarantees that we explicitly return the fields for our MapItem instead of doing { attributes: ...savedObject.attributes }

@sebelga sebelga force-pushed the content-management/maps-onboard branch from 67eb74c to abd68a4 Compare April 5, 2023 10:18
sebelga added 7 commits April 5, 2023 15:50
We declare clear TS types for each CRUD (get, create, update, delete) and search methods inside a versioned folder ("v1"). Once that is done we can create the schema validation for the different object and  expose a "v1" serviceDefinition.
A service definition is an object where every objects that comes "in" (e.g. data to be saved or a query to execute) can have a schema validation and up & down transform handler for BWC. The same applies for the result object that comes "out".
The MapsStorage class is where the CRUD + search methods are declared. This is where calls to the Saved Object client apis are made
MapSavedObjectAttributes is going to be versioned and might evolve across different versions of the map content. For that we will expose under the "v1" folder. It is then re-exposed by the "latest.ts" file which is exposed by the barrel file.
@sebelga sebelga self-assigned this Apr 10, 2023
uiStateJSON?: string;
};

export interface MapItem {
Copy link
Member

Choose a reason for hiding this comment

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

this seems like saved object type that could be abstracted as it will be the same for all our saved objects ? SavedObject ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that the goal is to decouple from the SavedObject naming (exposing the persistence layer). There is indeed an opportunity to create a generic somewhere that SO content could extend but the idea in this PR is to decouple the specific content type from the storage layer (SO) and creating generic is out of scope.

Where this generic should live, I don't know.

I do think it is important to not want to abstract too early to save a few LOC (types anyway that will go away). If teams/owners of multiple SO types want to create a package for the generic they are free to do so 😊


// Save data in DB
const soClient = await savedObjectClientFromRequest(ctx);
const partialSavedObject = await soClient.update<MapAttributes>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this work with partial saved objects? Is there something about the SO client that makes this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

uiStateJSON?: string;
};

export interface MapItem {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is really the SO data and meta data. The name item confused me a bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

MapItem,MapSavedObject, Map... It could be named as the team understand better.

With that said, adding the SavedObject suffix is what we want to get away from as we don't want to expose databases specifics (e.g. we would not call this MapPostgreSQL)

@mattkime
Copy link
Contributor

I put together a PR against this branch which simplifies types for any SO using content management. I've made a number of assumptions, hopefully I got more right than wrong - https://github.com/sebelga/kibana/pull/19/files

The abstraction - https://github.com/sebelga/kibana/pull/19/files#diff-1fcd1885f36b55f3d124588ce363d99feffa17cdc3a2f53ff7e611a3f353305a

The result - https://github.com/sebelga/kibana/blob/aabf1c9da2bfedb6f67e04c83cd5d7bfb2557fd6/x-pack/plugins/maps/common/content_management/v1/types.ts

@sebelga
Copy link
Contributor Author

sebelga commented Apr 12, 2023

I put together a PR against this branch which simplifies types for any SO using content management.

@mattkime Those abstraction look good to me. They are out of scope for this PR, you probably want to create a package and expose them for other plugins to consume. And then open a PR to refactor the types here in map 👍

@sebelga sebelga requested a review from nreese April 12, 2023 15:33
@sebelga
Copy link
Contributor Author

sebelga commented Apr 12, 2023

@nreese I reverted the change to return the full object back to only returning the "title" and "description". Can you have another look? Cheers! 👍

@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #40 / Lists plugin Lists API "after all" hook for "should return a 400 if endpoint exception entry has disallowed field"
  • [job] [logs] FTR Configs #40 / Lists plugin Lists API "before all" hook for "should return a 400 if an endpoint exception item with a list-based entry is provided"

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
maps 976 982 +6

Async chunks

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

id before after diff
maps 2.7MB 2.7MB +966.0B

Page load bundle

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

id before after diff
contentManagement 7.5KB 7.5KB +3.0B
maps 57.0KB 57.1KB +86.0B
total +89.0B
Unknown metric groups

ESLint disabled in files

id before after diff
maps 28 27 -1

ESLint disabled line counts

id before after diff
maps 46 47 +1
securitySolution 433 436 +3
total +4

References to deprecated APIs

id before after diff
maps 41 27 -14

Total ESLint disabled count

id before after diff
securitySolution 512 515 +3

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @sebelga

Copy link
Contributor

@nreese nreese left a comment

Choose a reason for hiding this comment

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

LGTM
code review, tested in chrome

Copy link
Contributor

@thomasneirynck thomasneirynck left a comment

Choose a reason for hiding this comment

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

hi @sebelga

this proposal looks really straightforward. Only some nits and small Qs thx!

@@ -44,7 +44,6 @@ export const getHttp = () => coreStart.http;
export const getExecutionContextService = () => coreStart.executionContext;
export const getTimeFilter = () => pluginsStart.data.query.timefilter.timefilter;
export const getToasts = () => coreStart.notifications.toasts;
export const getSavedObjectsClient = () => coreStart.savedObjects.client;
Copy link
Contributor

Choose a reason for hiding this comment

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

😄

@sebelga
Copy link
Contributor Author

sebelga commented Apr 13, 2023

Thanks for the review @nreese and @thomasneirynck 👍 !

@sebelga sebelga merged commit 42a893d into elastic:main Apr 13, 2023
@kibanamachine kibanamachine added v8.8.0 backport:skip This commit does not require backporting labels Apr 13, 2023
@sebelga sebelga deleted the content-management/maps-onboard branch April 13, 2023 10:46
@thomasneirynck
Copy link
Contributor

Part of #157043

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Content Management User generated content (saved objects) management Feature:Maps Project:BWCA compliance Work effort necessary for Serverless MVP, e.g. HTTP versioning, SO API deprecation work. Project:Serverless Work as part of the Serverless project for its initial release release_note:skip Skip the PR/issue when compiling release notes Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas Team:SharedUX Team label for AppEx-SharedUX (formerly Global Experience) v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[CM] Onboard maps type
10 participants