mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[State Management] Move url state_hashing utils to kibana_utils (#52280)
Part of #44151, Continuation of #51835, Just moves existing state related url utils to kibana_utils plugin Also fixes small regression introduced in #51835, When sharing hashed url directly it should show error toast instead of full page fatal error
This commit is contained in:
parent
ca55402496
commit
881c836f94
20 changed files with 120 additions and 32 deletions
|
@ -19,6 +19,7 @@
|
|||
"kbnVislibVisTypes": "src/legacy/core_plugins/kbn_vislib_vis_types",
|
||||
"kibana_react": "src/legacy/core_plugins/kibana_react",
|
||||
"kibana-react": "src/plugins/kibana_react",
|
||||
"kibana_utils": "src/plugins/kibana_utils",
|
||||
"navigation": "src/legacy/core_plugins/navigation",
|
||||
"newsfeed": "src/plugins/newsfeed",
|
||||
"regionMap": "src/legacy/core_plugins/region_map",
|
||||
|
|
|
@ -63,6 +63,6 @@ export { confirmModalFactory } from 'ui/modals/confirm_modal';
|
|||
export { configureAppAngularModule } from 'ui/legacy_compat';
|
||||
export { stateMonitorFactory, StateMonitor } from 'ui/state_management/state_monitor_factory';
|
||||
export { ensureDefaultIndexPattern } from 'ui/legacy_compat';
|
||||
export { unhashUrl } from 'ui/state_management/state_hashing';
|
||||
export { unhashUrl } from '../../../../../plugins/kibana_utils/public';
|
||||
export { IInjector } from 'ui/chrome';
|
||||
export { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder';
|
||||
|
|
|
@ -78,7 +78,7 @@ export { tabifyAggResponse } from 'ui/agg_response/tabify';
|
|||
// @ts-ignore
|
||||
export { vislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib';
|
||||
export { ensureDefaultIndexPattern } from 'ui/legacy_compat';
|
||||
export { unhashUrl } from 'ui/state_management/state_hashing';
|
||||
export { unhashUrl } from '../../../../../plugins/kibana_utils/public';
|
||||
|
||||
// EXPORT types
|
||||
export { Vis } from 'ui/vis';
|
||||
|
|
|
@ -45,7 +45,7 @@ import {
|
|||
showSaveModal,
|
||||
stateMonitorFactory,
|
||||
subscribeWithScope,
|
||||
unhashUrl,
|
||||
unhashUrl
|
||||
} from '../kibana_services';
|
||||
|
||||
const {
|
||||
|
|
|
@ -103,7 +103,7 @@ export { KibanaParsedUrl } from 'ui/url/kibana_parsed_url';
|
|||
export { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query';
|
||||
export { subscribeWithScope } from 'ui/utils/subscribe_with_scope';
|
||||
export { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal';
|
||||
export { unhashUrl } from 'ui/state_management/state_hashing';
|
||||
export { unhashUrl } from '../../../../../plugins/kibana_utils/public';
|
||||
export {
|
||||
Container,
|
||||
Embeddable,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import { hashUrl } from 'ui/state_management/state_hashing';
|
||||
import { hashUrl } from '../../../../plugins/kibana_utils/public';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { fatalError } from 'ui/notify';
|
||||
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
|
||||
import url from 'url';
|
||||
|
||||
import {
|
||||
unhashUrl,
|
||||
} from '../../state_management/state_hashing';
|
||||
import { unhashUrl } from '../../../../../plugins/kibana_utils/public';
|
||||
import { toastNotifications } from '../../notify/toasts';
|
||||
|
||||
export function registerSubUrlHooks(angularModule, internals) {
|
||||
angularModule.run(($rootScope, Private, $location) => {
|
||||
|
@ -29,8 +28,14 @@ export function registerSubUrlHooks(angularModule, internals) {
|
|||
|
||||
function updateSubUrls() {
|
||||
const urlWithHashes = window.location.href;
|
||||
const urlWithStates = unhashUrl(urlWithHashes);
|
||||
internals.trackPossibleSubUrl(urlWithStates);
|
||||
let urlWithStates;
|
||||
try {
|
||||
urlWithStates = unhashUrl(urlWithHashes);
|
||||
} catch (e) {
|
||||
toastNotifications.addDanger(e.message);
|
||||
}
|
||||
|
||||
internals.trackPossibleSubUrl(urlWithStates || urlWithHashes);
|
||||
}
|
||||
|
||||
function onRouteChange($event) {
|
||||
|
|
|
@ -26,11 +26,11 @@ import { toastNotifications } from '../../notify';
|
|||
import * as FatalErrorNS from '../../notify/fatal_error';
|
||||
import { StateProvider } from '../state';
|
||||
import {
|
||||
unhashQuery,
|
||||
createStateHash,
|
||||
isStateHash,
|
||||
unhashQuery
|
||||
} from '../state_hashing';
|
||||
import { HashedItemStore } from '../../../../../plugins/kibana_utils/public';
|
||||
HashedItemStore
|
||||
} from '../../../../../plugins/kibana_utils/public';
|
||||
import { StubBrowserStorage } from 'test_utils/stub_browser_storage';
|
||||
import { EventsProvider } from '../../events';
|
||||
|
||||
|
|
|
@ -35,11 +35,7 @@ import { fatalError, toastNotifications } from '../notify';
|
|||
import './config_provider';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
import { callEach } from '../utils/function';
|
||||
import { hashedItemStore } from '../../../../plugins/kibana_utils/public';
|
||||
import {
|
||||
createStateHash,
|
||||
isStateHash
|
||||
} from './state_hashing';
|
||||
import { hashedItemStore, isStateHash, createStateHash } from '../../../../plugins/kibana_utils/public';
|
||||
|
||||
export function StateProvider(Private, $rootScope, $location, stateManagementConfig, config, kbnUrl, $injector) {
|
||||
const Events = Private(EventsProvider);
|
||||
|
|
|
@ -28,3 +28,5 @@ export * from './errors';
|
|||
export * from './field_mapping';
|
||||
export * from './storage';
|
||||
export * from './storage/hashed_item_store';
|
||||
export * from './state_management/state_hash';
|
||||
export * from './state_management/url';
|
||||
|
|
|
@ -17,5 +17,4 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export { hashUrl, unhashUrl, hashQuery, unhashQuery } from './hash_unhash_url';
|
||||
export { createStateHash, isStateHash } from './state_hash';
|
||||
export * from './state_hash';
|
|
@ -18,9 +18,8 @@
|
|||
*/
|
||||
|
||||
import { encode as encodeRison } from 'rison-node';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { mockStorage } from '../../../../../plugins/kibana_utils/public/storage/hashed_item_store/mock';
|
||||
import { createStateHash, isStateHash } from '../state_hashing';
|
||||
import { mockStorage } from '../../storage/hashed_item_store/mock';
|
||||
import { createStateHash, isStateHash } from './state_hash';
|
||||
|
||||
describe('stateHash', () => {
|
||||
beforeEach(() => {
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { Sha256 } from '../../../../../core/public/utils';
|
||||
import { hashedItemStore } from '../../../../../plugins/kibana_utils/public';
|
||||
import { hashedItemStore } from '../../storage/hashed_item_store';
|
||||
|
||||
// This prefix is used to identify hash strings that have been encoded in the URL.
|
||||
const HASH_PREFIX = 'h@';
|
|
@ -17,9 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { mockStorage } from '../../../../../plugins/kibana_utils/public/storage/hashed_item_store/mock';
|
||||
import { HashedItemStore } from '../../../../../plugins/kibana_utils/public';
|
||||
import { mockStorage } from '../../storage/hashed_item_store/mock';
|
||||
import { HashedItemStore } from '../../storage/hashed_item_store';
|
||||
import { hashUrl, unhashUrl } from './hash_unhash_url';
|
||||
|
||||
describe('hash unhash url', () => {
|
|
@ -22,8 +22,8 @@ import rison, { RisonObject } from 'rison-node';
|
|||
import { stringify as stringifyQueryString } from 'querystring';
|
||||
import encodeUriQuery from 'encode-uri-query';
|
||||
import { format as formatUrl, parse as parseUrl } from 'url';
|
||||
import { hashedItemStore } from '../../../../../plugins/kibana_utils/public';
|
||||
import { createStateHash, isStateHash } from './state_hash';
|
||||
import { hashedItemStore } from '../../storage/hashed_item_store';
|
||||
import { createStateHash, isStateHash } from '../state_hash';
|
||||
|
||||
export type IParsedUrlQuery = Record<string, any>;
|
||||
|
||||
|
@ -98,7 +98,7 @@ export function retrieveState(stateHash: string): RisonObject {
|
|||
const json = hashedItemStore.getItem(stateHash);
|
||||
const throwUnableToRestoreUrlError = () => {
|
||||
throw new Error(
|
||||
i18n.translate('common.ui.stateManagement.unableToRestoreUrlErrorMessage', {
|
||||
i18n.translate('kibana_utils.stateManagement.url.unableToRestoreUrlErrorMessage', {
|
||||
defaultMessage:
|
||||
'Unable to completely restore the URL, be sure to use the share functionality.',
|
||||
})
|
||||
|
@ -125,7 +125,7 @@ export function persistState(state: RisonObject): string {
|
|||
if (isItemSet) return hash;
|
||||
// If we ran out of space trying to persist the state, notify the user.
|
||||
const message = i18n.translate(
|
||||
'common.ui.stateManagement.unableToStoreHistoryInSessionErrorMessage',
|
||||
'kibana_utils.stateManagement.url.unableToStoreHistoryInSessionErrorMessage',
|
||||
{
|
||||
defaultMessage:
|
||||
'Kibana is unable to store history items in your session ' +
|
|
@ -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 * from './hash_unhash_url';
|
24
test/typings/encode_uri_query.d.ts
vendored
Normal file
24
test/typings/encode_uri_query.d.ts
vendored
Normal 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.
|
||||
*/
|
||||
|
||||
declare module 'encode-uri-query' {
|
||||
function encodeUriQuery(query: string, usePercentageSpace?: boolean): string;
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default encodeUriQuery;
|
||||
}
|
39
test/typings/rison_node.d.ts
vendored
Normal file
39
test/typings/rison_node.d.ts
vendored
Normal 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.
|
||||
*/
|
||||
|
||||
declare module 'rison-node' {
|
||||
export type RisonValue = null | boolean | number | string | RisonObject | RisonArray;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface RisonArray extends Array<RisonValue> {}
|
||||
|
||||
export interface RisonObject {
|
||||
[key: string]: RisonValue;
|
||||
}
|
||||
|
||||
export const decode: (input: string) => RisonValue;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
export const decode_object: (input: string) => RisonObject;
|
||||
|
||||
export const encode: <Input extends RisonValue>(input: Input) => string;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
export const encode_object: <Input extends RisonObject>(input: Input) => string;
|
||||
}
|
|
@ -676,6 +676,8 @@
|
|||
"kibana-react.savedObjects.saveModal.saveButtonLabel": "保存",
|
||||
"kibana-react.savedObjects.saveModal.saveTitle": "{objectType} を保存",
|
||||
"kibana-react.savedObjects.saveModal.titleLabel": "タイトル",
|
||||
"kibana_utils.stateManagement.url.unableToRestoreUrlErrorMessage": "URL を完全に復元できません。共有機能を使用していることを確認してください。",
|
||||
"kibana_utils.stateManagement.url.unableToStoreHistoryInSessionErrorMessage": "セッションがいっぱいで安全に削除できるアイテムが見つからないため、Kibana は履歴アイテムを保存できません。\n\nこれは大抵新規タブに移動することで解決されますが、より大きな問題が原因である可能性もあります。このメッセージが定期的に表示される場合は、{gitHubIssuesUrl} で問題を報告してください。",
|
||||
"inspector.closeButton": "インスペクターを閉じる",
|
||||
"inspector.reqTimestampDescription": "リクエストの開始が記録された時刻です",
|
||||
"inspector.reqTimestampKey": "リクエストのタイムスタンプ",
|
||||
|
@ -12750,4 +12752,4 @@
|
|||
"xpack.licensing.check.errorUnavailableMessage": "現在ライセンス情報が利用できないため {pluginName} を使用できません。",
|
||||
"xpack.licensing.check.errorUnsupportedMessage": "ご使用の {licenseType} ライセンスは {pluginName} をサポートしていません。ライセンスをアップグレードしてください。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -677,6 +677,8 @@
|
|||
"kibana-react.savedObjects.saveModal.saveButtonLabel": "保存",
|
||||
"kibana-react.savedObjects.saveModal.saveTitle": "保存 {objectType}",
|
||||
"kibana-react.savedObjects.saveModal.titleLabel": "标题",
|
||||
"kibana_utils.stateManagement.url.unableToRestoreUrlErrorMessage": "无法完整还原 URL,确保使用共享功能。",
|
||||
"kibana_utils.stateManagement.url.unableToStoreHistoryInSessionErrorMessage": "Kibana 无法将历史记录项存储在您的会话中,因为其已满,并且似乎没有任何可安全删除的项。\n\n通常可通过移至新的标签页来解决此问题,但这会导致更大的问题。如果您有规律地看到此消息,请在 {gitHubIssuesUrl} 提交问题。",
|
||||
"inspector.closeButton": "关闭检查器",
|
||||
"inspector.reqTimestampDescription": "记录请求启动的时间",
|
||||
"inspector.reqTimestampKey": "请求时间戳",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue