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

[Visualize] Prevent overwriting managed content #175274

Merged
merged 44 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e1ec9d9
detecting managed Lens visualizations
drewdaemon Jan 17, 2024
7eb00bd
add managed badge to lens
drewdaemon Jan 17, 2024
8f2588d
force copy-on-save for managed content
drewdaemon Jan 17, 2024
ce339fc
Add title
drewdaemon Jan 17, 2024
817742a
Add functional test
drewdaemon Jan 18, 2024
77d71e2
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 18, 2024
f7441ed
move must copy on save message to keyboard accessible element
drewdaemon Jan 18, 2024
11b1daa
Merge branch 'lens-respect-managed-content' of github.com:drewdaemon/…
drewdaemon Jan 18, 2024
cb61a57
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 18, 2024
524d1a3
Merge branch 'main' into lens-respect-managed-content
kibanamachine Jan 18, 2024
08495b8
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine Jan 18, 2024
e95de1b
Merge branch 'main' into lens-respect-managed-content
kibanamachine Jan 18, 2024
0978bc0
undo managed type change
drewdaemon Jan 18, 2024
7c15f12
make managed prop optional
drewdaemon Jan 18, 2024
7e24a6b
update snap
drewdaemon Jan 18, 2024
394db6d
fix translation string
drewdaemon Jan 18, 2024
ee5e0b8
remove unused translation
drewdaemon Jan 21, 2024
a67bfbf
Merge branch 'main' into lens-respect-managed-content
kibanamachine Jan 21, 2024
367dc86
show managed badge for saved searches
drewdaemon Jan 22, 2024
c401eb6
update unsaved changes badge for managed content
drewdaemon Jan 22, 2024
8fa69cc
disable overwriting in save modal
drewdaemon Jan 22, 2024
caaedec
add FT
drewdaemon Jan 22, 2024
fa167c9
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 22, 2024
6ae44e4
fix saved search mocks
drewdaemon Jan 22, 2024
3c70448
show managed badge
drewdaemon Jan 22, 2024
e0ce6ad
Enforce copy-on-save
drewdaemon Jan 22, 2024
d33a521
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 22, 2024
5ecd977
update snapshots
drewdaemon Jan 22, 2024
19eda22
actually save a new copy
drewdaemon Jan 22, 2024
1b864fb
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 22, 2024
4d2f844
Merge branch 'main' of github.com:elastic/kibana into lens-respect-ma…
drewdaemon Jan 23, 2024
46f8f65
Merge branch 'lens-respect-managed-content' of github.com:drewdaemon/…
drewdaemon Jan 23, 2024
21a87b2
Merge branch 'lens-respect-managed-content' into discover-respect-man…
drewdaemon Jan 23, 2024
8928cd9
update snapshot
drewdaemon Jan 23, 2024
43adee9
Merge branch 'main' of github.com:elastic/kibana into discover-respec…
drewdaemon Jan 24, 2024
b8784c3
Merge branch 'discover-respect-managed-content' into visualize-respec…
drewdaemon Jan 24, 2024
ef4e2a0
add FT
drewdaemon Jan 24, 2024
5027b97
Merge branch 'main' of github.com:elastic/kibana into visualize-respe…
drewdaemon Jan 26, 2024
062301e
Merge branch 'main' into visualize-respect-managed-content
stratoula Jan 29, 2024
2862791
Merge branch 'main' of github.com:elastic/kibana into visualize-respe…
drewdaemon Jan 30, 2024
5bbd9e3
Merge branch 'main' into visualize-respect-managed-content
kibanamachine Jan 30, 2024
46a17c8
Merge branch 'main' into visualize-respect-managed-content
kibanamachine Jan 30, 2024
9734ab8
Merge branch 'main' of github.com:elastic/kibana into visualize-respe…
drewdaemon Jan 30, 2024
9b342f1
Merge branch 'visualize-respect-managed-content' of github.com:drewda…
drewdaemon Jan 30, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface VisualizationSavedObject {
statusCode: number;
metadata?: Record<string, unknown>;
};
managed?: boolean;
}

export type PartialVisualizationSavedObject = Omit<
Expand Down
1 change: 1 addition & 0 deletions src/plugins/visualizations/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface VisSavedObject extends ISavedVis {
searchSource?: ISearchSource;
version?: string;
tags?: string[];
managed: boolean;
}

export interface SaveVisOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ export async function getSavedVisualization(
getEsType: () => SAVED_VIS_TYPE,
getDisplayName: () => SAVED_VIS_TYPE,
searchSource: opts.searchSource ? services.search.searchSource.createEmpty() : undefined,
managed: false,
} as VisSavedObject;
const defaultsProps = getDefaults(opts);

Expand Down Expand Up @@ -255,6 +256,7 @@ export async function getSavedVisualization(

Object.assign(savedObject, attributes);
savedObject.lastSavedTitle = savedObject.title;
savedObject.managed = Boolean(resp.managed);

savedObject.sharingSavedObjectProps = {
aliasTargetId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import useLocalStorage from 'react-use/lib/useLocalStorage';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/public';
import { switchMap } from 'rxjs';
import { getManagedContentBadge } from '@kbn/managed-content-badge';
import type {
VisualizeServices,
VisualizeAppState,
Expand Down Expand Up @@ -63,7 +64,11 @@ const TopNav = ({
const { services } = useKibana<VisualizeServices>();
const { TopNavMenu } = services.navigation.ui;
const { setHeaderActionMenu, visualizeCapabilities } = services;
const { embeddableHandler, vis } = visInstance;
const {
embeddableHandler,
vis,
savedVis: { managed },
} = visInstance;
const [inspectorSession, setInspectorSession] = useState<OverlayRef>();
const [navigateToLens, setNavigateToLens] = useState(false);
const [displayEditInLensItem, setDisplayEditInLensItem] = useState(false);
Expand Down Expand Up @@ -315,6 +320,18 @@ const TopNav = ({
showDatePicker={showDatePicker()}
showFilterBar={showFilterBar}
showQueryInput={showQueryInput}
badges={
managed
? [
getManagedContentBadge(
i18n.translate('visualizations.managedBadgeTooltip', {
defaultMessage:
'This visualization is managed by Elastic. Changes made here must be saved to a new visualization.',
})
),
]
: undefined
}
saveQueryMenuVisibility={
services.visualizeCapabilities.saveQuery ? 'allowed_by_app_privilege' : 'globally_managed'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,14 @@ export const getTopNavConfig = (
}
)}
onClose={() => {}}
mustCopyOnSaveMessage={
savedVis.managed
? i18n.translate('visualizations.topNavMenu.mustCopyOnSave', {
defaultMessage:
'This visualization is managed by Elastic. Changes here must be saved to a new visualization.',
})
: undefined
}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
VisualizeEmbeddableContract,
VisualizeInput,
} from '../..';
import type { VisualizeServices } from '../types';
import type { VisInstance, VisualizeServices } from '../types';

function isErrorRelatedToRuntimeFields(error: ExpressionValueError['error']) {
const originalError = error.original || error;
Expand Down Expand Up @@ -120,7 +120,7 @@ export const getVisualizationInstance = async (
* Both come from url search query
*/
opts?: Record<string, unknown> | string
) => {
): Promise<VisInstance> => {
const { data, spaces, savedObjectsTagging } = visualizeServices;

const savedVis: VisSavedObject = await getSavedVisualization(
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/visualizations/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"@kbn/logging",
"@kbn/content-management-table-list-view-common",
"@kbn/chart-expressions-common",
"@kbn/shared-ux-utility"
"@kbn/shared-ux-utility",
"@kbn/managed-content-badge"
],
"exclude": [
"target/**/*",
Expand Down
4 changes: 4 additions & 0 deletions test/functional/fixtures/kbn_archiver/managed_content.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@
{"attributes":{"columns":["@tags","clientip"],"description":"","grid":{},"hideChart":false,"isTextBasedQuery":false,"kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"agent.raw:\\\"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\\\" \",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"},"sort":[["@timestamp","desc"]],"timeRestore":false,"title":"Saved search","usesAdHocDataView":false},"coreMigrationVersion":"8.8.0","created_at":"2024-01-22T18:11:05.016Z","id":"managed-3d62-4113-ac7c-de2e20a68fbc","managed":true,"references":[{"id":"5f863f70-4728-4e8d-b441-db08f8c33b28","name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern"}],"type":"search","typeMigrationVersion":"8.0.0","updated_at":"2024-01-22T18:11:05.016Z","version":"WzIzLDFd"}

{"attributes":{"columns":["@tags","clientip"],"description":"","grid":{},"hideChart":false,"isTextBasedQuery":false,"kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"agent.raw:\\\"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\\\" \",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"},"sort":[["@timestamp","desc"]],"timeRestore":false,"title":"Saved search","usesAdHocDataView":false},"coreMigrationVersion":"8.8.0","created_at":"2024-01-22T18:11:05.016Z","id":"unmanaged-3d62-4113-ac7c-de2e20a68fbc","managed":false,"references":[{"id":"5f863f70-4728-4e8d-b441-db08f8c33b28","name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern"}],"type":"search","typeMigrationVersion":"8.0.0","updated_at":"2024-01-22T18:11:05.016Z","version":"WzIzLDFd"}

{"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"title":"Legacy visualization","uiStateJSON":"{}","version":1,"visState":"{\"title\":\"Legacy visualization\",\"type\":\"metrics\",\"aggs\":[],\"params\":{\"id\":\"1a14d0ad-0d74-4470-a189-8f040cddc1a1\",\"type\":\"timeseries\",\"series\":[{\"id\":\"daa8bbf7-86cc-4394-b249-be48da9f7351\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"palette\":{\"type\":\"palette\",\"name\":\"default\"},\"metrics\":[{\"id\":\"795375d9-1aa6-454d-9b23-687e69f3382c\",\"type\":\"count\"}],\"separate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"default\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"override_index_pattern\":0,\"series_drop_last_bucket\":0}],\"time_field\":\"\",\"use_kibana_indexes\":true,\"interval\":\"\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"axis_scale\":\"normal\",\"show_legend\":1,\"truncate_legend\":1,\"max_lines_legend\":1,\"show_grid\":1,\"tooltip_mode\":\"show_all\",\"drop_last_bucket\":0,\"index_pattern_ref_name\":\"metrics_0_index_pattern\"}}"},"coreMigrationVersion":"8.8.0","created_at":"2024-01-24T18:53:06.818Z","id":"managed-feb9-4ba6-9538-1b8f67fb4f57","managed":true,"references":[{"id":"5f863f70-4728-4e8d-b441-db08f8c33b28","name":"metrics_0_index_pattern","type":"index-pattern"}],"type":"visualization","typeMigrationVersion":"8.5.0","updated_at":"2024-01-24T18:53:06.818Z","version":"WzEzLDFd"}

{"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"title":"Legacy visualization","uiStateJSON":"{}","version":1,"visState":"{\"title\":\"Legacy visualization\",\"type\":\"metrics\",\"aggs\":[],\"params\":{\"id\":\"1a14d0ad-0d74-4470-a189-8f040cddc1a1\",\"type\":\"timeseries\",\"series\":[{\"id\":\"daa8bbf7-86cc-4394-b249-be48da9f7351\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"palette\":{\"type\":\"palette\",\"name\":\"default\"},\"metrics\":[{\"id\":\"795375d9-1aa6-454d-9b23-687e69f3382c\",\"type\":\"count\"}],\"separate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"default\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"override_index_pattern\":0,\"series_drop_last_bucket\":0}],\"time_field\":\"\",\"use_kibana_indexes\":true,\"interval\":\"\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"axis_scale\":\"normal\",\"show_legend\":1,\"truncate_legend\":1,\"max_lines_legend\":1,\"show_grid\":1,\"tooltip_mode\":\"show_all\",\"drop_last_bucket\":0,\"index_pattern_ref_name\":\"metrics_0_index_pattern\"}}"},"coreMigrationVersion":"8.8.0","created_at":"2024-01-24T18:53:06.818Z","id":"unmanaged-feb9-4ba6-9538-1b8f67fb4f57","managed":false,"references":[{"id":"5f863f70-4728-4e8d-b441-db08f8c33b28","name":"metrics_0_index_pattern","type":"index-pattern"}],"type":"visualization","typeMigrationVersion":"8.5.0","updated_at":"2024-01-24T18:53:06.818Z","version":"WzEzLDFd"}
20 changes: 19 additions & 1 deletion x-pack/test/functional/apps/managed_content/managed_content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';

export default function ({ getPageObjects, getService }: FtrProviderContext) {
const PageObjects = getPageObjects(['timePicker', 'lens', 'common', 'discover']);
const PageObjects = getPageObjects(['visChart', 'timePicker', 'lens', 'common', 'discover']);
const kibanaServer = getService('kibanaServer');
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
Expand Down Expand Up @@ -76,5 +76,23 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {

await expectManagedContentSignifiers(false, 'discoverSaveButton');
});

it('visualize', async () => {
await PageObjects.common.navigateToActualUrl(
'visualize',
'edit/managed-feb9-4ba6-9538-1b8f67fb4f57'
);
await PageObjects.visChart.waitForVisualization();

await expectManagedContentSignifiers(true, 'visualizeSaveButton');

await PageObjects.common.navigateToActualUrl(
'visualize',
'edit/unmanaged-feb9-4ba6-9538-1b8f67fb4f57'
);
await PageObjects.visChart.waitForVisualization();

await expectManagedContentSignifiers(false, 'visualizeSaveButton');
});
});
}