Create Spaces OSS plugin (#87585)

This commit is contained in:
Joe Portner 2021-01-12 12:26:40 -05:00 committed by GitHub
parent 5fb5605ffa
commit 07a3756a62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 496 additions and 108 deletions

1
.github/CODEOWNERS vendored
View file

@ -236,6 +236,7 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib
# Security
/src/core/server/csp/ @elastic/kibana-security @elastic/kibana-core
/src/plugins/security_oss/ @elastic/kibana-security
/src/plugins/spaces_oss/ @elastic/kibana-security
/test/security_functional/ @elastic/kibana-security
/x-pack/plugins/spaces/ @elastic/kibana-security
/x-pack/plugins/encrypted_saved_objects/ @elastic/kibana-security

View file

@ -194,6 +194,10 @@ so they can properly protect the data within their clusters.
|Replaces the legacy ui/share module for registering share context menus.
|{kib-repo}blob/{branch}/src/plugins/spaces_oss/README.md[spacesOss]
|Bridge plugin for consumption of the Spaces feature from OSS plugins.
|{kib-repo}blob/{branch}/src/plugins/telemetry/README.md[telemetry]
|Telemetry allows Kibana features to have usage tracked in the wild. The general term "telemetry" refers to multiple things:

View file

@ -106,3 +106,4 @@ pageLoadAssetSize:
stackAlerts: 29684
presentationUtil: 28545
runtimeFieldEditor: 46986
spacesOss: 18817

View file

@ -0,0 +1,3 @@
# SpacesOss
Bridge plugin for consumption of the Spaces feature from OSS plugins.

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { Space } from './types';

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export interface Space {
id: string;
name: string;
description?: string;
color?: string;
initials?: string;
disabledFeatures: string[];
_reserved?: boolean;
imageUrl?: string;
}

View file

@ -0,0 +1,24 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/src/plugins/spaces_oss'],
};

View file

@ -0,0 +1,8 @@
{
"id": "spacesOss",
"version": "kibana",
"server": false,
"ui": true,
"requiredPlugins": [],
"optionalPlugins": []
}

View file

@ -0,0 +1,30 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { of } from 'rxjs';
import { SpacesApi } from './api';
const createApiMock = (): jest.Mocked<SpacesApi> => ({
activeSpace$: of(),
getActiveSpace: jest.fn(),
});
export const spacesApiMock = {
create: createApiMock,
};

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Observable } from 'rxjs';
import { Space } from '../common';
/**
* @public
*/
export interface SpacesApi {
readonly activeSpace$: Observable<Space>;
getActiveSpace(): Promise<Space>;
}

View file

@ -0,0 +1,26 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { SpacesOssPlugin } from './plugin';
export { SpacesOssPluginSetup, SpacesOssPluginStart } from './types';
export { SpacesApi } from './api';
export const plugin = () => new SpacesOssPlugin();

View file

@ -0,0 +1,35 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { spacesApiMock } from '../api.mock';
import { SpacesOssPluginSetup, SpacesOssPluginStart } from '..';
const createSetupContract = (): jest.Mocked<SpacesOssPluginSetup> => ({
registerSpacesApi: jest.fn(),
});
const createStartContract = (): jest.Mocked<SpacesOssPluginStart> => ({
isSpacesAvailable: true,
...spacesApiMock.create(),
});
export const spacesOssPluginMock = {
createSetupContract,
createStartContract,
};

View file

@ -0,0 +1,65 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { spacesApiMock } from './api.mock';
import { SpacesOssPlugin } from './plugin';
describe('SpacesOssPlugin', () => {
let plugin: SpacesOssPlugin;
beforeEach(() => {
plugin = new SpacesOssPlugin();
});
describe('#setup', () => {
it('only allows the API to be registered once', async () => {
const spacesApi = spacesApiMock.create();
const { registerSpacesApi } = plugin.setup();
expect(() => registerSpacesApi(spacesApi)).not.toThrow();
expect(() => registerSpacesApi(spacesApi)).toThrowErrorMatchingInlineSnapshot(
`"Spaces API can only be registered once"`
);
});
});
describe('#start', () => {
it('returns the spaces API if registered', async () => {
const spacesApi = spacesApiMock.create();
const { registerSpacesApi } = plugin.setup();
registerSpacesApi(spacesApi);
const { isSpacesAvailable, ...api } = plugin.start();
expect(isSpacesAvailable).toBe(true);
expect(api).toStrictEqual(spacesApi);
});
it('does not return the spaces API if not registered', async () => {
plugin.setup();
const { isSpacesAvailable, ...api } = plugin.start();
expect(isSpacesAvailable).toBe(false);
expect(Object.keys(api)).toHaveLength(0);
});
});
});

View file

@ -0,0 +1,52 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Plugin } from 'src/core/public';
import { SpacesOssPluginSetup, SpacesOssPluginStart } from './types';
import { SpacesApi } from './api';
export class SpacesOssPlugin implements Plugin<SpacesOssPluginSetup, SpacesOssPluginStart, {}, {}> {
private api?: SpacesApi;
constructor() {}
public setup() {
return {
registerSpacesApi: (provider: SpacesApi) => {
if (this.api) {
throw new Error('Spaces API can only be registered once');
}
this.api = provider;
},
};
}
public start() {
if (this.api) {
return {
isSpacesAvailable: true as true,
...this.api!,
};
} else {
return {
isSpacesAvailable: false as false,
};
}
}
}

View file

@ -0,0 +1,39 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { SpacesApi } from './api';
interface SpacesAvailableStartContract extends SpacesApi {
isSpacesAvailable: true;
}
interface SpacesUnavailableStartContract {
isSpacesAvailable: false;
}
export interface SpacesOssPluginSetup {
/**
* Register a provider for the Spaces API.
*
* Only one provider can be registered, subsequent calls to this method will fail.
*/
registerSpacesApi(provider: SpacesApi): void;
}
export type SpacesOssPluginStart = SpacesAvailableStartContract | SpacesUnavailableStartContract;

View file

@ -0,0 +1,17 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true
},
"include": [
"common/**/*",
"public/**/*",
],
"references": [
{ "path": "../../core/tsconfig.json" },
]
}

View file

@ -27,9 +27,10 @@
"src/plugins/navigation/**/*",
"src/plugins/newsfeed/**/*",
"src/plugins/saved_objects/**/*",
"src/plugins/security_oss/**/*",
"src/plugins/saved_objects_tagging_oss/**/*",
"src/plugins/security_oss/**/*",
"src/plugins/share/**/*",
"src/plugins/spaces_oss/**/*",
"src/plugins/telemetry/**/*",
"src/plugins/telemetry_collection_manager/**/*",
"src/plugins/ui_actions/**/*",
@ -67,6 +68,7 @@
{ "path": "./src/plugins/saved_objects_tagging_oss/tsconfig.json" },
{ "path": "./src/plugins/security_oss/tsconfig.json" },
{ "path": "./src/plugins/share/tsconfig.json" },
{ "path": "./src/plugins/spaces_oss/tsconfig.json" },
{ "path": "./src/plugins/telemetry/tsconfig.json" },
{ "path": "./src/plugins/telemetry_collection_manager/tsconfig.json" },
{ "path": "./src/plugins/ui_actions/tsconfig.json" },

View file

@ -27,6 +27,7 @@
{ "path": "./src/plugins/presentation_util/tsconfig.json" },
{ "path": "./src/plugins/security_oss/tsconfig.json" },
{ "path": "./src/plugins/share/tsconfig.json" },
{ "path": "./src/plugins/spaces_oss/tsconfig.json" },
{ "path": "./src/plugins/telemetry/tsconfig.json" },
{ "path": "./src/plugins/telemetry_collection_manager/tsconfig.json" },
{ "path": "./src/plugins/ui_actions/tsconfig.json" },

View file

@ -9,7 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { EuiButtonEmpty, EuiOverlayMask, EuiButton } from '@elastic/eui';
import { EuiFlyout } from '@elastic/eui';
import { EuiFlyoutHeader, EuiTitle, EuiFlyoutBody, EuiFlyoutFooter } from '@elastic/eui';
import { Space } from '../../../../../../../../spaces/common/model/space';
import { Space } from '../../../../../../../../spaces/public';
import { Role } from '../../../../../../../common/model';
import { PrivilegeSummaryTable } from './privilege_summary_table';
import { KibanaPrivileges } from '../../../../model';

View file

@ -18,7 +18,7 @@ import {
EuiAccordion,
EuiTitle,
} from '@elastic/eui';
import { Space } from '../../../../../../../../spaces/common/model/space';
import { Space } from '../../../../../../../../spaces/public';
import { Role, RoleKibanaPrivilege } from '../../../../../../../common/model';
import { isGlobalPrivilegeDefinition } from '../../../privilege_utils';
import { FeatureTableCell } from '../feature_table_cell';

View file

@ -7,8 +7,7 @@
import { EuiComboBox, EuiComboBoxOptionOption, EuiHealth, EuiHighlight } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { Component } from 'react';
import { getSpaceColor } from '../../../../../../../../spaces/public';
import { Space } from '../../../../../../../../spaces/common/model/space';
import { getSpaceColor, Space } from '../../../../../../../../spaces/public';
const spaceToOption = (space?: Space, currentSelection?: 'global' | 'spaces') => {
if (!space) {

View file

@ -14,7 +14,7 @@ import { deepFreeze } from '@kbn/std';
import { Space } from '../../../spaces/server';
import { authorizationMock } from '../authorization/index.mock';
import { AuthorizationServiceSetup } from '../authorization';
import { GetAllSpacesPurpose } from '../../../spaces/common/model/types';
import { GetAllSpacesPurpose } from '../../../spaces/server';
import { CheckPrivilegesResponse } from '../authorization/types';
import { LegacySpacesAuditLogger } from './legacy_audit_logger';
import { SavedObjectsErrorHelpers } from 'src/core/server';

View file

@ -6,8 +6,13 @@
import Boom from '@hapi/boom';
import { KibanaRequest } from 'src/core/server';
import { GetAllSpacesPurpose, GetSpaceResult } from '../../../spaces/common/model/types';
import { Space, ISpacesClient } from '../../../spaces/server';
import {
Space,
ISpacesClient,
GetAllSpacesOptions,
GetAllSpacesPurpose,
GetSpaceResult,
} from '../../../spaces/server';
import { LegacySpacesAuditLogger } from './legacy_audit_logger';
import { AuthorizationServiceSetup } from '../authorization';
import { AuditLogger, EventOutcome, SpaceAuditAction, spaceAuditEvent } from '../audit';
@ -29,11 +34,6 @@ const PURPOSE_PRIVILEGE_MAP: Record<
],
};
interface GetAllSpacesOptions {
purpose?: GetAllSpacesPurpose;
includeAuthorizedPurposes?: boolean;
}
export class SecureSpacesClientWrapper implements ISpacesClient {
private readonly useRbac = this.authorization.mode.useRbacForRequest(this.request);

View file

@ -7,3 +7,4 @@
export { isReservedSpace } from './is_reserved_space';
export { MAX_SPACE_INITIALS, SPACE_SEARCH_COUNT_THRESHOLD, ENTER_SPACE_PATH } from './constants';
export { addSpaceIdToPath, getSpaceIdFromPath } from './lib/spaces_url_parser';
export { GetAllSpacesOptions, GetAllSpacesPurpose, GetSpaceResult } from './types';

View file

@ -5,7 +5,7 @@
*/
import { isReservedSpace } from './is_reserved_space';
import { Space } from './model/space';
import { Space } from '../../../../src/plugins/spaces_oss/common';
test('it returns true for reserved spaces', () => {
const space: Space = {

View file

@ -5,7 +5,7 @@
*/
import { get } from 'lodash';
import { Space } from './model/space';
import { Space } from '../../../../src/plugins/spaces_oss/common';
/**
* Returns whether the given Space is reserved or not.

View file

@ -1,16 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export interface Space {
id: string;
name: string;
description?: string;
color?: string;
initials?: string;
disabledFeatures: string[];
_reserved?: boolean;
imageUrl?: string;
}

View file

@ -4,7 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Space } from './space';
import type { Space } from '../../../../src/plugins/spaces_oss/common';
export interface GetAllSpacesOptions {
purpose?: GetAllSpacesPurpose;
includeAuthorizedPurposes?: boolean;
}
export type GetAllSpacesPurpose =
| 'any'

View file

@ -3,7 +3,7 @@
"version": "8.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "spaces"],
"requiredPlugins": ["features", "licensing"],
"requiredPlugins": ["features", "licensing", "spacesOss"],
"optionalPlugins": [
"advancedSettings",
"home",

View file

@ -5,7 +5,7 @@
*/
import React from 'react';
import { AdvancedSettingsSetup } from 'src/plugins/advanced_settings/public';
import { Space } from '../../common/model/space';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { AdvancedSettingsTitle, AdvancedSettingsSubtitle } from './components';
interface SetupDeps {

View file

@ -7,7 +7,7 @@
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { Fragment, useState, useEffect } from 'react';
import { Space } from '../../../../common/model/space';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
interface Props {
getActiveSpace: () => Promise<Space>;

View file

@ -7,7 +7,7 @@
import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { useState, useEffect } from 'react';
import { Space } from '../../../../common/model/space';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { SpaceAvatar } from '../../../space_avatar';
interface Props {

View file

@ -8,7 +8,7 @@ import './copy_status_summary_indicator.scss';
import React, { Fragment } from 'react';
import { EuiLoadingSpinner, EuiIconTip, EuiBadge } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { ImportRetry } from '../types';
import { ResolveAllConflicts } from './resolve_all_conflicts';
import { SummarizedCopyToSpaceResult } from '..';

View file

@ -9,7 +9,7 @@ import { mountWithIntl, nextTick } from '@kbn/test/jest';
import { CopySavedObjectsToSpaceFlyout } from './copy_to_space_flyout';
import { CopyToSpaceForm } from './copy_to_space_form';
import { EuiLoadingSpinner, EuiEmptyPrompt } from '@elastic/eui';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { findTestSubject } from '@kbn/test/jest';
import { SelectableSpacesControl } from './selectable_spaces_control';
import { CopyModeControl } from './copy_mode_control';

View file

@ -27,7 +27,7 @@ import {
processImportResponse,
SavedObjectsManagementRecord,
} from '../../../../../../src/plugins/saved_objects_management/public';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { SpacesManager } from '../../spaces_manager';
import { ProcessingCopyToSpace } from './processing_copy_to_space';
import { CopyToSpaceFlyoutFooter } from './copy_to_space_flyout_footer';

View file

@ -9,7 +9,7 @@ import { EuiSpacer, EuiTitle, EuiFormRow } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { CopyOptions } from '../types';
import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { SelectableSpacesControl } from './selectable_spaces_control';
import { CopyModeControl, CopyMode } from './copy_mode_control';

View file

@ -17,7 +17,7 @@ import {
ProcessedImportResponse,
SavedObjectsManagementRecord,
} from 'src/plugins/saved_objects_management/public';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { CopyOptions, ImportRetry } from '../types';
import { SpaceResult, SpaceResultProcessing } from './space_result';
import { summarizeCopyResult } from '..';

View file

@ -8,8 +8,8 @@ import './selectable_spaces_control.scss';
import React, { Fragment } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiSelectable, EuiSelectableOption, EuiLoadingSpinner, EuiIconTip } from '@elastic/eui';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { SpaceAvatar } from '../../space_avatar';
import { Space } from '../../../common/model/space';
interface Props {
spaces: Space[];

View file

@ -15,9 +15,9 @@ import {
EuiLoadingSpinner,
} from '@elastic/eui';
import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { SummarizedCopyToSpaceResult } from '../index';
import { SpaceAvatar } from '../../space_avatar';
import { Space } from '../../../common/model/space';
import { CopyStatusSummaryIndicator } from './copy_status_summary_indicator';
import { SpaceCopyResultDetails } from './space_result_details';
import { ImportRetry } from '../types';

View file

@ -24,7 +24,7 @@ import { EuiSuperSelect } from '@elastic/eui';
import moment from 'moment';
import { SummarizedCopyToSpaceResult } from '../index';
import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { CopyStatusIndicator } from './copy_status_indicator';
import { ImportRetry } from '../types';

View file

@ -6,16 +6,17 @@
import { SpacesPlugin } from './plugin';
export { Space } from '../common/model/space';
export { GetSpaceResult } from '../common/model/types';
export { SpaceAvatar, getSpaceColor, getSpaceImageUrl, getSpaceInitials } from './space_avatar';
export { SpacesPluginSetup, SpacesPluginStart } from './plugin';
export { SpacesManager } from './spaces_manager';
export { GetAllSpacesOptions, GetAllSpacesPurpose, GetSpaceResult } from '../common';
// re-export types from oss definition
export type { Space } from '../../../../src/plugins/spaces_oss/common';
export const plugin = () => {
return new SpacesPlugin();
};

View file

@ -24,8 +24,8 @@ import {
} from '@elastic/eui';
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
import React, { ChangeEvent, Component } from 'react';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { SpacesManager } from '../../../spaces_manager';
import { Space } from '../../../../../../plugins/spaces/common/model/space';
interface Props {
space: Space;

View file

@ -17,8 +17,8 @@ import {
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import React, { ChangeEvent, Component, Fragment } from 'react';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { isReservedSpace } from '../../../../common';
import { Space } from '../../../../common/model/space';
import { SpaceAvatar } from '../../../space_avatar';
import { SpaceValidator, toSpaceIdentifier } from '../../lib';
import { SectionPanel } from '../section_panel';

View file

@ -17,7 +17,7 @@ import {
isValidHex,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Space } from '../../../../common/model/space';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { imageTypes, encode } from '../../../../common/lib/dataurl';
import { getSpaceColor, getSpaceInitials } from '../../../space_avatar';
import { MAX_SPACE_INITIALS } from '../../../../common';

View file

@ -7,7 +7,7 @@
import { EuiFieldText, EuiFormRow, EuiLink } from '@elastic/eui';
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
import React, { ChangeEvent, Component, Fragment } from 'react';
import { Space } from '../../../../common/model/space';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { SpaceValidator, toSpaceIdentifier } from '../../lib';
interface Props {

View file

@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { Component, Fragment } from 'react';
import { NotificationsStart } from 'src/core/public';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { SpacesManager } from '../../spaces_manager';
import { ConfirmDeleteModal } from '../components/confirm_delete_modal';

View file

@ -9,8 +9,8 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { Component, Fragment, ReactNode } from 'react';
import { ApplicationStart } from 'kibana/public';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { KibanaFeatureConfig } from '../../../../../../plugins/features/public';
import { Space } from '../../../../common/model/space';
import { getEnabledFeatures } from '../../lib/feature_utils';
import { SectionPanel } from '../section_panel';
import { FeatureTable } from './feature_table';

View file

@ -23,8 +23,8 @@ import { i18n } from '@kbn/i18n';
import { AppCategory } from 'kibana/public';
import _ from 'lodash';
import React, { ChangeEvent, Component, ReactElement } from 'react';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { KibanaFeatureConfig } from '../../../../../../plugins/features/public';
import { Space } from '../../../../common/model/space';
import { getEnabledFeatures } from '../../lib/feature_utils';
import './feature_table.scss';

View file

@ -19,9 +19,9 @@ import { i18n } from '@kbn/i18n';
import _ from 'lodash';
import React, { Component, Fragment } from 'react';
import { ApplicationStart, Capabilities, NotificationsStart, ScopedHistory } from 'src/core/public';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { KibanaFeature, FeaturesPluginStart } from '../../../../features/public';
import { isReservedSpace } from '../../../common';
import { Space } from '../../../common/model/space';
import { SpacesManager } from '../../spaces_manager';
import { SecureSpaceMessage, UnauthorizedPrompt } from '../components';
import { toSpaceIdentifier } from '../lib';

View file

@ -8,8 +8,8 @@ import React from 'react';
import { EuiBadge, EuiToolTip } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { isReservedSpace } from '../../../common';
import { Space } from '../../../common/model/space';
interface Props {
space?: Space;

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { isReservedSpace } from '../../../common/is_reserved_space';
import { Space } from '../../../common/model/space';
import { isValidSpaceIdentifier } from './space_identifier_utils';
interface SpaceValidatorOptions {

View file

@ -21,10 +21,10 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { ApplicationStart, Capabilities, NotificationsStart, ScopedHistory } from 'src/core/public';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { KibanaFeature, FeaturesPluginStart } from '../../../../features/public';
import { isReservedSpace } from '../../../common';
import { DEFAULT_SPACE_ID } from '../../../common/constants';
import { Space } from '../../../common/model/space';
import { SpaceAvatar } from '../../space_avatar';
import { getSpacesFeatureDescription } from '../../constants';
import { SpacesManager } from '../..//spaces_manager';

View file

@ -15,8 +15,8 @@ import {
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
import React, { Component, ReactElement } from 'react';
import { Capabilities, ApplicationStart } from 'src/core/public';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { addSpaceIdToPath, SPACE_SEARCH_COUNT_THRESHOLD, ENTER_SPACE_PATH } from '../../../common';
import { Space } from '../../../common/model/space';
import { ManageSpacesButton } from './manage_spaces_button';
import { SpaceAvatar } from '../../space_avatar';

View file

@ -13,7 +13,7 @@ import {
import React, { Component } from 'react';
import { Capabilities, ApplicationStart } from 'src/core/public';
import { Subscription } from 'rxjs';
import { Space } from '../../common/model/space';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { SpaceAvatar } from '../space_avatar';
import { SpacesManager } from '../spaces_manager';
import { SpacesDescription } from './components/spaces_description';

View file

@ -6,21 +6,24 @@
import { coreMock } from 'src/core/public/mocks';
import { SpacesPlugin } from './plugin';
import { spacesOssPluginMock } from '../../../../src/plugins/spaces_oss/public/mocks';
import { homePluginMock } from '../../../../src/plugins/home/public/mocks';
import {
managementPluginMock,
createManagementSectionMock,
} from '../../../../src/plugins/management/public/mocks';
import { advancedSettingsMock } from '../../../../src/plugins/advanced_settings/public/mocks';
import { featuresPluginMock } from '../../features/public/mocks';
describe('Spaces plugin', () => {
describe('#setup', () => {
it('should register the space selector app', () => {
it('should register the spaces API and the space selector app', () => {
const coreSetup = coreMock.createSetup();
const spacesOss = spacesOssPluginMock.createSetupContract();
const plugin = new SpacesPlugin();
plugin.setup(coreSetup, {});
plugin.setup(coreSetup, { spacesOss });
expect(spacesOss.registerSpacesApi).toHaveBeenCalledTimes(1);
expect(coreSetup.application.register).toHaveBeenCalledWith(
expect.objectContaining({
@ -34,6 +37,7 @@ describe('Spaces plugin', () => {
it('should register the management and feature catalogue sections when the management and home plugins are both available', () => {
const coreSetup = coreMock.createSetup();
const spacesOss = spacesOssPluginMock.createSetupContract();
const home = homePluginMock.createSetupContract();
const management = managementPluginMock.createSetupContract();
@ -44,6 +48,7 @@ describe('Spaces plugin', () => {
const plugin = new SpacesPlugin();
plugin.setup(coreSetup, {
spacesOss,
management,
home,
});
@ -64,10 +69,11 @@ describe('Spaces plugin', () => {
it('should register the advanced settings components if the advanced_settings plugin is available', () => {
const coreSetup = coreMock.createSetup();
const spacesOss = spacesOssPluginMock.createSetupContract();
const advancedSettings = advancedSettingsMock.createSetupContract();
const plugin = new SpacesPlugin();
plugin.setup(coreSetup, { advancedSettings });
plugin.setup(coreSetup, { spacesOss, advancedSettings });
expect(advancedSettings.component.register.mock.calls).toMatchInlineSnapshot(`
Array [
@ -89,12 +95,13 @@ describe('Spaces plugin', () => {
describe('#start', () => {
it('should register the spaces nav control', () => {
const coreSetup = coreMock.createSetup();
const spacesOss = spacesOssPluginMock.createSetupContract();
const coreStart = coreMock.createStart();
const plugin = new SpacesPlugin();
plugin.setup(coreSetup, {});
plugin.setup(coreSetup, { spacesOss });
plugin.start(coreStart, { features: featuresPluginMock.createStart() });
plugin.start(coreStart);
expect(coreStart.chrome.navControls.registerLeft).toHaveBeenCalled();
});

View file

@ -5,6 +5,7 @@
*/
import { CoreSetup, CoreStart, Plugin, StartServicesAccessor } from 'src/core/public';
import { SpacesOssPluginSetup, SpacesApi } from 'src/plugins/spaces_oss/public';
import { HomePublicPluginSetup } from 'src/plugins/home/public';
import { SavedObjectsManagementPluginSetup } from 'src/plugins/saved_objects_management/public';
import { ManagementStart, ManagementSetup } from 'src/plugins/management/public';
@ -21,6 +22,7 @@ import { ManagementService } from './management';
import { spaceSelectorApp } from './space_selector';
export interface PluginsSetup {
spacesOss: SpacesOssPluginSetup;
advancedSettings?: AdvancedSettingsSetup;
home?: HomePublicPluginSetup;
management?: ManagementSetup;
@ -42,7 +44,7 @@ export class SpacesPlugin implements Plugin<SpacesPluginSetup, SpacesPluginStart
private managementService?: ManagementService;
public setup(core: CoreSetup, plugins: PluginsSetup) {
public setup(core: CoreSetup<{}, SpacesPluginStart>, plugins: PluginsSetup) {
this.spacesManager = new SpacesManager(core.http);
if (plugins.home) {
@ -89,16 +91,15 @@ export class SpacesPlugin implements Plugin<SpacesPluginSetup, SpacesPluginStart
spacesManager: this.spacesManager,
});
plugins.spacesOss.registerSpacesApi(this.createSpacesApi());
return {};
}
public start(core: CoreStart, plugins: PluginsStart) {
public start(core: CoreStart) {
initSpacesNavControl(this.spacesManager, core);
return {
activeSpace$: this.spacesManager.onActiveSpaceChange$,
getActiveSpace: () => this.spacesManager.getActiveSpace(),
};
return this.createSpacesApi();
}
public stop() {
@ -107,4 +108,11 @@ export class SpacesPlugin implements Plugin<SpacesPluginSetup, SpacesPluginStart
this.managementService = undefined;
}
}
private createSpacesApi(): SpacesApi {
return {
activeSpace$: this.spacesManager.onActiveSpaceChange$,
getActiveSpace: () => this.spacesManager.getActiveSpace(),
};
}
}

View file

@ -9,7 +9,7 @@ import { mountWithIntl, nextTick } from '@kbn/test/jest';
import { ShareSavedObjectsToSpaceFlyout } from './share_to_space_flyout';
import { ShareToSpaceForm } from './share_to_space_form';
import { EuiLoadingSpinner, EuiSelectable } from '@elastic/eui';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { findTestSubject } from '@kbn/test/jest';
import { SelectableSpacesControl } from './selectable_spaces_control';
import { act } from '@testing-library/react';

View file

@ -23,8 +23,8 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { ToastsStart } from 'src/core/public';
import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public';
import { GetSpaceResult } from '../../../common';
import { ALL_SPACES_ID, UNKNOWN_SPACE } from '../../../common/constants';
import { GetSpaceResult } from '../../../common/model/types';
import { SpacesManager } from '../../spaces_manager';
import { ShareToSpaceForm } from './share_to_space_form';
import { ShareOptions, SpaceTarget } from '../types';

View file

@ -5,7 +5,7 @@
*/
import { VISUALIZATION_COLORS } from '@elastic/eui';
import { Space } from '../../common/model/space';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { MAX_SPACE_INITIALS } from '../../common';
// code point for lowercase "a"

View file

@ -6,8 +6,8 @@
import { EuiAvatar, isValidHex } from '@elastic/eui';
import React, { FC } from 'react';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { MAX_SPACE_INITIALS } from '../../common';
import { Space } from '../../common/model/space';
import { getSpaceColor, getSpaceInitials, getSpaceImageUrl } from './space_attributes';
interface Props {

View file

@ -7,7 +7,7 @@
import './space_cards.scss';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React, { Component } from 'react';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { SpaceCard } from './space_card';
interface Props {

View file

@ -6,7 +6,7 @@
import React from 'react';
import { shallowWithIntl } from '@kbn/test/jest';
import { Space } from '../../common/model/space';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { SpaceSelector } from './space_selector';
import { spacesManagerMock } from '../spaces_manager/mocks';

View file

@ -26,7 +26,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
import { CoreStart } from 'src/core/public';
import { Space } from '../../common/model/space';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { SpaceCards } from './components';
import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../common/constants';
import { SpacesManager } from '../spaces_manager';

View file

@ -5,7 +5,7 @@
*/
import { of, Observable } from 'rxjs';
import { Space } from '../../common/model/space';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { SpacesManager } from './spaces_manager';
function createSpacesManagerMock() {

View file

@ -6,15 +6,13 @@
import { Observable, BehaviorSubject } from 'rxjs';
import { skipWhile } from 'rxjs/operators';
import { HttpSetup } from 'src/core/public';
import { SavedObjectsManagementRecord } from 'src/plugins/saved_objects_management/public';
import { Space } from '../../common/model/space';
import { GetAllSpacesPurpose, GetSpaceResult } from '../../common/model/types';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { GetAllSpacesOptions, GetSpaceResult } from '../../common';
import { CopySavedObjectsToSpaceResponse } from '../copy_saved_objects_to_space/types';
type SavedObject = Pick<SavedObjectsManagementRecord, 'type' | 'id'>;
interface GetAllSpacesOptions {
purpose?: GetAllSpacesPurpose;
includeAuthorizedPurposes?: boolean;
interface SavedObjectTarget {
type: string;
id: string;
}
export class SpacesManager {
@ -85,7 +83,7 @@ export class SpacesManager {
}
public async copySavedObjects(
objects: SavedObject[],
objects: SavedObjectTarget[],
spaces: string[],
includeReferences: boolean,
createNewCopies: boolean,
@ -103,7 +101,7 @@ export class SpacesManager {
}
public async resolveCopySavedObjectsErrors(
objects: SavedObject[],
objects: SavedObjectTarget[],
retries: unknown,
includeReferences: boolean,
createNewCopies: boolean
@ -133,13 +131,13 @@ export class SpacesManager {
});
}
public async shareSavedObjectAdd(object: SavedObject, spaces: string[]): Promise<void> {
public async shareSavedObjectAdd(object: SavedObjectTarget, spaces: string[]): Promise<void> {
return this.http.post(`/api/spaces/_share_saved_object_add`, {
body: JSON.stringify({ object, spaces }),
});
}
public async shareSavedObjectRemove(object: SavedObject, spaces: string[]): Promise<void> {
public async shareSavedObjectRemove(object: SavedObjectTarget, spaces: string[]): Promise<void> {
return this.http.post(`/api/spaces/_share_saved_object_remove`, {
body: JSON.stringify({ object, spaces }),
});

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { KibanaFeature } from '../../../../plugins/features/server';
import { Space } from '../../common/model/space';
import { setupCapabilitiesSwitcher } from './capabilities_switcher';
import { Capabilities, CoreSetup } from 'src/core/server';
import { coreMock, httpServerMock, loggingSystemMock } from 'src/core/server/mocks';

View file

@ -5,8 +5,8 @@
*/
import _ from 'lodash';
import { Capabilities, CapabilitiesSwitcher, CoreSetup, Logger } from 'src/core/server';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { KibanaFeature } from '../../../../plugins/features/server';
import { Space } from '../../common/model/space';
import { SpacesServiceStart } from '../spaces_service';
import { PluginsStart } from '../plugin';

View file

@ -20,7 +20,11 @@ export { addSpaceIdToPath } from '../common';
export { SpacesPluginSetup, SpacesPluginStart } from './plugin';
export { SpacesServiceSetup, SpacesServiceStart } from './spaces_service';
export { ISpacesClient } from './spaces_client';
export { Space } from '../common/model/space';
export { GetAllSpacesOptions, GetAllSpacesPurpose, GetSpaceResult } from '../common';
// re-export types from oss definition
export { Space } from '../../../../src/plugins/spaces_oss/common';
export const config: PluginConfigDescriptor = {
schema: ConfigSchema,

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Logger, CoreSetup } from 'src/core/server';
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
import { wrapError } from '../errors';
import { SpacesServiceStart } from '../../spaces_service/spaces_service';
import { PluginsSetup } from '../../plugin';

View file

@ -5,7 +5,7 @@
*/
import { schema } from '@kbn/config-schema';
import { Space } from '../../../../common/model/space';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { wrapError } from '../../../lib/errors';
import { ExternalRouteDeps } from '.';
import { createLicensedRouteHandler } from '../../lib';

View file

@ -6,7 +6,7 @@
import { schema } from '@kbn/config-schema';
import { SavedObjectsErrorHelpers } from '../../../../../../../src/core/server';
import { Space } from '../../../../common/model/space';
import { Space } from '../../../../../../../src/plugins/spaces_oss/common';
import { wrapError } from '../../../lib/errors';
import { spaceSchema } from '../../../lib/space_schema';
import { ExternalRouteDeps } from '.';

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Space } from '../../../common/model/space';
import { Space } from '../../../../../../src/plugins/spaces_oss/common';
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one

View file

@ -5,7 +5,7 @@
*/
import { DEFAULT_SPACE_ID } from '../../common/constants';
import { Space } from '../../common/model/space';
import { Space } from '../../../../../src/plugins/spaces_oss/common';
import { SpacesClient } from './spaces_client';
const createSpacesClientMock = () =>

View file

@ -6,8 +6,8 @@
import { SpacesClient } from './spaces_client';
import { ConfigType, ConfigSchema } from '../config';
import { GetAllSpacesPurpose } from '../../common/model/types';
import { savedObjectsRepositoryMock } from '../../../../../src/core/server/mocks';
import { GetAllSpacesPurpose } from '../../common';
const createMockDebugLogger = () => {
return jest.fn();

View file

@ -8,15 +8,10 @@ import Boom from '@hapi/boom';
import { omit } from 'lodash';
import { ISavedObjectsRepository, SavedObject } from 'src/core/server';
import { PublicMethodsOf } from '@kbn/utility-types';
import { Space } from 'src/plugins/spaces_oss/common';
import { GetAllSpacesOptions, GetAllSpacesPurpose, GetSpaceResult } from '../../common';
import { isReservedSpace } from '../../common';
import { Space } from '../../common/model/space';
import { ConfigType } from '../config';
import { GetAllSpacesPurpose, GetSpaceResult } from '../../common/model/types';
export interface GetAllSpacesOptions {
purpose?: GetAllSpacesPurpose;
includeAuthorizedPurposes?: boolean;
}
const SUPPORTED_GET_SPACE_PURPOSES: GetAllSpacesPurpose[] = [
'any',