-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Remove spacesOss plugin #109258
Remove spacesOss plugin #109258
Conversation
This was originally built for only the "share to spaces" components to consume. However, we now have a need for other consumers too. I renamed it to "spacesDataPromise" and I changed the type for each entry, removing the specific "cannotShareToSpace" flag in favor of a generic "isAuthorizedForPurpose" function that can be used for any purpose.
Now uses spacesDataPromise instead of fetching all spaces each time the flyout is opened.
The dashboard and savedObjectsManagement plugins now both depend on the spaces plugin directly!
The maps plugin was missing references, this is just now starting to cause the type checker to fail due to a yet-to-be determined in our TS configuration.
Note: I did this after rebasing onto 3cb3984.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
limits.yml LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Author's notes for reviewers. Again.
{ "path": "../../../src/plugins/dashboard/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/inspector/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/data/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/ui_actions/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/navigation/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/expressions/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/visualizations/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/embeddable/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/saved_objects/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/share/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/presentation_util/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/home/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/charts/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/usage_collection/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/kibana_react/tsconfig.json" }, | ||
{ "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, | ||
{ "path": "../features/tsconfig.json" }, | ||
{ "path": "../licensing/tsconfig.json" }, | ||
{ "path": "../file_upload/tsconfig.json" }, | ||
{ "path": "../saved_objects_tagging/tsconfig.json" }, | ||
{ "path": "../security/tsconfig.json" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #108975 (comment):
@elastic/kibana-gis it seems these TS references were mistakenly omitted from your
tsconfig.json
file. Speaking with @spalger it seems there is a bug in the TS checker which did not surface until my other (unrelated) changes in this PR.TL;DR these references should have always been here 👍
// This is derived from the function of the same name in the savedObjectsManagement plugin | ||
export function processImportResponse( | ||
response: SavedObjectsImportResponse | ||
): ProcessedImportResponse { | ||
const { success, errors = [], successResults = [] } = response; | ||
const failedImports = errors.map<FailedImport>(({ error, ...obj }) => ({ obj, error })); | ||
return { | ||
success, | ||
failedImports, | ||
successfulImports: successResults, | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #108975 (comment):
I needed to remove this to handle a cyclic dependency between the
spaces
andsavedObjectsManagement
plugin.Since copy-to-space was implemented as a thin veneer over export/import, the CTS flyout used this existing
processImportResponse
function from thesavedObjectsManagement
plugin to process the import response.Turns out we could pare this down quite a bit, we didn't need a lot of what the original function provided for CTS. So I decided to just recreate a CTS-specific function here to remove that problematic dependency 👍
async function getShareToSpacesData( | ||
spacesManager: SpacesManager, | ||
feature?: string | ||
): Promise<ShareToSpacesData> { | ||
async function getSpacesData(spacesManager: SpacesManager, feature?: string): Promise<SpacesData> { | ||
const spaces = await spacesManager.getSpaces({ includeAuthorizedPurposes: true }); | ||
const activeSpace = await spacesManager.getActiveSpace(); | ||
const spacesMap = spaces | ||
.map<ShareToSpaceTarget>(({ authorizedPurposes, disabledFeatures, ...space }) => { | ||
.map<SpacesDataEntry>(({ authorizedPurposes, disabledFeatures, ...space }) => { | ||
const isActiveSpace = space.id === activeSpace.id; | ||
const cannotShareToSpace = authorizedPurposes?.shareSavedObjectsIntoSpace === false; | ||
const isFeatureDisabled = feature !== undefined && disabledFeatures.includes(feature); | ||
return { | ||
...space, | ||
...(isActiveSpace && { isActiveSpace }), | ||
...(cannotShareToSpace && { cannotShareToSpace }), | ||
...(isFeatureDisabled && { isFeatureDisabled }), | ||
isAuthorizedForPurpose: (purpose: GetAllSpacesPurpose) => | ||
// If authorizedPurposes is not present, then Security is disabled; normally in a situation like this we would "fail-secure", but | ||
// in this case we are dealing with an abstraction over the client-side UI capabilities. There is no chance for privilege | ||
// escalation here, and the correct behavior is that if Security is disabled, the user is implicitly authorized to do everything. | ||
authorizedPurposes ? authorizedPurposes[purpose] === true : true, | ||
}; | ||
}) | ||
.reduce((acc, cur) => acc.set(cur.id, cur), new Map<string, ShareToSpaceTarget>()); | ||
.reduce((acc, cur) => acc.set(cur.id, cur), new Map<string, SpacesDataEntry>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #108975 (comment):
This function is run when the SpacesContext provider is first mounted. It fetches all spaces and passes them to consumers via the context
value
.This was originally purpose-built for the share-to-space flyout, but I renamed it and added a generic
isAuthorizedForPurpose
function. I have two motivations behind this:
- The CTS flyout can also reuse this data, so we don't need to fetch all spaces every time the flyout is rendered
- Other consumers can reuse this data in the future so they don't have to fetch all spaces too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alerting changes LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presentation team changes LGTM! It's awesome that we get to simplify the OSS / x-pack relationship now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ML changes LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maps changes LGTM
💚 Build Succeeded
Metrics [docs]Module Count
Async chunks
Page load bundle
Unknown metric groupsAPI count
API count missing comments
Non-exported public API item count
References to deprecated APIs
To update your PR or re-run it, just comment with: |
ack: will review tomorrow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this!
const context = createContext<Partial<SpacesReactContextValue<KibanaServices>>>({}); | ||
const context = createContext<Partial<SpacesReactContextValue<Partial<CoreStart>>>>({}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not related to this PR, was already there: Why was the spaces context extending KibanaServices
, and why do we need to have it now extends Partial<CoreStart>
? Why is SpacesReactContextValue
extending anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I based this implementation off of the Kibana React Context:
export const context = createContext<KibanaReactContextValue<KibanaServices>>(defaultContextValue); |
export type KibanaServices = Partial<CoreStart>; |
The useSpaces
context also provides access to core start services so you don't need to use two different context providers in the client consumer. I guess it was written with this generic type so you can specify what core services you need to use.
export const getUiApi = ({ spacesManager, getStartServices }: GetUiApiOptions): SpacesApiUi => { | ||
const components = getComponents({ spacesManager, getStartServices }); | ||
|
||
return { | ||
components, | ||
redirectLegacyUrl: createRedirectLegacyUrl(getStartServices), | ||
useSpaces, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this addition.
However, the useSpaces
hook will only work for functional components (not class components). Class components will need to either have a reference of the context class to use the contextType
property, or have access to the context.Consumer
component (and most of the 'legacy' 'controller' components are class-based).
Any objection adding a getSpacesContextConsumer
API to SpacesApiUiComponent
? If that's fine, I could do it directly in #109196
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure that's fine, thanks for adding it!
ACK: reviewing... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks!
@@ -1,1320 +0,0 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: do you know why we still mention spacesOss
in spaces.json (and in triggers_actions_ui.json
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this was intentional. We don't automatically require regenerating the new API docs for each PR (yet); whenever we next regenerate them that will go away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, nice, thanks
const start = service.start(spacesPluginMock.createStartContract()); | ||
expect(start.getAll()).toEqual([ | ||
column, | ||
// expect.any(ShareToSpaceSavedObjectsManagementColumn), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You left a clarifying comment in column_service.ts
, would you mind leaving a brief note why we keep commented code here as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, auto-merge already happened when the PR was approved 😄 I'll make a mental note to do this next time I'm in the code.
FWIW the existing test will fail if the code in column_service.ts
is uncommented, and this needs to be uncommented to make it pass.
export interface ProcessedImportResponse { | ||
success: boolean; | ||
failedImports: FailedImport[]; | ||
successfulImports: SavedObjectsImportSuccess[]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: type names feel a bit inconsistent:
failedImports
-FailedImport[]
successfulImports
-SavedObjectsImportSuccess[]
Why not SuccessfullImport[]
(or SavedObjectImportFailure[]
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, SavedObjectsImportFailure
and SavedObjectsImportSuccess
both come from Core.
SavedObjectsImportFailure
is older and commingles the error with the rest of the object fields. So basically the entire point of this function is to "un-commingle" that into FailedImport
😅.
I added SavedObjectsImportSuccess
later, but I was able to use it on the client side without any additional processing.
I can add this:
export type SuccessfulImport = FailedImport;
next time I'm in the code, agree it would make things clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation!
💔 Backport failed
To backport manually run: |
# Conflicts: # .eslintrc.js # .github/CODEOWNERS # src/plugins/dashboard/kibana.json
Resubmitting #108975.
Partially resolves #104152.
spacesOss
plugin (fromdashboard
andsavedObjectsManagement
plugins)savedObjectsManagement
plugin to register the Spaces columns/actions directlyspacesOss
plugin completelyspaces
pluginuseSpaces
function for external consumers to use the Spaces Context provider