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

[State Management] Move url state_hashing utils to kibana_utils #52280

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
showSaveModal,
stateMonitorFactory,
subscribeWithScope,
unhashUrl,
unhashUrl
} from '../kibana_services';

const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
15 changes: 10 additions & 5 deletions src/legacy/ui/public/chrome/api/sub_url_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@

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) => {
const subUrlRouteFilter = Private(SubUrlRouteFilterProvider);

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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixes small regression introduced in #51835,
When sharing hashed url directly it should show error toast instead of full page fatal error

}

internals.trackPossibleSubUrl(urlWithStates || urlWithHashes);
}

function onRouteChange($event) {
Expand Down
6 changes: 3 additions & 3 deletions src/legacy/ui/public/state_management/__tests__/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
6 changes: 1 addition & 5 deletions src/legacy/ui/public/state_management/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/kibana_utils/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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@';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

Expand Down Expand Up @@ -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.',
})
Expand All @@ -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 ' +
Expand Down
20 changes: 20 additions & 0 deletions src/plugins/kibana_utils/public/state_management/url/index.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 24 additions & 0 deletions test/typings/encode_uri_query.d.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 39 additions & 0 deletions test/typings/rison_node.d.ts
Original file line number Diff line number Diff line change
@@ -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;
}
4 changes: 3 additions & 1 deletion x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -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} で問題を報告してください。",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from common.ui.stateManagement

"inspector.closeButton": "インスペクターを閉じる",
"inspector.reqTimestampDescription": "リクエストの開始が記録された時刻です",
"inspector.reqTimestampKey": "リクエストのタイムスタンプ",
Expand Down Expand Up @@ -12750,4 +12752,4 @@
"xpack.licensing.check.errorUnavailableMessage": "現在ライセンス情報が利用できないため {pluginName} を使用できません。",
"xpack.licensing.check.errorUnsupportedMessage": "ご使用の {licenseType} ライセンスは {pluginName} をサポートしていません。ライセンスをアップグレードしてください。"
}
}
}
2 changes: 2 additions & 0 deletions x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "请求时间戳",
Expand Down