Skip to content

Commit

Permalink
Merge branch 'master' into make-actions-exportable
Browse files Browse the repository at this point in the history
  • Loading branch information
FrankHassanabad committed Oct 15, 2021
2 parents 375d1d4 + 712fac6 commit e951c42
Show file tree
Hide file tree
Showing 107 changed files with 2,375 additions and 606 deletions.
6 changes: 5 additions & 1 deletion .buildkite/scripts/build_kibana.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ set -euo pipefail
export KBN_NP_PLUGINS_BUILT=true

echo "--- Build Kibana Distribution"
node scripts/build --debug
if [[ "${GITHUB_PR_LABELS:-}" == *"ci:build-all-platforms"* ]]; then
node scripts/build --all-platforms --skip-os-packages
else
node scripts/build
fi

echo "--- Archive Kibana Distribution"
linuxBuild="$(find "$KIBANA_DIR/target" -name 'kibana-*-linux-x86_64.tar.gz')"
Expand Down
5 changes: 2 additions & 3 deletions .buildkite/scripts/post_build_kibana.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ fi
echo "--- Upload Build Artifacts"
# Moving to `target/` first will keep `buildkite-agent` from including directories in the artifact name
cd "$KIBANA_DIR/target"
mv kibana-*-linux-x86_64.tar.gz kibana-default.tar.gz
buildkite-agent artifact upload kibana-default.tar.gz
buildkite-agent artifact upload kibana-default-plugins.tar.gz
cp kibana-*-linux-x86_64.tar.gz kibana-default.tar.gz
buildkite-agent artifact upload "./*.tar.gz;./*.zip"
cd -
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Side Public License, v 1.
*/

const Fs = require('fs');
const Path = require('path');

const { REPO_ROOT } = require('@kbn/dev-utils');
Expand All @@ -22,7 +23,7 @@ require('@babel/register')({
// TODO: should should probably remove this link back to the source
Path.resolve(REPO_ROOT, 'x-pack/plugins/task_manager/server/config.ts'),
Path.resolve(REPO_ROOT, 'src/core/utils/default_app_categories.ts'),
],
].map((path) => Fs.realpathSync(path)),
babelrc: false,
presets: [require.resolve('@kbn/babel-preset/node_preset')],
extensions: ['.js', '.ts', '.tsx'],
Expand Down
8 changes: 7 additions & 1 deletion src/plugins/dashboard/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
"presentationUtil",
"visualizations"
],
"optionalPlugins": ["home", "spaces", "savedObjectsTaggingOss", "usageCollection"],
"optionalPlugins": [
"home",
"spaces",
"savedObjectsTaggingOss",
"screenshotMode",
"usageCollection"
],
"server": true,
"ui": true,
"requiredBundles": ["home", "kibanaReact", "kibanaUtils", "presentationUtil"]
Expand Down
15 changes: 14 additions & 1 deletion src/plugins/dashboard/public/application/dashboard_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { EmbeddableRenderer } from '../services/embeddable';
import { DashboardTopNav, isCompleteDashboardAppState } from './top_nav/dashboard_top_nav';
import { DashboardAppServices, DashboardEmbedSettings, DashboardRedirect } from '../types';
import { createKbnUrlStateStorage, withNotifyOnErrors } from '../services/kibana_utils';
import { createDashboardEditUrl } from '../dashboard_constants';
export interface DashboardAppProps {
history: History;
savedDashboardId?: string;
Expand All @@ -34,7 +35,7 @@ export function DashboardApp({
redirectTo,
history,
}: DashboardAppProps) {
const { core, chrome, embeddable, onAppLeave, uiSettings, data } =
const { core, chrome, embeddable, onAppLeave, uiSettings, data, spacesService } =
useKibana<DashboardAppServices>().services;

const kbnUrlStateStorage = useMemo(
Expand Down Expand Up @@ -109,6 +110,18 @@ export function DashboardApp({
embedSettings={embedSettings}
dashboardAppState={dashboardAppState}
/>

{dashboardAppState.savedDashboard.outcome === 'conflict' &&
dashboardAppState.savedDashboard.id &&
dashboardAppState.savedDashboard.aliasId
? spacesService?.ui.components.getLegacyUrlConflict({
currentObjectId: dashboardAppState.savedDashboard.id,
otherObjectId: dashboardAppState.savedDashboard.aliasId,
otherObjectPath: `#${createDashboardEditUrl(
dashboardAppState.savedDashboard.aliasId
)}${history.location.search}`,
})
: null}
<div className="dashboardViewport">
<EmbeddableRenderer embeddable={dashboardAppState.dashboardContainer} />
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/dashboard/public/application/dashboard_router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export async function mountApp({
savedObjectsTaggingOss,
visualizations,
presentationUtil,
screenshotMode,
} = pluginsStart;

const activeSpaceId =
Expand Down Expand Up @@ -129,6 +130,8 @@ export async function mountApp({
core.notifications.toasts,
activeSpaceId || 'default'
),
spacesService: spacesApi,
screenshotModeService: screenshotMode,
};

const getUrlStateStorage = (history: RouteComponentProps['history']) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ export const useDashboardAppState = ({
dashboardCapabilities,
dashboardSessionStorage,
scopedHistory,
spacesService,
screenshotModeService,
} = services;
const { docTitle } = chrome;
const { notifications } = core;
Expand Down Expand Up @@ -149,6 +151,25 @@ export const useDashboardAppState = ({
if (canceled || !loadSavedDashboardResult) return;
const { savedDashboard, savedDashboardState } = loadSavedDashboardResult;

// If the saved dashboard is an alias match, then we will redirect
if (savedDashboard.outcome === 'aliasMatch' && savedDashboard.id && savedDashboard.aliasId) {
// We want to keep the "query" params on our redirect.
// But, these aren't true query params, they are technically part of the hash
// So, to get the new path, we will just replace the current id in the hash
// with the alias id
const path = scopedHistory().location.hash.replace(
savedDashboard.id,
savedDashboard.aliasId
);
if (screenshotModeService?.isScreenshotMode()) {
scopedHistory().replace(path);
} else {
await spacesService?.ui.redirectLegacyUrl(path);
}
// Return so we don't run any more of the hook and let it rerun after the redirect that just happened
return;
}

/**
* Combine initial state from the saved object, session storage, and URL, then dispatch it to Redux.
*/
Expand Down Expand Up @@ -340,6 +361,8 @@ export const useDashboardAppState = ({
search,
query,
data,
spacesService?.ui,
screenshotModeService,
]);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ export const loadSavedDashboardState = async ({
await indexPatterns.ensureDefaultDataView();
let savedDashboard: DashboardSavedObject | undefined;
try {
savedDashboard = (await savedDashboards.get(savedDashboardId)) as DashboardSavedObject;
savedDashboard = (await savedDashboards.get({
id: savedDashboardId,
useResolve: true,
})) as DashboardSavedObject;
} catch (error) {
// E.g. a corrupt or deleted dashboard
notifications.toasts.addDanger(error.message);
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/dashboard/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { filter, map } from 'rxjs/operators';

import { Start as InspectorStartContract } from 'src/plugins/inspector/public';
import { UrlForwardingSetup, UrlForwardingStart } from 'src/plugins/url_forwarding/public';
import { ScreenshotModePluginStart } from 'src/plugins/screenshot_mode/public';
import { APP_WRAPPER_CLASS } from '../../../core/public';
import {
App,
Expand Down Expand Up @@ -115,6 +116,7 @@ export interface DashboardStartDependencies {
savedObjects: SavedObjectsStart;
presentationUtil: PresentationUtilPluginStart;
savedObjectsTaggingOss?: SavedObjectTaggingOssPluginStart;
screenshotMode?: ScreenshotModePluginStart;
spaces?: SpacesPluginStart;
visualizations: VisualizationsStart;
}
Expand Down
93 changes: 72 additions & 21 deletions src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Side Public License, v 1.
*/

import { assign, cloneDeep } from 'lodash';
import { SavedObjectsClientContract } from 'kibana/public';
import { EmbeddableStart } from '../services/embeddable';
import { SavedObject, SavedObjectsStart } from '../services/saved_objects';
import { Filter, ISearchSource, Query, RefreshInterval } from '../services/data';
Expand All @@ -32,12 +34,33 @@ export interface DashboardSavedObject extends SavedObject {
getQuery(): Query;
getFilters(): Filter[];
getFullEditPath: (editMode?: boolean) => string;
outcome?: string;
aliasId?: string;
}

const defaults = {
title: '',
hits: 0,
description: '',
panelsJSON: '[]',
optionsJSON: JSON.stringify({
// for BWC reasons we can't default dashboards that already exist without this setting to true.
useMargins: true,
syncColors: false,
hidePanelTitles: false,
} as DashboardOptions),
version: 1,
timeRestore: false,
timeTo: undefined,
timeFrom: undefined,
refreshInterval: undefined,
};

// Used only by the savedDashboards service, usually no reason to change this
export function createSavedDashboardClass(
savedObjectStart: SavedObjectsStart,
embeddableStart: EmbeddableStart
embeddableStart: EmbeddableStart,
savedObjectsClient: SavedObjectsClientContract
): new (id: string) => DashboardSavedObject {
class SavedDashboard extends savedObjectStart.SavedObjectClass {
// save these objects with the 'dashboard' type
Expand Down Expand Up @@ -68,7 +91,10 @@ export function createSavedDashboardClass(
public static searchSource = true;
public showInRecentlyAccessed = true;

constructor(id: string) {
public outcome?: string;
public aliasId?: string;

constructor(arg: { id: string; useResolve: boolean } | string) {
super({
type: SavedDashboard.type,
mapping: SavedDashboard.mapping,
Expand All @@ -88,28 +114,53 @@ export function createSavedDashboardClass(
},

// if this is null/undefined then the SavedObject will be assigned the defaults
id,
id: typeof arg === 'string' ? arg : arg.id,

// default values that will get assigned if the doc is new
defaults: {
title: '',
hits: 0,
description: '',
panelsJSON: '[]',
optionsJSON: JSON.stringify({
// for BWC reasons we can't default dashboards that already exist without this setting to true.
useMargins: true,
syncColors: false,
hidePanelTitles: false,
} as DashboardOptions),
version: 1,
timeRestore: false,
timeTo: undefined,
timeFrom: undefined,
refreshInterval: undefined,
},
defaults,
});
this.getFullPath = () => `/app/dashboards#${createDashboardEditUrl(this.id)}`;

const id: string = typeof arg === 'string' ? arg : arg.id;
const useResolve = typeof arg === 'string' ? false : arg.useResolve;

this.getFullPath = () => `/app/dashboards#${createDashboardEditUrl(this.aliasId || this.id)}`;

// Overwrite init if we want to use resolve
if (useResolve || true) {
this.init = async () => {
const esType = SavedDashboard.type;
// ensure that the esType is defined
if (!esType) throw new Error('You must define a type name to use SavedObject objects.');

if (!id) {
// just assign the defaults and be done
assign(this, defaults);
await this.hydrateIndexPattern!();

return this;
}

const {
outcome,
alias_target_id: aliasId,
saved_object: resp,
} = await savedObjectsClient.resolve(esType, id);

const respMapped = {
_id: resp.id,
_type: resp.type,
_source: cloneDeep(resp.attributes),
references: resp.references,
found: !!resp._version,
};

this.outcome = outcome;
this.aliasId = aliasId;
await this.applyESResp(respMapped);

return this;
};
}
}

getQuery() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export function createSavedDashboardLoader({
savedObjectsClient,
embeddableStart,
}: Services) {
const SavedDashboard = createSavedDashboardClass(savedObjects, embeddableStart);
const SavedDashboard = createSavedDashboardClass(
savedObjects,
embeddableStart,
savedObjectsClient
);
return new SavedObjectLoader(SavedDashboard, savedObjectsClient);
}
4 changes: 4 additions & 0 deletions src/plugins/dashboard/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
import { History } from 'history';
import { AnyAction, Dispatch } from 'redux';
import { BehaviorSubject, Subject } from 'rxjs';
import { ScreenshotModePluginStart } from 'src/plugins/screenshot_mode/public';
import { Query, Filter, IndexPattern, RefreshInterval, TimeRange } from './services/data';
import { ContainerInput, EmbeddableInput, ViewMode } from './services/embeddable';
import { SharePluginStart } from './services/share';
Expand All @@ -35,6 +36,7 @@ import { IKbnUrlStateStorage } from './services/kibana_utils';
import { DashboardContainer, DashboardSavedObject } from '.';
import { VisualizationsStart } from '../../visualizations/public';
import { DashboardAppLocatorParams } from './locator';
import { SpacesPluginStart } from './services/spaces';

export { SavedDashboardPanel };

Expand Down Expand Up @@ -203,4 +205,6 @@ export interface DashboardAppServices {
dashboardSessionStorage: DashboardSessionStorage;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
savedQueryService: DataPublicPluginStart['query']['savedQueries'];
spacesService?: SpacesPluginStart;
screenshotModeService?: ScreenshotModePluginStart;
}
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ describe('Field editor Preview panel', () => {
subTitle: 'First doc - subTitle',
title: 'First doc - title',
},
documentId: '001',
index: 'testIndex',
script: {
source: 'echo("hello")',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => {
document: params.document!,
context: `${params.type!}_field` as FieldPreviewContext,
script: params.script!,
documentId: currentDocId,
});

if (currentApiCall !== previewCount.current) {
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/index_pattern_field_editor/public/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ export const initApi = (httpClient: HttpSetup) => {
context,
script,
document,
documentId,
}: {
index: string;
context: FieldPreviewContext;
script: { source: string } | null;
document: Record<string, any>;
documentId: string;
}) => {
return sendRequest<FieldPreviewResponse>(httpClient, {
path: `${API_BASE_PATH}/field_preview`,
Expand All @@ -30,6 +32,7 @@ export const initApi = (httpClient: HttpSetup) => {
context,
script,
document,
documentId,
},
});
};
Expand Down
Loading

0 comments on commit e951c42

Please sign in to comment.