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

[Dashboard Navigation] Make links panel available under technical preview #166896

Merged
merged 69 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
2cb977f
[Dashboard Navigation] Create and register navigation embeddable plug…
nickpeihl May 4, 2023
41287f7
Merge branch 'main' into navigation-embeddable
Heenawter Jun 21, 2023
dcc37c6
Initialize content management
nickpeihl Jun 29, 2023
e36e4e6
Revert "Initialize content management"
nickpeihl Jun 29, 2023
3c2e8f6
[Dashboard Navigation] Add creation UI (#160179)
Heenawter Jul 10, 2023
9280980
[Dashboard Navigation] Improve empty state (#161605)
andreadelrio Jul 14, 2023
70813b7
Merge branch 'main' into navigation-embeddable
Heenawter Jul 14, 2023
c7485e6
[Dashboard Navigation] Add link editing + reordering (#161568)
Heenawter Jul 17, 2023
577134c
[Navigation embeddable] Add content management (#160896)
nickpeihl Aug 10, 2023
f0ebcb2
[Dashboard Navigation] Add horizontal/vertical embeddable rendering +…
Heenawter Aug 16, 2023
38e8988
Add `EMBEDDABLE_DISPLAY_NAME` to constants
Heenawter Aug 16, 2023
00d3c80
Merge branch 'main' into navigation-embeddable
Heenawter Aug 16, 2023
6fa536c
Switch back to `APP_NAME` for now
Heenawter Aug 16, 2023
d51bcd8
[Dashboard Navigation] Store unwrapped attributes in componentState (…
nickpeihl Aug 28, 2023
75f1fbe
Merge remote-tracking branch 'upstream/main' into navigation-embeddable
ThomThomson Aug 31, 2023
409a8f9
[Dashboard navigation] Inject/extract references (#164330)
nickpeihl Aug 31, 2023
26cc51e
Merge remote-tracking branch 'upstream/navigation-embeddable' into na…
ThomThomson Aug 31, 2023
84b7b17
[Dashboard Navigation] Drilldown on link click (#164196)
Heenawter Sep 5, 2023
e585f12
[Dashboard Navigation] Disable Links panel in Canvas (#165770)
nickpeihl Sep 5, 2023
a2a2cf2
[Links] Panel Placement (#165919)
ThomThomson Sep 11, 2023
657d424
Improve empty state
Heenawter Sep 18, 2023
b599d13
Fix spacing on comment
Heenawter Sep 18, 2023
91113c7
Merge branch 'main' into navigation-embeddable
Heenawter Sep 19, 2023
9b268f3
[Dashboard Navigation] Unit tests (#166297)
nickpeihl Sep 20, 2023
c1114cd
Merge branch 'main' into navigation-embeddable
Heenawter Sep 21, 2023
0a3a011
Remove `console.log` from panel placement PR
Heenawter Sep 21, 2023
2bf868a
Update saved object hash
Heenawter Sep 21, 2023
3651af1
Merge branch 'main' into navigation-embeddable
Heenawter Sep 21, 2023
d75cb19
Merge branch 'main' into navigation-embeddable
kibanamachine Sep 21, 2023
496612b
Fix implicit dependencies on `DashboardGridItem` in `jest_setup`
Heenawter Sep 22, 2023
57de283
[Dashboard Navigation] Rename "Navigation Embeddable" to "Links" (#16…
nickpeihl Sep 23, 2023
7a3c8ef
Fix SO tests
Heenawter Sep 25, 2023
91a0c97
Merge branch 'main' into navigation-embeddable
kibanamachine Sep 25, 2023
3da4878
Fix bad functional test fixture
nickpeihl Sep 25, 2023
933492e
Only replace embeddable if type changes (#167070)
nickpeihl Sep 25, 2023
2188ec9
[Dashboard Navigation] Mark links panel as technical preview (#167091)
Heenawter Sep 25, 2023
bc03367
Merge branch 'main' into navigation-embeddable
kibanamachine Sep 25, 2023
d83a3dd
Update scrolling screenshot to actual last panel
Heenawter Sep 26, 2023
74d5726
Merge branch 'main' of github.com:elastic/kibana into navigation-embe…
Heenawter Sep 26, 2023
2964560
Fix linting that wasn't failing before
Heenawter Sep 26, 2023
b2f2da6
More linting fixes
Heenawter Sep 26, 2023
7df59e1
Fix `copy_panel_to` unused import
Heenawter Sep 26, 2023
c877aa8
Merge branch 'main' into navigation-embeddable
Heenawter Sep 27, 2023
d6b1d9e
Another round of `Check Types Commit Diff` fixes
Heenawter Sep 27, 2023
00a7765
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Sep 27, 2023
a208fca
Delete broken storybook
Heenawter Sep 27, 2023
79e02d1
More descriptive title for save modal
nickpeihl Sep 27, 2023
881902e
Fix layout problems
Heenawter Sep 27, 2023
2329a6b
Add a clarifying comment
Heenawter Sep 27, 2023
b9e5193
Undo screenshot change
Heenawter Sep 27, 2023
c7d3a2b
Remove 'links' definition from pre 8.8.0 maps
gsoldevila Sep 28, 2023
8648deb
Fix saved object namespace type
nickpeihl Sep 28, 2023
9de245b
Fix saved object integration test
nickpeihl Sep 28, 2023
76939fc
Merge remote-tracking branch 'upstream/main' into navigation-embeddable
nickpeihl Sep 28, 2023
4fc73af
Update serverless saved object
Heenawter Sep 28, 2023
b1ca381
Fix links hash
Heenawter Sep 28, 2023
c59a893
Merge remote-tracking branch 'refs/remotes/upstream/navigation-embedd…
nickpeihl Sep 28, 2023
79eb54d
Soften response validation
nickpeihl Sep 28, 2023
e0b2c38
[Dashboard navigation] Functional tests for links panel (#167324)
nickpeihl Sep 28, 2023
91ae3b0
Fix failing test
nickpeihl Sep 28, 2023
9d0873a
Fix expected links length in test
nickpeihl Sep 28, 2023
44743fc
Give test suites distinctive names
nickpeihl Sep 28, 2023
1aa4fc3
Remove deprecated functions + fix flyout animation
Heenawter Sep 28, 2023
f958b7f
Make timeout smaller
Heenawter Sep 28, 2023
fe6e862
Rename a couple components
Heenawter Sep 28, 2023
72f0c4d
Start some easy clean up based on feedback
Heenawter Sep 28, 2023
f4608e0
Use dashboard's overlay tracker
Heenawter Sep 28, 2023
f3661c5
Merge branch 'main' into navigation-embeddable
Heenawter Sep 29, 2023
bb35a5e
Review feedback
nickpeihl Sep 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ x-pack/plugins/lens @elastic/kibana-visualizations
x-pack/plugins/license_api_guard @elastic/platform-deployment-management
x-pack/plugins/license_management @elastic/platform-deployment-management
x-pack/plugins/licensing @elastic/kibana-core
src/plugins/links @elastic/kibana-presentation
packages/kbn-lint-packages-cli @elastic/kibana-operations
packages/kbn-lint-ts-projects-cli @elastic/kibana-operations
x-pack/plugins/lists @elastic/security-detection-engine
Expand Down
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
],
"monaco": "packages/kbn-monaco/src",
"navigation": "src/plugins/navigation",
"links": "src/plugins/links",
"newsfeed": "src/plugins/newsfeed",
"presentationUtil": "src/plugins/presentation_util",
"randomSampling": "x-pack/packages/kbn-random-sampling",
Expand Down
4 changes: 4 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ in Kibana, e.g. visualizations. It has the form of a flyout panel.
|Utilities for building Kibana plugins.


|{kib-repo}blob/{branch}/src/plugins/links/README.md[links]
|This plugin adds the Links panel which allows authors to create hard links to navigate on click and bring all context from the source dashboard to the destination dashboard.


|{kib-repo}blob/{branch}/src/plugins/management/README.md[management]
|This plugins contains the "Stack Management" page framework. It offers navigation and an API
to link individual management section into it. This plugin does not contain any individual
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@
"@kbn/license-api-guard-plugin": "link:x-pack/plugins/license_api_guard",
"@kbn/license-management-plugin": "link:x-pack/plugins/license_management",
"@kbn/licensing-plugin": "link:x-pack/plugins/licensing",
"@kbn/links-plugin": "link:src/plugins/links",
"@kbn/lists-plugin": "link:x-pack/plugins/lists",
"@kbn/locator-examples-plugin": "link:examples/locator_examples",
"@kbn/locator-explorer-plugin": "link:examples/locator_explorer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const DEFAULT_INDEX_TYPES_MAP: IndexTypesMap = {
'legacy-url-alias',
'lens',
'lens-ui-telemetry',
'links',
'map',
'metrics-explorer-view',
'ml-job',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,23 @@ export const INDEX_MAP_BEFORE_SPLIT: IndexMap = {
},
},
},
links: {
properties: {
id: {
type: 'text',
},
title: {
type: 'text',
},
description: {
type: 'text',
},
links: {
dynamic: false,
properties: {},
},
},
},
Heenawter marked this conversation as resolved.
Show resolved Hide resolved
map: {
properties: {
description: {
Expand Down
18 changes: 18 additions & 0 deletions packages/kbn-check-mappings-update-cli/current_mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,24 @@
}
}
},
"links": {
"dynamic": false,
"properties": {
"id": {
"type": "text"
},
"title": {
"type": "text"
},
"description": {
"type": "text"
},
"links": {
"dynamic": false,
"properties": {}
}
}
},
"lens": {
"properties": {
"title": {
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pageLoadAssetSize:
lens: 38000
licenseManagement: 41817
licensing: 29004
links: 44490
lists: 22900
logExplorer: 39045
logsShared: 281060
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
"legacy-url-alias": "9b8cca3fbb2da46fd12823d3cd38fdf1c9f24bc8",
"lens": "5cfa2c52b979b4f8df56dd13c477e152183468b9",
"lens-ui-telemetry": "8c47a9e393861f76e268345ecbadfc8a5fb1e0bd",
"links": "a2c467f8b00e851d343dace3ef532d7fb29462e7",
"maintenance-window": "d893544460abad56ff7a0e25b78f78776dfe10d1",
"map": "76c71023bd198fb6b1163b31bafd926fe2ceb9da",
"metrics-data-source": "81b69dc9830699d9ead5ac8dcb9264612e2a3c89",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const previouslyRegisteredTypes = [
'legacy-url-alias',
'lens',
'lens-ui-telemetry',
'links',
'maintenance-window',
'map',
'maps-telemetry',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ describe('split .kibana index into multiple system indices', () => {
"legacy-url-alias",
"lens",
"lens-ui-telemetry",
"links",
"maintenance-window",
"map",
"metrics-data-source",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ export const EditControlFlyout = ({
}

closeFlyout();
await controlGroup.replaceEmbeddable(embeddable.id, inputToReturn, type);
if (panel.type === type) {
controlGroup.updateInputForChild(embeddable.id, inputToReturn);
} else {
await controlGroup.replaceEmbeddable(embeddable.id, inputToReturn, type);
}
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,22 +222,22 @@ export class ControlGroupContainer extends Container<

public async addDataControlFromField(controlProps: AddDataControlProps) {
const panelState = await getDataControlPanelState(this.getInput(), controlProps);
return this.createAndSaveEmbeddable(panelState.type, panelState);
return this.createAndSaveEmbeddable(panelState.type, panelState, this.getInput().panels);
}

public addOptionsListControl(controlProps: AddOptionsListControlProps) {
const panelState = getOptionsListPanelState(this.getInput(), controlProps);
return this.createAndSaveEmbeddable(panelState.type, panelState);
return this.createAndSaveEmbeddable(panelState.type, panelState, this.getInput().panels);
}

public addRangeSliderControl(controlProps: AddRangeSliderControlProps) {
const panelState = getRangeSliderPanelState(this.getInput(), controlProps);
return this.createAndSaveEmbeddable(panelState.type, panelState);
return this.createAndSaveEmbeddable(panelState.type, panelState, this.getInput().panels);
}

public addTimeSliderControl() {
const panelState = getTimeSliderPanelState(this.getInput());
return this.createAndSaveEmbeddable(panelState.type, panelState);
return this.createAndSaveEmbeddable(panelState.type, panelState, this.getInput().panels);
}

public openAddDataControlFlyout = openAddDataControlFlyout;
Expand Down Expand Up @@ -283,15 +283,19 @@ export class ControlGroupContainer extends Container<

protected createNewPanelState<TEmbeddableInput extends ControlInput = ControlInput>(
factory: EmbeddableFactory<ControlInput, ControlOutput, ControlEmbeddable>,
partial: Partial<TEmbeddableInput> = {}
): ControlPanelState<TEmbeddableInput> {
const panelState = super.createNewPanelState(factory, partial);
partial: Partial<TEmbeddableInput> = {},
otherPanels: ControlGroupInput['panels']
) {
const { newPanel } = super.createNewPanelState(factory, partial);
return {
order: getNextPanelOrder(this.getInput().panels),
width: this.getInput().defaultControlWidth,
grow: this.getInput().defaultControlGrow,
...panelState,
} as ControlPanelState<TEmbeddableInput>;
newPanel: {
order: getNextPanelOrder(this.getInput().panels),
width: this.getInput().defaultControlWidth,
grow: this.getInput().defaultControlGrow,
...newPanel,
} as ControlPanelState<TEmbeddableInput>,
otherPanels,
};
}

protected onRemoveEmbeddable(idToRemove: string) {
Expand Down
12 changes: 9 additions & 3 deletions src/plugins/dashboard/jest_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
* Side Public License, v 1.
*/

import { pluginServices } from './public/services/plugin_services';
import { registry } from './public/services/plugin_services.stub';
import { setStubDashboardServices } from './public/services/mocks';

pluginServices.setRegistry(registry.start({}));
/**
* CAUTION: Be very mindful of the things you import in to this `jest_setup` file - anything that is imported
Heenawter marked this conversation as resolved.
Show resolved Hide resolved
* here (either directly or implicitly through dependencies) will be **unable** to be mocked elsewhere!
*
* Refer to the "Caution" section here:
* https://jestjs.io/docs/jest-object#jestmockmodulename-factory-options
*/
setStubDashboardServices();
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ beforeEach(async () => {
.fn()
.mockReturnValue(mockEmbeddableFactory);
container = buildMockDashboard({
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Kibanana', id: '123' },
type: CONTACT_CARD_EMBEDDABLE,
}),
overrides: {
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Kibanana', id: '123' },
type: CONTACT_CARD_EMBEDDABLE,
}),
},
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';

import { type DashboardPanelState } from '../../common';
import { pluginServices } from '../services/plugin_services';
import { createPanelState } from '../dashboard_container/component/panel';
import { dashboardClonePanelActionStrings } from './_dashboard_actions_strings';
import { placeClonePanel } from '../dashboard_container/component/panel_placement';
import { DASHBOARD_CONTAINER_TYPE, type DashboardContainer } from '../dashboard_container';
import { placePanelBeside } from '../dashboard_container/component/panel/dashboard_panel_placement';

export const ACTION_CLONE_PANEL = 'clonePanel';

Expand Down Expand Up @@ -82,6 +81,7 @@ export class ClonePanelAction implements Action<ClonePanelActionContext> {
throw new PanelNotFoundError();
}

// Clone panel input
const clonedPanelState: PanelState<EmbeddableInput> = await (async () => {
const newTitle = await this.getCloneTitle(embeddable, embeddable.getTitle() || '');
const id = uuidv4();
Expand Down Expand Up @@ -110,18 +110,20 @@ export class ClonePanelAction implements Action<ClonePanelActionContext> {
'data-test-subj': 'addObjectToContainerSuccess',
});

const { otherPanels, newPanel } = createPanelState(
clonedPanelState,
dashboard.getInput().panels,
placePanelBeside,
{
width: panelToClone.gridData.w,
height: panelToClone.gridData.h,
currentPanels: dashboard.getInput().panels,
placeBesideId: panelToClone.explicitInput.id,
scrollToPanel: true,
}
);
const { newPanelPlacement, otherPanels } = placeClonePanel({
width: panelToClone.gridData.w,
height: panelToClone.gridData.h,
currentPanels: dashboard.getInput().panels,
placeBesideId: panelToClone.explicitInput.id,
});

const newPanel = {
...clonedPanelState,
gridData: {
...newPanelPlacement,
i: clonedPanelState.explicitInput.id,
},
};

dashboard.updateInput({
panels: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ pluginServices.getServices().embeddable.getEmbeddableFactory = jest

beforeEach(async () => {
container = buildMockDashboard({
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Sam', id: '123' },
type: CONTACT_CARD_EMBEDDABLE,
}),
overrides: {
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Sam', id: '123' },
type: CONTACT_CARD_EMBEDDABLE,
}),
},
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ describe('Export CSV action', () => {
};

container = buildMockDashboard({
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Kibanana', id: '123' },
type: CONTACT_CARD_EXPORTABLE_EMBEDDABLE,
}),
overrides: {
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Kibanana', id: '123' },
type: CONTACT_CARD_EXPORTABLE_EMBEDDABLE,
}),
},
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ let container: DashboardContainer;
let embeddable: ContactCardEmbeddable;
beforeEach(async () => {
container = buildMockDashboard({
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Sam', id: '123' },
type: CONTACT_CARD_EMBEDDABLE,
}),
overrides: {
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Sam', id: '123' },
type: CONTACT_CARD_EMBEDDABLE,
}),
},
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
} from '@kbn/embeddable-plugin/public';
import { Toast } from '@kbn/core/public';

import { DashboardPanelState } from '../../common';
import { pluginServices } from '../services/plugin_services';
import { dashboardReplacePanelActionStrings } from './_dashboard_actions_strings';
import { DashboardContainer } from '../dashboard_container';
Expand Down Expand Up @@ -58,30 +57,15 @@ export class ReplacePanelFlyout extends React.Component<Props> {

public onReplacePanel = async (savedObjectId: string, type: string, name: string) => {
const { panelToRemove, container } = this.props;
const { w, h, x, y } = (container.getInput().panels[panelToRemove.id] as DashboardPanelState)
.gridData;

const { id } = await container.addNewEmbeddable<SavedObjectEmbeddableInput>(type, {
savedObjectId,
});

const { [panelToRemove.id]: omit, ...panels } = container.getInput().panels;

container.updateInput({
panels: {
...panels,
[id]: {
...panels[id],
gridData: {
...(panels[id] as DashboardPanelState).gridData,
w,
h,
x,
y,
},
} as DashboardPanelState,
const id = await container.replaceEmbeddable<SavedObjectEmbeddableInput>(
panelToRemove.id,
{
savedObjectId,
},
});
type,
true
);

(container as DashboardContainer).setHighlightPanelId(id);
this.showToast(name);
Expand Down
Loading