@spinnaker/kayenta 1.0.5 → 2.1.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/.github/workflows/ci-branch.yml +73 -0
  2. package/.github/workflows/publish_lib_test.yml +26 -0
  3. package/.husky/pre-commit +6 -0
  4. package/.lintstagedrc.json +4 -0
  5. package/build/dist/index-6aa5a1a4.js +2 -0
  6. package/build/dist/index-6aa5a1a4.js.map +1 -0
  7. package/build/dist/index.d.ts +1 -0
  8. package/build/dist/index.d.ts.map +1 -1
  9. package/build/dist/index.js +1 -38
  10. package/build/dist/index.js.map +1 -1
  11. package/build/dist/kayenta/canary.dataSource.bridge.d.ts +2 -0
  12. package/build/dist/kayenta/canary.dataSource.bridge.d.ts.map +1 -0
  13. package/build/dist/kayenta/canary.dataSource.stub.d.ts +9 -0
  14. package/build/dist/kayenta/canary.dataSource.stub.d.ts.map +1 -0
  15. package/build/dist/kayenta/edit/copyConfigButton.d.ts +1 -1
  16. package/build/dist/kayenta/edit/createConfigButton.d.ts +1 -1
  17. package/build/dist/kayenta/index.d.ts +0 -1
  18. package/build/dist/kayenta/index.d.ts.map +1 -1
  19. package/build/dist/kayenta/navigation/canary.states.d.ts +5 -1
  20. package/build/dist/kayenta/navigation/canary.states.d.ts.map +1 -1
  21. package/build/dist/kayenta/navigation/canary.states.stub.d.ts +4 -0
  22. package/build/dist/kayenta/navigation/canary.states.stub.d.ts.map +1 -0
  23. package/build/dist/kayenta/report/detail/graph/metricSetPairGraph.service.d.ts +1 -1
  24. package/build/dist/kayenta/report/detail/graph/metricSetPairGraph.service.d.ts.map +1 -1
  25. package/build/dist/kayenta/report/detail/graph/semiotic/index.d.ts.map +1 -1
  26. package/build/dist/kayenta/stages/kayentaStage/kayentaStage.d.ts +28 -1
  27. package/build/dist/kayenta/stages/kayentaStage/kayentaStage.d.ts.map +1 -1
  28. package/build/dist/kayenta/stages/kayentaStage/kayentaStage.transformer.d.ts +0 -1
  29. package/build/dist/kayenta/stages/kayentaStage/kayentaStage.transformer.d.ts.map +1 -1
  30. package/build/dist/lazy-94b6420d.js +2 -0
  31. package/build/dist/lazy-94b6420d.js.map +1 -0
  32. package/build/dist/lazy.d.ts +6 -0
  33. package/build/dist/lazy.d.ts.map +1 -0
  34. package/build/dist/semioticGraph-a9ade595.js +2 -0
  35. package/build/dist/semioticGraph-a9ade595.js.map +1 -0
  36. package/build/dist/stub.d.ts +15 -0
  37. package/build/dist/stub.d.ts.map +1 -0
  38. package/package.json +19 -16
  39. package/rollup.config.js +2 -0
  40. package/src/index.ts +1 -0
  41. package/src/kayenta/canary.dataSource.bridge.ts +53 -0
  42. package/src/kayenta/canary.dataSource.stub.ts +64 -0
  43. package/src/kayenta/index.ts +0 -1
  44. package/src/kayenta/navigation/canary.states.stub.ts +28 -0
  45. package/src/kayenta/navigation/canary.states.ts +158 -166
  46. package/src/kayenta/report/detail/graph/metricSetPairGraph.service.ts +1 -1
  47. package/src/kayenta/report/detail/graph/semiotic/index.tsx +19 -0
  48. package/src/kayenta/stages/kayentaStage/kayentaStage.transformer.ts +0 -4
  49. package/src/kayenta/stages/kayentaStage/kayentaStage.ts +150 -178
  50. package/src/lazy.ts +29 -0
  51. package/src/stub.ts +60 -0
  52. package/build/dist/kayenta/canary.dataSource.d.ts +0 -2
  53. package/build/dist/kayenta/canary.dataSource.d.ts.map +0 -1
  54. package/build/dist/kayenta/canary.module.d.ts +0 -5
  55. package/build/dist/kayenta/canary.module.d.ts.map +0 -1
  56. package/build/dist/kayenta/components/components.module.d.ts +0 -2
  57. package/build/dist/kayenta/components/components.module.d.ts.map +0 -1
  58. package/build/dist/kayenta/stages/stages.module.d.ts +0 -2
  59. package/build/dist/kayenta/stages/stages.module.d.ts.map +0 -1
  60. package/src/kayenta/canary.dataSource.ts +0 -131
  61. package/src/kayenta/canary.module.ts +0 -20
  62. package/src/kayenta/components/components.module.ts +0 -7
  63. package/src/kayenta/report/detail/graph/semiotic/index.ts +0 -10
  64. package/src/kayenta/stages/stages.module.ts +0 -6
@@ -0,0 +1,15 @@
1
+ import 'kayenta/canary.help';
2
+ /**
3
+ * This is the stub for Kayenta in deck
4
+ *
5
+ * - Registers all AngularJS components and controllers
6
+ * - Registers the full Kayenta Stage with Deck
7
+ * - Registers STUB routes for canary configs and canary reports (see: registerKayentaStateStubs)
8
+ * - These stub routes are names and URLs only
9
+ * - A lazyLoad router hook runs when the user navigates to a stub route and loads the remainder of Kayenta
10
+ * - Registers a DataSource that fetches kayenta canary/report data (and provides the nav items)
11
+ *
12
+ * See: lazy.ts for what happens next
13
+ */
14
+ export declare const KAYENTA_MODULE = "spinnaker.kayenta";
15
+ //# sourceMappingURL=stub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stub.d.ts","sourceRoot":"","sources":["../../src/stub.ts"],"names":[],"mappings":"AAGA,OAAO,qBAAqB,CAAC;AAgB7B;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,cAAc,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spinnaker/kayenta",
3
- "version": "1.0.5",
3
+ "version": "2.1.0-rc1",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,20 +25,21 @@
25
25
  "postinstall": "check-plugin && check-peer-dependencies || true",
26
26
  "prettier": "prettier --write 'src/**/*.{js,jsx,ts,tsx,html,css,less,json}'",
27
27
  "proxy": "dev-proxy",
28
- "watch": "rollup -c -w --no-watch.clearScreen"
28
+ "watch": "rollup -c -w --no-watch.clearScreen",
29
+ "prepare": "husky-install"
29
30
  },
30
31
  "dependencies": {
31
32
  "@uirouter/core": "6.0.4",
32
33
  "@uirouter/react": "1.0.2",
33
34
  "@uirouter/react-hybrid": "1.0.2",
34
35
  "angular-ui-bootstrap": "^2.5.0",
35
- "ansi_up": "^4.0.4",
36
+ "ansi_up": "^5.0.0",
36
37
  "bootstrap": "3.4.1",
37
38
  "class-autobind-decorator": "^2.2.1",
38
39
  "human-readable-ids": "^1.0.4",
39
40
  "lodash": "4.17.21",
40
41
  "lodash-decorators": "4.5.0",
41
- "lodash-es": "4.17.15",
42
+ "lodash-es": "4.17.21",
42
43
  "memoize-one": "^4.0.2",
43
44
  "ngimport": "^0.6.0",
44
45
  "react": "~16.14.0",
@@ -68,19 +69,20 @@
68
69
  "ui-select": "^0.19.6"
69
70
  },
70
71
  "devDependencies": {
72
+ "@apollo/client": "^3.3.15",
71
73
  "@babel/preset-env": "^7.13.12",
72
74
  "@babel/preset-react": "^7.13.13",
73
75
  "@babel/preset-typescript": "^7.13.0",
74
- "@rollup/plugin-commonjs": "16.0.0",
76
+ "@rollup/plugin-commonjs": "18.0.0",
75
77
  "@rollup/plugin-json": "^4.1.0",
76
- "@rollup/plugin-node-resolve": "10.0.0",
78
+ "@rollup/plugin-node-resolve": "11.2.1",
77
79
  "@rollup/plugin-replace": "^2.4.2",
78
- "@rollup/plugin-typescript": "6.1.0",
80
+ "@rollup/plugin-typescript": "8.2.1",
79
81
  "@rollup/plugin-url": "6.0.0",
80
- "@spinnaker/core": "0.0.563",
82
+ "@spinnaker/core": "0.0.571",
81
83
  "@spinnaker/eslint-plugin": "1.0.13",
82
- "@spinnaker/pluginsdk": "0.0.25",
83
- "@spinnaker/pluginsdk-peerdeps": "0.0.11",
84
+ "@spinnaker/pluginsdk": "0.0.30",
85
+ "@spinnaker/pluginsdk-peerdeps": "0.0.14",
84
86
  "@spinnaker/presentation": "0.0.4",
85
87
  "@types/angular": "1.6.26",
86
88
  "@types/angular-mocks": "1.5.10",
@@ -130,26 +132,27 @@
130
132
  "eslint": "7.10.0",
131
133
  "eslint-config-prettier": "6.12.0",
132
134
  "eslint-plugin-react-hooks": "4.1.2",
133
- "husky": "^1.3.1",
135
+ "graphql": "^15.5.0",
134
136
  "jest": "^26.6.3",
135
137
  "jquery": "3.5.1",
136
138
  "jquery-textcomplete": "1.6.1",
137
- "jquery-ui": "1.12.0",
139
+ "jquery-ui": "1.13.2",
138
140
  "js-worker-search": "^1.2.1",
139
141
  "license-checker": "^15.0.0",
140
- "luxon": "1.23.0",
142
+ "luxon": "1.28.1",
141
143
  "npm-run-all": "4.1.5",
142
144
  "prettier": "2.1.2",
143
145
  "pretty-quick": "3.1.0",
144
146
  "prop-types": "15.6.1",
147
+ "react-toastify": "^7.0.4",
145
148
  "react2angular": "^3.2.1",
146
149
  "redux-test-utils": "^0.3.0",
147
- "rollup": "2.33.1",
150
+ "rollup": "2.45.2",
148
151
  "rollup-plugin-external-globals": "0.6.1",
149
- "rollup-plugin-less": "1.1.2",
152
+ "rollup-plugin-less": "1.1.3",
150
153
  "rollup-plugin-postcss": "3.1.8",
151
154
  "rollup-plugin-terser": "7.0.2",
152
- "rollup-plugin-visualizer": "^4.2.2",
155
+ "rollup-plugin-visualizer": "5.4.1",
153
156
  "shx": "0.3.3",
154
157
  "typescript": "^4.0.0",
155
158
  "utf-8-validate": "5.0.3"
package/rollup.config.js CHANGED
@@ -16,6 +16,8 @@ const externals = [
16
16
  'luxon',
17
17
  'prop-types',
18
18
  'react',
19
+ 'react-bootstrap',
20
+ 'react-select',
19
21
  'react-dom',
20
22
  'semiotic',
21
23
  ];
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
+ export * from './stub';
1
2
  export * from './kayenta';
@@ -0,0 +1,53 @@
1
+ import { Application } from '@spinnaker/core';
2
+
3
+ import * as Creators from './actions/creators';
4
+ import { canaryStore } from './canary';
5
+ import { stub } from './canary.dataSource.stub';
6
+ import { ICanaryExecutionStatusResult } from './domain/ICanaryExecutionStatusResult';
7
+ import { ICanaryConfigSummary, IJudge } from './domain/index';
8
+ import { listCanaryExecutions } from './service/canaryRun.service';
9
+
10
+ export function bridgeKayentaDataSourceToReduxStore() {
11
+ stub.afterConfigsLoaded = (application: Application) => {
12
+ if (application !== canaryStore.getState().data.application) {
13
+ return;
14
+ }
15
+ canaryStore.dispatch(
16
+ Creators.updateConfigSummaries({
17
+ configSummaries: application.getDataSource('canaryConfigs').data as ICanaryConfigSummary[],
18
+ }),
19
+ );
20
+ };
21
+
22
+ stub.afterJudgesLoaded = (application: Application) => {
23
+ if (application !== canaryStore.getState().data.application) {
24
+ return;
25
+ }
26
+ canaryStore.dispatch(
27
+ Creators.updateJudges({
28
+ judges: application.getDataSource('canaryJudges').data as IJudge[],
29
+ }),
30
+ );
31
+ };
32
+
33
+ stub.loadCanaryExecutions = (application: Application) => {
34
+ const listExecutionsRequest = listCanaryExecutions(application.name);
35
+
36
+ listExecutionsRequest.catch((error) => {
37
+ canaryStore.dispatch(Creators.loadExecutionsFailure({ error }));
38
+ });
39
+
40
+ return listExecutionsRequest;
41
+ };
42
+
43
+ stub.afterCanaryExecutionsLoaded = (application: Application) => {
44
+ if (application !== canaryStore.getState().data.application) {
45
+ return;
46
+ }
47
+ canaryStore.dispatch(
48
+ Creators.loadExecutionsSuccess({
49
+ executions: application.getDataSource('canaryExecutions').data as ICanaryExecutionStatusResult[],
50
+ }),
51
+ );
52
+ };
53
+ }
@@ -0,0 +1,64 @@
1
+ import { CanarySettings } from 'kayenta/canary.settings';
2
+
3
+ import { Application, ApplicationDataSourceRegistry } from '@spinnaker/core';
4
+
5
+ import { getCanaryConfigSummaries, listJudges } from './service/canaryConfig.service';
6
+ import { listCanaryExecutions } from './service/canaryRun.service';
7
+
8
+ // When the lazy portion loads, it overwrites these stub with implementation that bridges data to the redux store
9
+ export const stub = {
10
+ loadCanaryExecutions: (application: Application) => listCanaryExecutions(application.name),
11
+ afterConfigsLoaded: (_application: Application): void => void 0,
12
+ afterJudgesLoaded: (_application: Application): void => void 0,
13
+ afterCanaryExecutionsLoaded: (_application: Application): void => void 0,
14
+ };
15
+
16
+ export function registerKayentaDataSourceStubs() {
17
+ const onLoad = (app: Application, data: any) => Promise.resolve(data);
18
+ const loadCanaryConfigs = (application: Application) => {
19
+ return CanarySettings.showAllConfigs ? getCanaryConfigSummaries() : getCanaryConfigSummaries(application.name);
20
+ };
21
+
22
+ ApplicationDataSourceRegistry.registerDataSource({
23
+ optIn: !CanarySettings.optInAll,
24
+ optional: true,
25
+ loader: loadCanaryConfigs,
26
+ onLoad,
27
+ afterLoad: (application) => stub.afterConfigsLoaded(application),
28
+ description: 'Canary analysis configuration and reporting',
29
+ key: 'canaryConfigs',
30
+ label: 'Canary',
31
+ defaultData: [],
32
+ });
33
+
34
+ ApplicationDataSourceRegistry.registerDataSource({
35
+ key: 'canaryJudges',
36
+ label: 'Canary Configs',
37
+ sref: '.canary.canaryConfig',
38
+ activeState: '**.canaryConfig.**',
39
+ category: 'delivery',
40
+ requiresDataSource: 'canaryConfigs',
41
+ loader: listJudges,
42
+ onLoad,
43
+ afterLoad: (application) => stub.afterJudgesLoaded(application),
44
+ lazy: true,
45
+ autoActivate: true,
46
+ defaultData: [],
47
+ iconName: 'spMenuCanaryConfig',
48
+ });
49
+
50
+ ApplicationDataSourceRegistry.registerDataSource({
51
+ key: 'canaryExecutions',
52
+ label: 'Canary Reports',
53
+ sref: '.canary.report',
54
+ activeState: '**.report.**',
55
+ category: 'delivery',
56
+ requiresDataSource: 'canaryConfigs',
57
+ loader: (application) => stub.loadCanaryExecutions(application),
58
+ onLoad,
59
+ afterLoad: (application) => stub.afterCanaryExecutionsLoaded(application),
60
+ lazy: true,
61
+ defaultData: [],
62
+ iconName: 'spMenuCanaryReport',
63
+ });
64
+ }
@@ -1,4 +1,3 @@
1
- export { KAYENTA_MODULE } from './canary.module';
2
1
  export * from './actions';
3
2
  export * from './domain';
4
3
  export * from './metricStore';
@@ -0,0 +1,28 @@
1
+ import { StateDeclaration, UIRouter } from '@uirouter/core';
2
+
3
+ import { ApplicationStateProvider } from '@spinnaker/core';
4
+
5
+ export function registerKayentaStateStubs(applicationState: ApplicationStateProvider, uiRouter: UIRouter) {
6
+ const states: StateDeclaration[] = [
7
+ {
8
+ name: 'canary',
9
+ url: '/canary',
10
+ lazyLoad: () =>
11
+ import(/* webpackChunkName: "Lazy-Kayenta-Tabs" */ '../../lazy').then((m) =>
12
+ m.lazyInitializeKayenta(applicationState, uiRouter),
13
+ ),
14
+ },
15
+ { name: 'canary.canaryConfig', url: '/config' },
16
+ { name: 'canary.canaryConfig.configDetail', url: '/:id?copy&new' },
17
+ { name: 'canary.canaryConfig.configDefault', url: '' },
18
+ { name: 'canary.report', url: '/report?count' },
19
+ { name: 'canary.report.reportDetail', url: '/:configId/:runId' },
20
+ { name: 'canary.report.reportDefault', url: '' },
21
+ ];
22
+
23
+ ['home.project', 'home.applications'].forEach((prefix) => {
24
+ states
25
+ .map((state) => ({ ...state, name: `${prefix}.application.${state.name}` } as StateDeclaration))
26
+ .forEach((state) => uiRouter.stateRegistry.register(state as StateDeclaration));
27
+ });
28
+ }
@@ -1,5 +1,4 @@
1
- import { UIRouter, Transition } from '@uirouter/core';
2
- import { IWindowService, module } from 'angular';
1
+ import { Transition, UIRouter } from '@uirouter/core';
3
2
  import * as Creators from 'kayenta/actions/creators';
4
3
  import Canary, { canaryStore } from 'kayenta/canary';
5
4
  import ConfigDetailLoader from 'kayenta/edit/configDetailLoader';
@@ -9,182 +8,175 @@ import SelectConfig from 'kayenta/edit/selectConfig';
9
8
  import ResultDetailLoader from 'kayenta/report/detail/detailLoader';
10
9
  import ExecutionListLoadStates from 'kayenta/report/list/loadStates';
11
10
  import Report from 'kayenta/report/report';
11
+ import { $rootScope } from 'ngimport';
12
12
 
13
- import { APPLICATION_STATE_PROVIDER, ApplicationStateProvider, IDeckRootScope, INestedState } from '@spinnaker/core';
13
+ import { ApplicationStateProvider, INestedState } from '@spinnaker/core';
14
14
 
15
+ import '../canary.dataSource.bridge';
15
16
  import { CanarySettings } from '../canary.settings';
16
17
 
17
- export const CANARY_STATES = 'spinnaker.kayenta.canary.states';
18
- module(CANARY_STATES, [APPLICATION_STATE_PROVIDER])
19
- .config([
20
- 'applicationStateProvider',
21
- (applicationStateProvider: ApplicationStateProvider) => {
22
- 'ngInject';
23
- const configDetail: INestedState = {
24
- name: 'configDetail',
25
- url: '/:id?copy&new',
26
- views: {
27
- detail: {
28
- component: ConfigDetailLoader,
29
- $type: 'react',
30
- },
31
- footer: {
32
- component: CanaryConfigSave,
33
- $type: 'react',
34
- },
35
- },
36
- params: {
37
- copy: { type: 'boolean', value: false, squash: true },
38
- new: { type: 'boolean', value: false, squash: true },
39
- },
40
- resolve: [
41
- {
42
- token: 'configNameStream',
43
- deps: [UIRouter],
44
- resolveFn: (uiRouter: any) => uiRouter.globals.params$,
45
- },
46
- ],
47
- };
18
+ export function registerStates($uiRouter: UIRouter, applicationStateProvider: ApplicationStateProvider) {
19
+ const configDetail: INestedState = {
20
+ name: 'configDetail',
21
+ url: '/:id?copy&new',
22
+ views: {
23
+ detail: {
24
+ component: ConfigDetailLoader,
25
+ $type: 'react',
26
+ },
27
+ footer: {
28
+ component: CanaryConfigSave,
29
+ $type: 'react',
30
+ },
31
+ },
32
+ params: {
33
+ copy: { type: 'boolean', value: false, squash: true },
34
+ new: { type: 'boolean', value: false, squash: true },
35
+ },
36
+ resolve: [
37
+ {
38
+ token: 'configNameStream',
39
+ deps: [UIRouter],
40
+ resolveFn: (uiRouter: any) => uiRouter.globals.params$,
41
+ },
42
+ ],
43
+ };
48
44
 
49
- const configDefault: INestedState = {
50
- name: 'configDefault',
51
- url: '',
52
- views: {
53
- detail: {
54
- component: SelectConfig,
55
- $type: 'react',
56
- },
57
- },
58
- };
45
+ const configDefault: INestedState = {
46
+ name: 'configDefault',
47
+ url: '',
48
+ views: {
49
+ detail: {
50
+ component: SelectConfig,
51
+ $type: 'react',
52
+ },
53
+ },
54
+ };
59
55
 
60
- const config: INestedState = {
61
- name: 'canaryConfig',
62
- url: '/config',
63
- views: {
64
- canary: {
65
- component: CanaryConfigEdit,
66
- $type: 'react',
67
- },
68
- },
69
- children: [configDefault, configDetail],
70
- redirectTo: (transition) => transition.to().name + '.configDefault',
71
- };
56
+ const config: INestedState = {
57
+ name: 'canaryConfig',
58
+ url: '/config',
59
+ views: {
60
+ canary: {
61
+ component: CanaryConfigEdit,
62
+ $type: 'react',
63
+ },
64
+ },
65
+ children: [configDefault, configDetail],
66
+ redirectTo: (transition) => transition.to().name + '.configDefault',
67
+ };
72
68
 
73
- const reportDetail: INestedState = {
74
- name: 'reportDetail',
75
- url: '/:configId/:runId',
76
- views: {
77
- detail: {
78
- component: ResultDetailLoader,
79
- $type: 'react',
80
- },
81
- },
82
- resolve: [
83
- {
84
- token: 'resultIdStream',
85
- deps: [UIRouter],
86
- resolveFn: (uiRouter: any) => uiRouter.globals.params$,
87
- },
88
- ],
89
- };
69
+ const reportDetail: INestedState = {
70
+ name: 'reportDetail',
71
+ url: '/:configId/:runId',
72
+ views: {
73
+ detail: {
74
+ component: ResultDetailLoader,
75
+ $type: 'react',
76
+ },
77
+ },
78
+ resolve: [
79
+ {
80
+ token: 'resultIdStream',
81
+ deps: [UIRouter],
82
+ resolveFn: (uiRouter: any) => uiRouter.globals.params$,
83
+ },
84
+ ],
85
+ };
86
+
87
+ const reportDefault: INestedState = {
88
+ name: 'reportDefault',
89
+ url: '',
90
+ views: {
91
+ detail: {
92
+ component: ExecutionListLoadStates,
93
+ $type: 'react',
94
+ },
95
+ },
96
+ };
90
97
 
91
- const reportDefault: INestedState = {
92
- name: 'reportDefault',
93
- url: '',
94
- views: {
95
- detail: {
96
- component: ExecutionListLoadStates,
97
- $type: 'react',
98
- },
99
- },
100
- };
98
+ const report: INestedState = {
99
+ name: 'report',
100
+ url: '/report?count',
101
+ views: {
102
+ canary: {
103
+ component: Report,
104
+ $type: 'react',
105
+ },
106
+ },
107
+ params: {
108
+ count: {
109
+ type: 'int',
110
+ value: CanarySettings.defaultExecutionCount ?? CanarySettings.executionsCountOptions?.[0] ?? 20,
111
+ squash: true,
112
+ },
113
+ },
114
+ children: [reportDetail, reportDefault],
115
+ redirectTo: (transition) => transition.to().name + '.reportDefault',
116
+ };
101
117
 
102
- const report: INestedState = {
103
- name: 'report',
104
- url: '/report?count',
105
- views: {
106
- canary: {
107
- component: Report,
108
- $type: 'react',
109
- },
110
- },
111
- params: {
112
- count: {
113
- type: 'int',
114
- value: CanarySettings.defaultExecutionCount ?? CanarySettings.executionsCountOptions?.[0] ?? 20,
115
- squash: true,
116
- },
117
- },
118
- children: [reportDetail, reportDefault],
119
- redirectTo: (transition) => transition.to().name + '.reportDefault',
120
- };
118
+ const canaryRoot: INestedState = {
119
+ abstract: true,
120
+ name: 'canary',
121
+ url: '/canary',
122
+ views: {
123
+ insight: {
124
+ component: Canary,
125
+ $type: 'react',
126
+ },
127
+ },
128
+ data: {
129
+ pageTitleSection: {
130
+ title: 'Canary',
131
+ },
132
+ },
133
+ children: [config, report],
134
+ };
121
135
 
122
- const canaryRoot: INestedState = {
123
- abstract: true,
124
- name: 'canary',
125
- url: '/canary',
126
- views: {
127
- insight: {
128
- component: Canary,
129
- $type: 'react',
130
- },
131
- },
132
- data: {
133
- pageTitleSection: {
134
- title: 'Canary',
135
- },
136
- },
137
- children: [config, report],
138
- };
136
+ applicationStateProvider.addChildState(canaryRoot);
137
+ }
139
138
 
140
- applicationStateProvider.addChildState(canaryRoot);
139
+ export function registerTransitionHooks($uiRouter: UIRouter) {
140
+ // When leaving a config detail state, clear that config.
141
+ $uiRouter.transitionService.onBefore(
142
+ {
143
+ from: '**.configDetail.**',
144
+ to: (state) => !state.name.includes('configDetail'),
141
145
  },
142
- ])
143
- .run([
144
- '$uiRouter',
145
- '$window',
146
- '$rootScope',
147
- ($uiRouter: UIRouter, $window: IWindowService, $rootScope: IDeckRootScope) => {
148
- // When leaving a config detail state, clear that config.
149
- $uiRouter.transitionService.onBefore(
150
- {
151
- from: '**.configDetail.**',
152
- to: (state) => !state.name.includes('configDetail'),
153
- },
154
- () => {
155
- canaryStore.dispatch(Creators.clearSelectedConfig());
156
- },
157
- );
146
+ () => {
147
+ canaryStore.dispatch(Creators.clearSelectedConfig());
148
+ },
149
+ );
158
150
 
159
- // Prompts confirmation for page navigation if config hasn't been saved.
160
- // Should be possible with a $uiRouter transition hook, but it's not.
161
- $rootScope.$on('$stateChangeStart', (event) => {
162
- const state = canaryStore.getState();
163
- const warningMessage = 'You have unsaved changes.\nAre you sure you want to navigate away from this page?';
164
- if (state.selectedConfig && !state.selectedConfig.isInSyncWithServer) {
165
- if (!$window.confirm(warningMessage)) {
166
- event.preventDefault();
167
- }
168
- }
169
- });
151
+ // Prompts confirmation for page navigation if config hasn't been saved.
152
+ // Should be possible with a $uiRouter transition hook, but it's not.
153
+ $rootScope.$on('$stateChangeStart', (event) => {
154
+ const state = canaryStore.getState();
155
+ const warningMessage = 'You have unsaved changes.\nAre you sure you want to navigate away from this page?';
156
+ if (state.selectedConfig && !state.selectedConfig.isInSyncWithServer) {
157
+ if (!window.confirm(warningMessage)) {
158
+ event.preventDefault();
159
+ }
160
+ }
161
+ });
170
162
 
171
- // Prompts confirmation for page reload if config hasn't been saved.
172
- $uiRouter.transitionService.onEnter({ to: '**.configDetail.**' }, () => {
173
- $window.onbeforeunload = () => {
174
- const state = canaryStore.getState();
175
- // Must return `null` if reload should be allowed.
176
- return (state.selectedConfig && !state.selectedConfig.isInSyncWithServer) || null;
177
- };
178
- });
163
+ // Prompts confirmation for page reload if config hasn't been saved.
164
+ $uiRouter.transitionService.onEnter({ to: '**.configDetail.**' }, () => {
165
+ window.onbeforeunload = () => {
166
+ const state = canaryStore.getState();
167
+ // Must return `null` if reload should be allowed.
168
+ return (state.selectedConfig && !state.selectedConfig.isInSyncWithServer) || null;
169
+ };
170
+ });
179
171
 
180
- // Clears reload hook when leaving canary config view.
181
- $uiRouter.transitionService.onExit({ from: '**.configDetail.**' }, () => {
182
- $window.onbeforeunload = undefined;
183
- });
184
- $uiRouter.transitionService.onSuccess({ to: '**.report.**' }, (transition: Transition) => {
185
- if (transition.params('from').count !== transition.params('to').count) {
186
- canaryStore.dispatch(Creators.setExecutionsCount({ count: transition.params('to').count }));
187
- }
188
- });
189
- },
190
- ]);
172
+ // Clears reload hook when leaving canary config view.
173
+ $uiRouter.transitionService.onExit({ from: '**.configDetail.**' }, () => {
174
+ window.onbeforeunload = undefined;
175
+ });
176
+
177
+ $uiRouter.transitionService.onSuccess({ to: '**.report.**' }, (transition: Transition) => {
178
+ if (transition.params('from').count !== transition.params('to').count) {
179
+ canaryStore.dispatch(Creators.setExecutionsCount({ count: transition.params('to').count }));
180
+ }
181
+ });
182
+ }
@@ -24,7 +24,7 @@ export interface IMetricSetPairGraph {
24
24
  /*
25
25
  * Returns top-level graph component class.
26
26
  * */
27
- getGraph: () => React.ComponentClass<IMetricSetPairGraphProps>;
27
+ getGraph: () => React.ComponentType<IMetricSetPairGraphProps>;
28
28
 
29
29
  /*
30
30
  * Returns true if the graph implementation supports a given graph type.
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import { Suspense } from 'react';
3
+
4
+ import { Spinner } from '@spinnaker/core';
5
+
6
+ import { GraphType, IMetricSetPairGraphProps, metricSetPairGraphService } from '../metricSetPairGraph.service';
7
+ const SemioticGraphLazy = React.lazy(() => import(/* webpackChunkName: "Lazy-KayentaGraphs" */ './semioticGraph'));
8
+
9
+ const supportedGraphTypes: GraphType[] = [GraphType.TimeSeries, GraphType.Histogram, GraphType.BoxPlot];
10
+ // Semiotic component registration
11
+ metricSetPairGraphService.register({
12
+ name: 'semiotic',
13
+ handlesGraphType: (type) => supportedGraphTypes.includes(type),
14
+ getGraph: () => (props: IMetricSetPairGraphProps) => (
15
+ <Suspense fallback={<Spinner />}>
16
+ <SemioticGraphLazy {...props} />
17
+ </Suspense>
18
+ ),
19
+ });