Skip to content

Commit

Permalink
[APM] Typed client-side routing (#104274)
Browse files Browse the repository at this point in the history
* [APM] @kbn/typed-router-config

* [APM] typed route config

* Breadcrumbs, wildcards

* Migrate settings, home

* Migrate part of service detail page

* Migrate remaining routes, tests

* Set maxWorkers for precommit script to 4

* Add jest types to tsconfigs

* Make sure transaction distribution data is fetched

* Fix typescript errors

* Remove usage of react-router's useParams

* Add route() utility function

* Don't use ApmServiceContext for alert flyouts

* Don't add onClick handler for breadcrumb

* Clarify ts-ignore

* Remove unused things

* Update documentation

* Use useServiceName() in ServiceMap component
  • Loading branch information
dgieselaar authored Jul 15, 2021
1 parent e999b33 commit 821aeb1
Show file tree
Hide file tree
Showing 98 changed files with 2,958 additions and 1,362 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
"@kbn/securitysolution-utils": "link:bazel-bin/packages/kbn-securitysolution-utils",
"@kbn/server-http-tools": "link:bazel-bin/packages/kbn-server-http-tools",
"@kbn/server-route-repository": "link:bazel-bin/packages/kbn-server-route-repository",
"@kbn/typed-react-router-config": "link:bazel-bin/packages/kbn-typed-react-router-config",
"@kbn/std": "link:bazel-bin/packages/kbn-std",
"@kbn/tinymath": "link:bazel-bin/packages/kbn-tinymath",
"@kbn/ui-framework": "link:bazel-bin/packages/kbn-ui-framework",
Expand All @@ -177,6 +178,7 @@
"@turf/distance": "6.0.1",
"@turf/helpers": "6.0.1",
"@turf/length": "^6.0.2",
"@types/react-router-config": "^5.0.2",
"@types/redux-logger": "^3.0.8",
"JSONStream": "1.3.5",
"abort-controller": "^3.0.0",
Expand Down Expand Up @@ -356,6 +358,7 @@
"react-resize-detector": "^4.2.0",
"react-reverse-portal": "^1.0.4",
"react-router": "^5.2.0",
"react-router-config": "^5.1.1",
"react-router-dom": "^5.2.0",
"react-router-redux": "^4.0.8",
"react-shortcuts": "^2.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ filegroup(
"//packages/kbn-test:build",
"//packages/kbn-test-subj-selector:build",
"//packages/kbn-tinymath:build",
"//packages/kbn-typed-react-router-config:build",
"//packages/kbn-ui-framework:build",
"//packages/kbn-ui-shared-deps:build",
"//packages/kbn-utility-types:build",
Expand Down
73 changes: 73 additions & 0 deletions packages/kbn-io-ts-utils/src/deep_exact_rt/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import * as t from 'io-ts';
import { deepExactRt } from '.';
import { mergeRt } from '../merge_rt';

describe('deepExactRt', () => {
it('recursively wraps partial/interface types in t.exact', () => {
const a = t.type({
path: t.type({
serviceName: t.string,
}),
query: t.type({
foo: t.string,
}),
});

const b = t.type({
path: t.type({
transactionType: t.string,
}),
});

const merged = mergeRt(a, b);

expect(
deepExactRt(a).decode({
path: {
serviceName: '',
transactionType: '',
},
query: {
foo: '',
bar: '',
},
// @ts-ignore
}).right
).toEqual({ path: { serviceName: '' }, query: { foo: '' } });

expect(
deepExactRt(b).decode({
path: {
serviceName: '',
transactionType: '',
},
query: {
foo: '',
bar: '',
},
// @ts-ignore
}).right
).toEqual({ path: { transactionType: '' } });

expect(
deepExactRt(merged).decode({
path: {
serviceName: '',
transactionType: '',
},
query: {
foo: '',
bar: '',
},
// @ts-ignore
}).right
).toEqual({ path: { serviceName: '', transactionType: '' }, query: { foo: '' } });
});
});
45 changes: 45 additions & 0 deletions packages/kbn-io-ts-utils/src/deep_exact_rt/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import * as t from 'io-ts';
import { mapValues } from 'lodash';
import { mergeRt } from '../merge_rt';
import { isParsableType, ParseableType } from '../parseable_types';

export function deepExactRt<T extends t.Type<any> | ParseableType>(type: T): T;

export function deepExactRt(type: t.Type<any> | ParseableType) {
if (!isParsableType(type)) {
return type;
}

switch (type._tag) {
case 'ArrayType':
return t.array(deepExactRt(type.type));

case 'DictionaryType':
return t.dictionary(type.domain, deepExactRt(type.codomain));

case 'InterfaceType':
return t.exact(t.interface(mapValues(type.props, deepExactRt)));

case 'PartialType':
return t.exact(t.partial(mapValues(type.props, deepExactRt)));

case 'IntersectionType':
return t.intersection(type.types.map(deepExactRt) as any);

case 'UnionType':
return t.union(type.types.map(deepExactRt) as any);

case 'MergeType':
return mergeRt(deepExactRt(type.types[0]), deepExactRt(type.types[1]));

default:
return type;
}
}
39 changes: 39 additions & 0 deletions packages/kbn-io-ts-utils/src/parseable_types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import * as t from 'io-ts';
import { MergeType } from '../merge_rt';

export type ParseableType =
| t.StringType
| t.NumberType
| t.BooleanType
| t.ArrayType<t.Mixed>
| t.RecordC<t.Mixed, t.Mixed>
| t.DictionaryType<t.Mixed, t.Mixed>
| t.InterfaceType<t.Props>
| t.PartialType<t.Props>
| t.UnionType<t.Mixed[]>
| t.IntersectionType<t.Mixed[]>
| MergeType<t.Mixed, t.Mixed>;

const parseableTags = [
'StringType',
'NumberType',
'BooleanType',
'ArrayType',
'DictionaryType',
'InterfaceType',
'PartialType',
'UnionType',
'IntersectionType',
'MergeType',
];

export const isParsableType = (type: t.Type<any> | ParseableType): type is ParseableType => {
return '_tag' in type && parseableTags.includes(type._tag);
};
32 changes: 2 additions & 30 deletions packages/kbn-io-ts-utils/src/to_json_schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,7 @@
*/
import * as t from 'io-ts';
import { mapValues } from 'lodash';

type JSONSchemableValueType =
| t.StringType
| t.NumberType
| t.BooleanType
| t.ArrayType<t.Mixed>
| t.RecordC<t.Mixed, t.Mixed>
| t.DictionaryType<t.Mixed, t.Mixed>
| t.InterfaceType<t.Props>
| t.PartialType<t.Props>
| t.UnionType<t.Mixed[]>
| t.IntersectionType<t.Mixed[]>;

const tags = [
'StringType',
'NumberType',
'BooleanType',
'ArrayType',
'DictionaryType',
'InterfaceType',
'PartialType',
'UnionType',
'IntersectionType',
];

const isSchemableValueType = (type: t.Mixed): type is JSONSchemableValueType => {
// @ts-ignore
return tags.includes(type._tag);
};
import { isParsableType } from '../parseable_types';

interface JSONSchemaObject {
type: 'object';
Expand Down Expand Up @@ -74,7 +46,7 @@ type JSONSchema =
| JSONSchemaAnyOf;

export const toJsonSchema = (type: t.Mixed): JSONSchema => {
if (isSchemableValueType(type)) {
if (isParsableType(type)) {
switch (type._tag) {
case 'ArrayType':
return { type: 'array', items: toJsonSchema(type.type) };
Expand Down
113 changes: 113 additions & 0 deletions packages/kbn-typed-react-router-config/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm")

PKG_BASE_NAME = "kbn-typed-react-router-config"
PKG_REQUIRE_NAME = "@kbn/typed-react-router-config"

SOURCE_FILES = glob(
[
"src/**/*.ts",
"src/**/*.tsx",
],
exclude = [
"**/*.test.*",
]
)

SRCS = SOURCE_FILES

filegroup(
name = "srcs",
srcs = SRCS,
)

NPM_MODULE_EXTRA_FILES = [
"package.json",
]

SRC_DEPS = [
"@npm//tslib",
"@npm//utility-types",
"@npm//io-ts",
"@npm//query-string",
"@npm//react-router-config",
"@npm//react-router-dom",
"//packages/kbn-io-ts-utils",
]

TYPES_DEPS = [
"@npm//@types/jest",
"@npm//@types/node",
"@npm//@types/react-router-config",
"@npm//@types/react-router-dom",
]

DEPS = SRC_DEPS + TYPES_DEPS

ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
],
)

ts_config(
name = "tsconfig_browser",
src = "tsconfig.browser.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.browser.json",
],
)

ts_project(
name = "tsc",
args = ['--pretty'],
srcs = SRCS,
deps = DEPS,
declaration = True,
declaration_dir = "target_types",
declaration_map = True,
incremental = True,
out_dir = "target_node",
source_map = True,
root_dir = "src",
tsconfig = ":tsconfig",
)

ts_project(
name = "tsc_browser",
args = ['--pretty'],
srcs = SRCS,
deps = DEPS,
declaration = False,
incremental = True,
out_dir = "target_web",
source_map = True,
root_dir = "src",
tsconfig = ":tsconfig_browser",
)

js_library(
name = PKG_BASE_NAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = DEPS + [":tsc", ":tsc_browser"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)

pkg_npm(
name = "npm_module",
deps = [
":%s" % PKG_BASE_NAME,
]
)

filegroup(
name = "build",
srcs = [
":npm_module",
],
visibility = ["//visibility:public"],
)
13 changes: 13 additions & 0 deletions packages/kbn-typed-react-router-config/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-typed-react-router-config'],
};
9 changes: 9 additions & 0 deletions packages/kbn-typed-react-router-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "@kbn/typed-react-router-config",
"main": "target_node/index.js",
"types": "target_types/index.d.ts",
"browser": "target_web/index.js",
"version": "1.0.0",
"license": "SSPL-1.0 OR Elastic License 2.0",
"private": true
}
Loading

0 comments on commit 821aeb1

Please sign in to comment.