@looker/api-explorer 0.9.26 → 0.9.27
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.
- package/CHANGELOG.md +47 -1
- package/e2e/e2e.spec.ts +1 -1
- package/lib/ApiExplorer.d.ts +2 -6
- package/lib/ApiExplorer.js +53 -74
- package/lib/ApiExplorer.js.map +1 -1
- package/lib/StandaloneApiExplorer.js +35 -47
- package/lib/StandaloneApiExplorer.js.map +1 -1
- package/lib/components/Banner/Banner.d.ts +8 -0
- package/lib/components/Banner/Banner.js +70 -0
- package/lib/components/Banner/Banner.js.map +1 -0
- package/lib/components/Banner/index.d.ts +1 -0
- package/lib/components/Banner/index.js +14 -0
- package/lib/components/Banner/index.js.map +1 -0
- package/lib/components/DocSDKs/DocSDKs.js +3 -3
- package/lib/components/DocSDKs/DocSDKs.js.map +1 -1
- package/lib/components/ExploreType/ExploreType.js +3 -5
- package/lib/components/ExploreType/ExploreType.js.map +1 -1
- package/lib/components/Header/Header.d.ts +2 -5
- package/lib/components/Header/Header.js +1 -5
- package/lib/components/Header/Header.js.map +1 -1
- package/lib/components/SelectorContainer/ApiSpecSelector.d.ts +2 -5
- package/lib/components/SelectorContainer/ApiSpecSelector.js +5 -5
- package/lib/components/SelectorContainer/ApiSpecSelector.js.map +1 -1
- package/lib/components/SelectorContainer/SelectorContainer.d.ts +2 -5
- package/lib/components/SelectorContainer/SelectorContainer.js +3 -7
- package/lib/components/SelectorContainer/SelectorContainer.js.map +1 -1
- package/lib/components/SideNav/SideNav.d.ts +2 -5
- package/lib/components/SideNav/SideNav.js.map +1 -1
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.js +8 -0
- package/lib/components/index.js.map +1 -1
- package/lib/esm/ApiExplorer.js +54 -74
- package/lib/esm/ApiExplorer.js.map +1 -1
- package/lib/esm/StandaloneApiExplorer.js +34 -48
- package/lib/esm/StandaloneApiExplorer.js.map +1 -1
- package/lib/esm/components/Banner/Banner.js +54 -0
- package/lib/esm/components/Banner/Banner.js.map +1 -0
- package/lib/esm/components/Banner/index.js +2 -0
- package/lib/esm/components/Banner/index.js.map +1 -0
- package/lib/esm/components/DocSDKs/DocSDKs.js +2 -2
- package/lib/esm/components/DocSDKs/DocSDKs.js.map +1 -1
- package/lib/esm/components/ExploreType/ExploreType.js +3 -4
- package/lib/esm/components/ExploreType/ExploreType.js.map +1 -1
- package/lib/esm/components/Header/Header.js +1 -5
- package/lib/esm/components/Header/Header.js.map +1 -1
- package/lib/esm/components/SelectorContainer/ApiSpecSelector.js +4 -5
- package/lib/esm/components/SelectorContainer/ApiSpecSelector.js.map +1 -1
- package/lib/esm/components/SelectorContainer/SelectorContainer.js +3 -7
- package/lib/esm/components/SelectorContainer/SelectorContainer.js.map +1 -1
- package/lib/esm/components/SideNav/SideNav.js.map +1 -1
- package/lib/esm/components/index.js +1 -0
- package/lib/esm/components/index.js.map +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/routes/AppRouter.js +3 -7
- package/lib/esm/routes/AppRouter.js.map +1 -1
- package/lib/esm/scenes/DiffScene/DiffScene.js +43 -99
- package/lib/esm/scenes/DiffScene/DiffScene.js.map +1 -1
- package/lib/esm/scenes/DiffScene/DocDiff/DiffItem.js +9 -13
- package/lib/esm/scenes/DiffScene/DocDiff/DiffItem.js.map +1 -1
- package/lib/esm/scenes/DiffScene/DocDiff/DocDiff.js +2 -2
- package/lib/esm/scenes/DiffScene/DocDiff/DocDiff.js.map +1 -1
- package/lib/esm/scenes/MethodScene/MethodScene.js +4 -5
- package/lib/esm/scenes/MethodScene/MethodScene.js.map +1 -1
- package/lib/esm/state/index.js +1 -0
- package/lib/esm/state/index.js.map +1 -1
- package/lib/esm/state/specs/index.js +3 -0
- package/lib/esm/state/specs/index.js.map +1 -0
- package/lib/esm/state/specs/sagas.js +58 -0
- package/lib/esm/state/specs/sagas.js.map +1 -0
- package/lib/esm/state/specs/selectors.js +8 -0
- package/lib/esm/state/specs/selectors.js.map +1 -0
- package/lib/esm/state/specs/slice.js +55 -0
- package/lib/esm/state/specs/slice.js.map +1 -0
- package/lib/esm/state/store.js +53 -2
- package/lib/esm/state/store.js.map +1 -1
- package/lib/esm/test-utils/redux.js +9 -5
- package/lib/esm/test-utils/redux.js.map +1 -1
- package/lib/esm/utils/adaptorUtils.js +101 -0
- package/lib/esm/utils/adaptorUtils.js.map +1 -0
- package/lib/esm/utils/apixAdaptor.js +48 -0
- package/lib/esm/utils/apixAdaptor.js.map +1 -0
- package/lib/esm/utils/index.js +3 -1
- package/lib/esm/utils/index.js.map +1 -1
- package/lib/esm/utils/path.js +27 -2
- package/lib/esm/utils/path.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +13 -0
- package/lib/index.js.map +1 -1
- package/lib/routes/AppRouter.d.ts +1 -5
- package/lib/routes/AppRouter.js +3 -7
- package/lib/routes/AppRouter.js.map +1 -1
- package/lib/scenes/DiffScene/DiffScene.js +45 -100
- package/lib/scenes/DiffScene/DiffScene.js.map +1 -1
- package/lib/scenes/DiffScene/DocDiff/DiffItem.js +9 -13
- package/lib/scenes/DiffScene/DocDiff/DiffItem.js.map +1 -1
- package/lib/scenes/DiffScene/DocDiff/DocDiff.js +2 -2
- package/lib/scenes/DiffScene/DocDiff/DocDiff.js.map +1 -1
- package/lib/scenes/MethodScene/MethodScene.d.ts +0 -4
- package/lib/scenes/MethodScene/MethodScene.js +5 -5
- package/lib/scenes/MethodScene/MethodScene.js.map +1 -1
- package/lib/state/index.d.ts +1 -0
- package/lib/state/index.js +13 -0
- package/lib/state/index.js.map +1 -1
- package/lib/state/settings/selectors.d.ts +1 -1
- package/lib/state/settings/slice.d.ts +1 -1
- package/lib/state/specs/index.d.ts +2 -0
- package/lib/state/specs/index.js +32 -0
- package/lib/state/specs/index.js.map +1 -0
- package/lib/state/specs/sagas.d.ts +1 -0
- package/lib/state/specs/sagas.js +67 -0
- package/lib/state/specs/sagas.js.map +1 -0
- package/lib/state/specs/selectors.d.ts +4 -0
- package/lib/state/specs/selectors.js +20 -0
- package/lib/state/specs/selectors.js.map +1 -0
- package/lib/state/specs/slice.d.ts +49 -0
- package/lib/state/specs/slice.js +70 -0
- package/lib/state/specs/slice.js.map +1 -0
- package/lib/state/store.d.ts +3 -0
- package/lib/state/store.js +56 -2
- package/lib/state/store.js.map +1 -1
- package/lib/test-data/declarations.d.ts +2 -0
- package/lib/test-data/examples.d.ts +2 -0
- package/lib/test-data/index.d.ts +3 -0
- package/lib/test-data/index.js +12 -42
- package/lib/test-data/index.js.map +1 -1
- package/lib/test-data/specs.d.ts +10 -0
- package/lib/test-data/specs.js +6 -6
- package/lib/test-data/specs.js.map +1 -1
- package/lib/test-utils/redux.d.ts +2 -1
- package/lib/test-utils/redux.js +9 -4
- package/lib/test-utils/redux.js.map +1 -1
- package/lib/utils/adaptorUtils.d.ts +30 -0
- package/lib/utils/adaptorUtils.js +124 -0
- package/lib/utils/adaptorUtils.js.map +1 -0
- package/lib/utils/apixAdaptor.d.ts +15 -0
- package/lib/utils/apixAdaptor.js +67 -0
- package/lib/utils/apixAdaptor.js.map +1 -0
- package/lib/utils/index.d.ts +3 -1
- package/lib/utils/index.js +45 -30
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/path.d.ts +3 -0
- package/lib/utils/path.js +32 -2
- package/lib/utils/path.js.map +1 -1
- package/package.json +10 -10
- package/src/ApiExplorer.tsx +47 -74
- package/src/StandaloneApiExplorer.tsx +37 -52
- package/src/components/Banner/Banner.spec.tsx +99 -0
- package/src/components/Banner/Banner.tsx +87 -0
- package/src/{reducers → components/Banner}/index.ts +1 -1
- package/src/components/DocSDKs/DocSDKs.tsx +4 -5
- package/src/components/ExploreType/ExploreType.spec.tsx +0 -23
- package/src/components/ExploreType/ExploreType.tsx +5 -6
- package/src/components/ExploreType/exploreUtils.spec.tsx +1 -1
- package/src/components/Header/Header.spec.tsx +9 -30
- package/src/components/Header/Header.tsx +3 -10
- package/src/components/SelectorContainer/ApiSpecSelector.spec.tsx +31 -44
- package/src/components/SelectorContainer/ApiSpecSelector.tsx +6 -12
- package/src/components/SelectorContainer/SelectorContainer.spec.tsx +7 -26
- package/src/components/SelectorContainer/SelectorContainer.tsx +4 -10
- package/src/components/SideNav/SideNav.spec.tsx +12 -45
- package/src/components/SideNav/SideNav.tsx +1 -7
- package/src/components/index.ts +1 -0
- package/src/index.ts +1 -0
- package/src/routes/AppRouter.tsx +25 -37
- package/src/scenes/DiffScene/DiffScene.tsx +47 -84
- package/src/scenes/DiffScene/DocDiff/DiffItem.spec.tsx +9 -16
- package/src/scenes/DiffScene/DocDiff/DiffItem.tsx +11 -12
- package/src/scenes/DiffScene/DocDiff/DocDiff.tsx +2 -2
- package/src/scenes/MethodScene/MethodScene.tsx +4 -10
- package/src/state/index.ts +1 -0
- package/src/{reducers/spec → state/specs}/index.ts +2 -3
- package/src/state/specs/sagas.spec.ts +135 -0
- package/src/state/specs/sagas.ts +81 -0
- package/src/{reducers/spec/actions.spec.ts → state/specs/selectors.ts} +12 -11
- package/src/state/specs/slice.ts +109 -0
- package/src/state/store.ts +58 -0
- package/src/test-data/index.ts +1 -8
- package/src/test-data/specs.ts +6 -6
- package/src/test-utils/redux.tsx +15 -4
- package/src/utils/adaptorUtils.ts +181 -0
- package/src/utils/apixAdaptor.ts +72 -0
- package/src/utils/index.ts +3 -7
- package/src/utils/path.ts +25 -2
- package/lib/esm/reducers/index.js +0 -2
- package/lib/esm/reducers/index.js.map +0 -1
- package/lib/esm/reducers/spec/actions.js +0 -19
- package/lib/esm/reducers/spec/actions.js.map +0 -1
- package/lib/esm/reducers/spec/index.js +0 -4
- package/lib/esm/reducers/spec/index.js.map +0 -1
- package/lib/esm/reducers/spec/reducer.js +0 -62
- package/lib/esm/reducers/spec/reducer.js.map +0 -1
- package/lib/esm/reducers/spec/utils.js +0 -74
- package/lib/esm/reducers/spec/utils.js.map +0 -1
- package/lib/reducers/index.d.ts +0 -1
- package/lib/reducers/index.js +0 -19
- package/lib/reducers/index.js.map +0 -1
- package/lib/reducers/spec/actions.d.ts +0 -20
- package/lib/reducers/spec/actions.js +0 -31
- package/lib/reducers/spec/actions.js.map +0 -1
- package/lib/reducers/spec/index.d.ts +0 -3
- package/lib/reducers/spec/index.js +0 -45
- package/lib/reducers/spec/index.js.map +0 -1
- package/lib/reducers/spec/reducer.d.ts +0 -7
- package/lib/reducers/spec/reducer.js +0 -73
- package/lib/reducers/spec/reducer.js.map +0 -1
- package/lib/reducers/spec/utils.d.ts +0 -7
- package/lib/reducers/spec/utils.js +0 -91
- package/lib/reducers/spec/utils.js.map +0 -1
- package/src/reducers/spec/actions.ts +0 -62
- package/src/reducers/spec/reducer.spec.ts +0 -44
- package/src/reducers/spec/reducer.ts +0 -69
- package/src/reducers/spec/utils.spec.ts +0 -138
- package/src/reducers/spec/utils.ts +0 -123
|
@@ -24,28 +24,23 @@
|
|
|
24
24
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import type { FC
|
|
27
|
+
import type { FC } from 'react'
|
|
28
28
|
import React from 'react'
|
|
29
29
|
import { Select } from '@looker/components'
|
|
30
30
|
import { useHistory, useLocation } from 'react-router-dom'
|
|
31
|
+
import type { SpecItem } from '@looker/sdk-codegen'
|
|
32
|
+
import { useSelector } from 'react-redux'
|
|
31
33
|
|
|
32
|
-
import
|
|
33
|
-
import type { SpecAction } from '../../reducers'
|
|
34
|
-
import { selectSpec } from '../../reducers'
|
|
34
|
+
import { selectSpecs } from '../../state'
|
|
35
35
|
|
|
36
36
|
interface ApiSpecSelectorProps {
|
|
37
|
-
specs: SpecList
|
|
38
37
|
spec: SpecItem
|
|
39
|
-
specDispatch: Dispatch<SpecAction>
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
export const ApiSpecSelector: FC<ApiSpecSelectorProps> = ({
|
|
43
|
-
specs,
|
|
44
|
-
spec,
|
|
45
|
-
specDispatch,
|
|
46
|
-
}) => {
|
|
40
|
+
export const ApiSpecSelector: FC<ApiSpecSelectorProps> = ({ spec }) => {
|
|
47
41
|
const history = useHistory()
|
|
48
42
|
const location = useLocation()
|
|
43
|
+
const specs = useSelector(selectSpecs)
|
|
49
44
|
const options = Object.entries(specs).map(([key, spec]) => ({
|
|
50
45
|
value: key,
|
|
51
46
|
label: key,
|
|
@@ -53,7 +48,6 @@ export const ApiSpecSelector: FC<ApiSpecSelectorProps> = ({
|
|
|
53
48
|
}))
|
|
54
49
|
|
|
55
50
|
const handleChange = (specKey: string) => {
|
|
56
|
-
specDispatch(selectSpec(specKey))
|
|
57
51
|
const matchPath = location.pathname.replace(`/${spec.key}`, `/${specKey}`)
|
|
58
52
|
history.push(matchPath)
|
|
59
53
|
}
|
|
@@ -28,28 +28,21 @@ import { act, screen, waitFor } from '@testing-library/react'
|
|
|
28
28
|
import { codeGenerators } from '@looker/sdk-codegen'
|
|
29
29
|
import userEvent from '@testing-library/user-event'
|
|
30
30
|
|
|
31
|
-
import {
|
|
31
|
+
import { getLoadedSpecs, specs } from '../../test-data'
|
|
32
32
|
import { renderWithRouterAndReduxProvider } from '../../test-utils'
|
|
33
33
|
import { defaultSettingsState } from '../../state'
|
|
34
34
|
import { SelectorContainer } from './SelectorContainer'
|
|
35
35
|
|
|
36
36
|
describe('SelectorContainer', () => {
|
|
37
|
-
const
|
|
38
|
-
|
|
37
|
+
const spec = getLoadedSpecs()['4.0']
|
|
39
38
|
beforeAll(() => {
|
|
40
39
|
window.HTMLElement.prototype.scrollIntoView = jest.fn()
|
|
41
40
|
})
|
|
42
41
|
|
|
43
42
|
test('it renders a spec selector with the correct default value and options', async () => {
|
|
44
|
-
renderWithRouterAndReduxProvider(
|
|
45
|
-
<SelectorContainer
|
|
46
|
-
specs={specs}
|
|
47
|
-
spec={specState.spec}
|
|
48
|
-
specDispatch={specDispatch}
|
|
49
|
-
/>
|
|
50
|
-
)
|
|
43
|
+
renderWithRouterAndReduxProvider(<SelectorContainer spec={spec} />)
|
|
51
44
|
const selector = screen.getByLabelText('spec selector')
|
|
52
|
-
expect(selector).toHaveValue(`${
|
|
45
|
+
expect(selector).toHaveValue(`${spec.key}`)
|
|
53
46
|
await act(async () => {
|
|
54
47
|
await userEvent.click(selector)
|
|
55
48
|
await waitFor(() => {
|
|
@@ -61,13 +54,7 @@ describe('SelectorContainer', () => {
|
|
|
61
54
|
})
|
|
62
55
|
|
|
63
56
|
test('it renders an sdk language selector with the correct value and options', async () => {
|
|
64
|
-
renderWithRouterAndReduxProvider(
|
|
65
|
-
<SelectorContainer
|
|
66
|
-
specs={specs}
|
|
67
|
-
spec={specState.spec}
|
|
68
|
-
specDispatch={specDispatch}
|
|
69
|
-
/>
|
|
70
|
-
)
|
|
57
|
+
renderWithRouterAndReduxProvider(<SelectorContainer spec={spec} />)
|
|
71
58
|
const selector = screen.getByLabelText('sdk language selector')
|
|
72
59
|
expect(selector).toHaveValue(defaultSettingsState.sdkLanguage)
|
|
73
60
|
await act(async () => {
|
|
@@ -81,19 +68,13 @@ describe('SelectorContainer', () => {
|
|
|
81
68
|
})
|
|
82
69
|
|
|
83
70
|
test('it renders an icon button for the differ', () => {
|
|
84
|
-
renderWithRouterAndReduxProvider(
|
|
85
|
-
<SelectorContainer
|
|
86
|
-
specs={specs}
|
|
87
|
-
spec={specState.spec}
|
|
88
|
-
specDispatch={specDispatch}
|
|
89
|
-
/>
|
|
90
|
-
)
|
|
71
|
+
renderWithRouterAndReduxProvider(<SelectorContainer spec={spec} />)
|
|
91
72
|
expect(
|
|
92
73
|
screen
|
|
93
74
|
.getByRole('button', {
|
|
94
75
|
name: 'Compare Specifications',
|
|
95
76
|
})
|
|
96
77
|
.closest('a')
|
|
97
|
-
).toHaveAttribute('href', `/diff/${
|
|
78
|
+
).toHaveAttribute('href', `/diff/${spec.key}/`)
|
|
98
79
|
})
|
|
99
80
|
})
|
|
@@ -24,25 +24,21 @@
|
|
|
24
24
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import type { FC
|
|
27
|
+
import type { FC } from 'react'
|
|
28
28
|
import React from 'react'
|
|
29
29
|
import type { SpaceHelperProps } from '@looker/components'
|
|
30
30
|
import { Space, IconButton } from '@looker/components'
|
|
31
31
|
import { ChangeHistory } from '@styled-icons/material/ChangeHistory'
|
|
32
|
-
import type {
|
|
32
|
+
import type { SpecItem } from '@looker/sdk-codegen'
|
|
33
|
+
|
|
33
34
|
import { Link } from '../Link'
|
|
34
|
-
import type { SpecAction } from '../../reducers'
|
|
35
35
|
import { diffPath } from '../../utils'
|
|
36
36
|
import { SdkLanguageSelector } from './SdkLanguageSelector'
|
|
37
37
|
import { ApiSpecSelector } from './ApiSpecSelector'
|
|
38
38
|
|
|
39
39
|
interface SelectorContainerProps extends SpaceHelperProps {
|
|
40
|
-
/** Specs to choose from */
|
|
41
|
-
specs: SpecList
|
|
42
40
|
/** Current selected spec */
|
|
43
41
|
spec: SpecItem
|
|
44
|
-
/** Spec state setter */
|
|
45
|
-
specDispatch: Dispatch<SpecAction>
|
|
46
42
|
}
|
|
47
43
|
|
|
48
44
|
export const HEADER_REM = 4
|
|
@@ -51,14 +47,12 @@ export const HEADER_REM = 4
|
|
|
51
47
|
* Renders a container for selectors
|
|
52
48
|
*/
|
|
53
49
|
export const SelectorContainer: FC<SelectorContainerProps> = ({
|
|
54
|
-
specs,
|
|
55
50
|
spec,
|
|
56
|
-
specDispatch,
|
|
57
51
|
...spaceProps
|
|
58
52
|
}) => (
|
|
59
53
|
<Space width="auto" {...spaceProps}>
|
|
60
54
|
<SdkLanguageSelector />
|
|
61
|
-
<ApiSpecSelector
|
|
55
|
+
<ApiSpecSelector spec={spec} />
|
|
62
56
|
<Link to={`/${diffPath}/${spec.key}/`}>
|
|
63
57
|
<IconButton
|
|
64
58
|
toggle
|
|
@@ -28,15 +28,15 @@ import { criteriaToSet } from '@looker/sdk-codegen'
|
|
|
28
28
|
import userEvent from '@testing-library/user-event'
|
|
29
29
|
import { screen, waitFor } from '@testing-library/react'
|
|
30
30
|
|
|
31
|
-
import { getLoadedSpecs
|
|
31
|
+
import { getLoadedSpecs } from '../../test-data'
|
|
32
32
|
import { renderWithRouterAndReduxProvider } from '../../test-utils'
|
|
33
33
|
import { defaultSettingsState } from '../../state'
|
|
34
34
|
import { SideNav } from './SideNav'
|
|
35
35
|
import { countMethods, countTypes } from './searchUtils'
|
|
36
36
|
|
|
37
|
+
const spec = getLoadedSpecs()['4.0']
|
|
38
|
+
|
|
37
39
|
describe('SideNav', () => {
|
|
38
|
-
const specs = getLoadedSpecs()
|
|
39
|
-
const specDispatch = jest.fn()
|
|
40
40
|
const allTagsPattern = /^(Auth|ApiAuth)$/
|
|
41
41
|
const allTypesPattern = /^(WriteDashboard|WriteQuery)$/
|
|
42
42
|
|
|
@@ -55,13 +55,7 @@ describe('SideNav', () => {
|
|
|
55
55
|
})
|
|
56
56
|
|
|
57
57
|
test('it renders search, methods tab and types tab', () => {
|
|
58
|
-
renderWithRouterAndReduxProvider(
|
|
59
|
-
<SideNav
|
|
60
|
-
specs={specs}
|
|
61
|
-
spec={specState.spec}
|
|
62
|
-
specDispatch={specDispatch}
|
|
63
|
-
/>
|
|
64
|
-
)
|
|
58
|
+
renderWithRouterAndReduxProvider(<SideNav spec={spec} />)
|
|
65
59
|
const search = screen.getByLabelText('Search')
|
|
66
60
|
expect(search).toHaveProperty('placeholder', 'Search')
|
|
67
61
|
const tabs = screen.getAllByRole('tab', {
|
|
@@ -69,23 +63,14 @@ describe('SideNav', () => {
|
|
|
69
63
|
})
|
|
70
64
|
expect(tabs).toHaveLength(2)
|
|
71
65
|
expect(tabs[0]).toHaveTextContent(
|
|
72
|
-
`Methods (${countMethods(
|
|
66
|
+
`Methods (${countMethods(spec.api!.tags)})`
|
|
73
67
|
)
|
|
74
68
|
|
|
75
|
-
expect(tabs[1]).toHaveTextContent(
|
|
76
|
-
`Types (${countTypes(specState.spec.api!.types)})`
|
|
77
|
-
)
|
|
69
|
+
expect(tabs[1]).toHaveTextContent(`Types (${countTypes(spec.api!.types)})`)
|
|
78
70
|
})
|
|
79
71
|
|
|
80
72
|
test('Methods tab is the default active tab', () => {
|
|
81
|
-
renderWithRouterAndReduxProvider(
|
|
82
|
-
<SideNav
|
|
83
|
-
specs={specs}
|
|
84
|
-
spec={specState.spec}
|
|
85
|
-
specDispatch={specDispatch}
|
|
86
|
-
/>,
|
|
87
|
-
['/3.1/methods']
|
|
88
|
-
)
|
|
73
|
+
renderWithRouterAndReduxProvider(<SideNav spec={spec} />, ['/3.1/methods'])
|
|
89
74
|
expect(screen.getAllByText(allTagsPattern)).toHaveLength(2)
|
|
90
75
|
expect(
|
|
91
76
|
screen.queryAllByRole('link', { name: allTypesPattern })
|
|
@@ -97,47 +82,29 @@ describe('SideNav', () => {
|
|
|
97
82
|
})
|
|
98
83
|
|
|
99
84
|
test('url determines active tab', () => {
|
|
100
|
-
renderWithRouterAndReduxProvider(
|
|
101
|
-
<SideNav
|
|
102
|
-
specs={specs}
|
|
103
|
-
spec={specState.spec}
|
|
104
|
-
specDispatch={specDispatch}
|
|
105
|
-
/>,
|
|
106
|
-
['/3.1/types']
|
|
107
|
-
)
|
|
85
|
+
renderWithRouterAndReduxProvider(<SideNav spec={spec} />, ['/3.1/types'])
|
|
108
86
|
// eslint-disable-next-line jest-dom/prefer-in-document
|
|
109
87
|
expect(screen.queryAllByText(allTagsPattern)).toHaveLength(2)
|
|
110
88
|
})
|
|
111
89
|
})
|
|
112
90
|
|
|
113
91
|
describe('Search', () => {
|
|
114
|
-
const specs = getLoadedSpecs()
|
|
115
|
-
const specDispatch = jest.fn()
|
|
116
|
-
|
|
117
92
|
test('it filters methods and types on input', async () => {
|
|
118
|
-
renderWithRouterAndReduxProvider(
|
|
119
|
-
<SideNav
|
|
120
|
-
specs={specs}
|
|
121
|
-
spec={specState.spec}
|
|
122
|
-
specDispatch={specDispatch}
|
|
123
|
-
/>
|
|
124
|
-
)
|
|
93
|
+
renderWithRouterAndReduxProvider(<SideNav spec={spec} />)
|
|
125
94
|
const searchPattern = 'embedsso'
|
|
126
95
|
const input = screen.getByLabelText('Search')
|
|
127
|
-
jest.spyOn(
|
|
96
|
+
jest.spyOn(spec.api!, 'search')
|
|
128
97
|
/** Pasting to avoid triggering search multiple times */
|
|
129
98
|
await userEvent.paste(input, searchPattern)
|
|
130
99
|
await waitFor(() => {
|
|
131
|
-
expect(
|
|
100
|
+
expect(spec.api!.search).toHaveBeenCalledWith(
|
|
132
101
|
searchPattern,
|
|
133
102
|
criteriaToSet(defaultSettingsState.searchCriteria)
|
|
134
103
|
)
|
|
135
104
|
const methods = screen.getByRole('tab', { name: 'Methods (1)' })
|
|
136
105
|
userEvent.click(methods)
|
|
137
106
|
expect(
|
|
138
|
-
screen.getByText(
|
|
139
|
-
specState.spec.api!.tags.Auth.create_sso_embed_url.summary
|
|
140
|
-
)
|
|
107
|
+
screen.getByText(spec.api!.tags.Auth.create_sso_embed_url.summary)
|
|
141
108
|
).toBeInTheDocument()
|
|
142
109
|
const types = screen.getByRole('tab', { name: 'Types (1)' })
|
|
143
110
|
userEvent.click(types)
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import type { FC
|
|
27
|
+
import type { FC } from 'react'
|
|
28
28
|
import React, { useEffect, useState } from 'react'
|
|
29
29
|
import { useHistory, useLocation } from 'react-router-dom'
|
|
30
30
|
import {
|
|
@@ -37,7 +37,6 @@ import {
|
|
|
37
37
|
} from '@looker/components'
|
|
38
38
|
import type {
|
|
39
39
|
SpecItem,
|
|
40
|
-
SpecList,
|
|
41
40
|
ISearchResult,
|
|
42
41
|
ApiModel,
|
|
43
42
|
TagList,
|
|
@@ -46,7 +45,6 @@ import type {
|
|
|
46
45
|
import { criteriaToSet, tagTypes } from '@looker/sdk-codegen'
|
|
47
46
|
import { useSelector } from 'react-redux'
|
|
48
47
|
|
|
49
|
-
import type { SpecAction } from '../../reducers'
|
|
50
48
|
import { useWindowSize } from '../../utils'
|
|
51
49
|
import { HEADER_REM } from '../Header'
|
|
52
50
|
import { selectSearchCriteria, useSettingActions } from '../../state'
|
|
@@ -65,12 +63,8 @@ interface SideNavState {
|
|
|
65
63
|
|
|
66
64
|
interface SideNavProps {
|
|
67
65
|
headless?: boolean
|
|
68
|
-
/** Specs to choose from */
|
|
69
|
-
specs: SpecList
|
|
70
66
|
/** Current selected spec */
|
|
71
67
|
spec: SpecItem
|
|
72
|
-
/** Spec state setter */
|
|
73
|
-
specDispatch: Dispatch<SpecAction>
|
|
74
68
|
}
|
|
75
69
|
|
|
76
70
|
export const SideNav: FC<SideNavProps> = ({ headless = false, spec }) => {
|
package/src/components/index.ts
CHANGED
package/src/index.ts
CHANGED
package/src/routes/AppRouter.tsx
CHANGED
|
@@ -28,8 +28,6 @@ import type { FC } from 'react'
|
|
|
28
28
|
import React from 'react'
|
|
29
29
|
import { Redirect, Route, Switch } from 'react-router-dom'
|
|
30
30
|
import type { ApiModel, SpecList } from '@looker/sdk-codegen'
|
|
31
|
-
import type { RunItSetter } from '@looker/run-it'
|
|
32
|
-
import type { IEnvironmentAdaptor } from '@looker/extension-utils'
|
|
33
31
|
|
|
34
32
|
import {
|
|
35
33
|
HomeScene,
|
|
@@ -42,47 +40,37 @@ import { DiffScene } from '../scenes/DiffScene'
|
|
|
42
40
|
import { diffPath } from '../utils'
|
|
43
41
|
|
|
44
42
|
interface AppRouterProps {
|
|
45
|
-
api: ApiModel
|
|
46
43
|
specKey: string
|
|
47
44
|
specs: SpecList
|
|
45
|
+
api: ApiModel
|
|
48
46
|
toggleNavigation: (target?: boolean) => void
|
|
49
|
-
adaptor: IEnvironmentAdaptor
|
|
50
|
-
setVersionsUrl: RunItSetter
|
|
51
47
|
}
|
|
52
48
|
|
|
53
49
|
export const AppRouter: FC<AppRouterProps> = ({
|
|
54
|
-
specKey,
|
|
55
50
|
api,
|
|
51
|
+
specKey,
|
|
56
52
|
specs,
|
|
57
53
|
toggleNavigation,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<TypeTagScene api={api} />
|
|
82
|
-
</Route>
|
|
83
|
-
<Route path="/:specKey/types/:typeTag/:typeName">
|
|
84
|
-
<TypeScene api={api} />
|
|
85
|
-
</Route>
|
|
86
|
-
</Switch>
|
|
87
|
-
)
|
|
88
|
-
}
|
|
54
|
+
}) => (
|
|
55
|
+
<Switch>
|
|
56
|
+
<Redirect from="/" to={`/${specKey}/`} exact />
|
|
57
|
+
<Route path={`/${diffPath}/:l?/:r?`}>
|
|
58
|
+
<DiffScene specs={specs} toggleNavigation={toggleNavigation} />
|
|
59
|
+
</Route>
|
|
60
|
+
<Route path="/:specKey/(methods|types)?" exact>
|
|
61
|
+
<HomeScene api={api} />
|
|
62
|
+
</Route>
|
|
63
|
+
<Route path="/:specKey/methods/:methodTag" exact>
|
|
64
|
+
<MethodTagScene api={api} />
|
|
65
|
+
</Route>
|
|
66
|
+
<Route path="/:specKey/methods/:methodTag/:methodName">
|
|
67
|
+
<MethodScene api={api} />
|
|
68
|
+
</Route>
|
|
69
|
+
<Route path="/:specKey/types/:typeTag" exact>
|
|
70
|
+
<TypeTagScene api={api} />
|
|
71
|
+
</Route>
|
|
72
|
+
<Route path="/:specKey/types/:typeTag/:typeName">
|
|
73
|
+
<TypeScene api={api} />
|
|
74
|
+
</Route>
|
|
75
|
+
</Switch>
|
|
76
|
+
)
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
import type { FC } from 'react'
|
|
28
28
|
import React, { useState, useEffect } from 'react'
|
|
29
|
-
import type { ApiModel, DiffRow, SpecList
|
|
29
|
+
import type { ApiModel, DiffRow, SpecList } from '@looker/sdk-codegen'
|
|
30
30
|
import { useHistory, useRouteMatch } from 'react-router-dom'
|
|
31
31
|
import {
|
|
32
32
|
Box,
|
|
@@ -38,35 +38,14 @@ import {
|
|
|
38
38
|
SelectMulti,
|
|
39
39
|
} from '@looker/components'
|
|
40
40
|
import { SyncAlt } from '@styled-icons/material/SyncAlt'
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
import { diffPath } from '../../utils'
|
|
41
|
+
import { useSelector } from 'react-redux'
|
|
42
|
+
|
|
44
43
|
import { ApixSection } from '../../components'
|
|
44
|
+
import { selectCurrentSpec } from '../../state'
|
|
45
|
+
import { diffPath, getApixAdaptor } from '../../utils'
|
|
45
46
|
import { diffSpecs, standardDiffToggles } from './diffUtils'
|
|
46
47
|
import { DocDiff } from './DocDiff'
|
|
47
48
|
|
|
48
|
-
/**
|
|
49
|
-
* Pick the left key, or default spec
|
|
50
|
-
* @param specs to pick from
|
|
51
|
-
* @param leftKey spec key that may or may not have a value
|
|
52
|
-
*/
|
|
53
|
-
const pickLeft = (specs: SpecList, leftKey: string) => {
|
|
54
|
-
if (leftKey) return leftKey
|
|
55
|
-
return getDefaultSpecKey(specs)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Pick the right key, or "other" spec
|
|
60
|
-
* @param specs to pick from
|
|
61
|
-
* @param rightKey spec key from url path
|
|
62
|
-
* @param leftKey spec key from url path
|
|
63
|
-
*/
|
|
64
|
-
const pickRight = (specs: SpecList, rightKey: string, leftKey: string) => {
|
|
65
|
-
if (rightKey) return rightKey
|
|
66
|
-
if (!leftKey) leftKey = getDefaultSpecKey(specs)
|
|
67
|
-
return Object.keys(specs).find((k) => k !== leftKey) || ''
|
|
68
|
-
}
|
|
69
|
-
|
|
70
49
|
const diffToggles = [
|
|
71
50
|
{
|
|
72
51
|
label: 'Missing',
|
|
@@ -104,7 +83,10 @@ const validateParam = (specs: SpecList, specKey = '') => {
|
|
|
104
83
|
}
|
|
105
84
|
|
|
106
85
|
export const DiffScene: FC<DiffSceneProps> = ({ specs, toggleNavigation }) => {
|
|
86
|
+
const adaptor = getApixAdaptor()
|
|
107
87
|
const history = useHistory()
|
|
88
|
+
const spec = useSelector(selectCurrentSpec)
|
|
89
|
+
const currentSpecKey = spec.key
|
|
108
90
|
const match = useRouteMatch<{ l: string; r: string }>(`/${diffPath}/:l?/:r?`)
|
|
109
91
|
const l = validateParam(specs, match?.params.l)
|
|
110
92
|
const r = validateParam(specs, match?.params.r)
|
|
@@ -114,83 +96,62 @@ export const DiffScene: FC<DiffSceneProps> = ({ specs, toggleNavigation }) => {
|
|
|
114
96
|
label: `${key} (${spec.status})`,
|
|
115
97
|
}))
|
|
116
98
|
|
|
117
|
-
const [leftKey, setLeftKey] = useState<string>(
|
|
118
|
-
const [rightKey, setRightKey] = useState<string>(
|
|
99
|
+
const [leftKey, setLeftKey] = useState<string>(l || currentSpecKey)
|
|
100
|
+
const [rightKey, setRightKey] = useState<string>(r || '')
|
|
119
101
|
const [leftApi, setLeftApi] = useState<ApiModel>(specs[leftKey].api!)
|
|
120
|
-
const [rightApi, setRightApi] = useState<ApiModel>(
|
|
102
|
+
const [rightApi, setRightApi] = useState<ApiModel>(() =>
|
|
121
103
|
rightKey ? specs[rightKey].api! : specs[leftKey].api!
|
|
122
104
|
)
|
|
123
105
|
const [toggles, setToggles] = useState<string[]>(standardDiffToggles)
|
|
124
106
|
|
|
125
107
|
useEffect(() => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const computeDelta = (left: string, right: string, toggles: string[]) => {
|
|
130
|
-
if (left && right && specs[left].api && specs[right].api) {
|
|
131
|
-
return diffSpecs(specs[left].api!, specs[right].api!, toggles)
|
|
108
|
+
if (r !== rightKey) {
|
|
109
|
+
setRightKey(r)
|
|
132
110
|
}
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
const [delta, setDelta] = useState<DiffRow[]>(
|
|
136
|
-
computeDelta(leftKey, rightKey, toggles)
|
|
137
|
-
)
|
|
111
|
+
}, [r, rightKey])
|
|
138
112
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
setter: (spec: SpecItem) => void
|
|
143
|
-
) => {
|
|
144
|
-
const spec = specs[key]
|
|
145
|
-
if (!spec.api) {
|
|
146
|
-
try {
|
|
147
|
-
const newSpec = { ...spec }
|
|
148
|
-
const api = await fallbackFetch(newSpec, funFetch)
|
|
149
|
-
if (api) {
|
|
150
|
-
spec.api = api
|
|
151
|
-
setter(spec)
|
|
152
|
-
}
|
|
153
|
-
} catch (error) {
|
|
154
|
-
console.error(error)
|
|
155
|
-
}
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (l !== leftKey) {
|
|
115
|
+
setLeftKey(l)
|
|
156
116
|
}
|
|
157
|
-
}
|
|
117
|
+
}, [l, leftKey])
|
|
158
118
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
await loadSpec(specs, leftKey, (spec) => setLeftApi(spec.api!))
|
|
165
|
-
}
|
|
166
|
-
if (!specs[right].api) {
|
|
167
|
-
await loadSpec(specs, rightKey, (spec) => setRightApi(spec.api!))
|
|
168
|
-
}
|
|
169
|
-
setDelta([...computeDelta(left, right, toggles)])
|
|
170
|
-
}
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
toggleNavigation(false)
|
|
121
|
+
}, [])
|
|
122
|
+
|
|
123
|
+
const [delta, setDelta] = useState<DiffRow[]>([])
|
|
171
124
|
|
|
172
125
|
const handleLeftChange = (newLeft: string) => {
|
|
173
|
-
|
|
126
|
+
history.push(`/${diffPath}/${newLeft}/${rightKey}`)
|
|
127
|
+
}
|
|
128
|
+
const handleRightChange = (newRight: string) => {
|
|
129
|
+
history.push(`/${diffPath}/${leftKey}/${newRight}`)
|
|
174
130
|
}
|
|
175
131
|
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
setToggles(newToggles)
|
|
179
|
-
setDelta([...computeDelta(leftKey, rightKey, newToggles)])
|
|
132
|
+
const handleSwitch = () => {
|
|
133
|
+
history.push(`/${diffPath}/${rightKey}/${leftKey}`)
|
|
180
134
|
}
|
|
181
135
|
|
|
182
136
|
useEffect(() => {
|
|
183
|
-
|
|
184
|
-
}, [leftKey
|
|
137
|
+
adaptor.fetchSpec(specs[leftKey]).then((spec) => setLeftApi(spec.api!))
|
|
138
|
+
}, [leftKey])
|
|
185
139
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
if (rightKey in specs) {
|
|
142
|
+
adaptor.fetchSpec(specs[rightKey]).then((spec) => setRightApi(spec.api!))
|
|
143
|
+
}
|
|
144
|
+
}, [rightKey])
|
|
189
145
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (leftApi && rightApi) {
|
|
148
|
+
setDelta([...diffSpecs(leftApi, rightApi, toggles)])
|
|
149
|
+
}
|
|
150
|
+
}, [leftApi, rightApi, toggles])
|
|
151
|
+
|
|
152
|
+
const handleTogglesChange = (values?: string[]) => {
|
|
153
|
+
const newToggles = values || []
|
|
154
|
+
setToggles(newToggles)
|
|
194
155
|
}
|
|
195
156
|
|
|
196
157
|
return (
|
|
@@ -211,6 +172,7 @@ export const DiffScene: FC<DiffSceneProps> = ({ specs, toggleNavigation }) => {
|
|
|
211
172
|
<IconButton
|
|
212
173
|
label="switch"
|
|
213
174
|
size="small"
|
|
175
|
+
disabled={!leftKey || !rightKey}
|
|
214
176
|
icon={<SyncAlt />}
|
|
215
177
|
mt="medium"
|
|
216
178
|
onClick={handleSwitch}
|
|
@@ -221,6 +183,7 @@ export const DiffScene: FC<DiffSceneProps> = ({ specs, toggleNavigation }) => {
|
|
|
221
183
|
mt="xxsmall"
|
|
222
184
|
id="compare"
|
|
223
185
|
name="Right Version"
|
|
186
|
+
placeholder="Select a comparison..."
|
|
224
187
|
value={rightKey}
|
|
225
188
|
options={options}
|
|
226
189
|
onChange={handleRightChange}
|
|
@@ -28,8 +28,7 @@ import { Router } from 'react-router'
|
|
|
28
28
|
import type { MemoryHistory } from 'history'
|
|
29
29
|
import { createMemoryHistory } from 'history'
|
|
30
30
|
import { renderWithTheme } from '@looker/components-test-utils'
|
|
31
|
-
import
|
|
32
|
-
import { act, screen } from '@testing-library/react'
|
|
31
|
+
import { screen, fireEvent } from '@testing-library/react'
|
|
33
32
|
import { api } from '../../../test-data'
|
|
34
33
|
import { DiffMethodLink } from './DiffItem'
|
|
35
34
|
|
|
@@ -37,27 +36,24 @@ describe('DiffMethodLink', () => {
|
|
|
37
36
|
const method = api.methods.create_dashboard
|
|
38
37
|
const specKey = '4.0'
|
|
39
38
|
let history: MemoryHistory
|
|
40
|
-
let pushSpy: jasmine.Spy
|
|
41
39
|
|
|
42
40
|
beforeEach(() => {
|
|
43
41
|
history = createMemoryHistory()
|
|
44
|
-
pushSpy = spyOn(history, 'push')
|
|
45
42
|
})
|
|
46
43
|
|
|
47
44
|
test('it renders method and navigates on click', () => {
|
|
45
|
+
const pushSpy = jest.spyOn(history, 'push')
|
|
48
46
|
renderWithTheme(
|
|
49
47
|
<Router history={history}>
|
|
50
48
|
<DiffMethodLink method={method} specKey={specKey} />
|
|
51
49
|
</Router>
|
|
52
50
|
)
|
|
53
|
-
const
|
|
54
|
-
expect(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
60
|
-
})
|
|
51
|
+
const link = screen.getByRole('link')
|
|
52
|
+
expect(link).toHaveTextContent(`${method.name} for ${specKey}`)
|
|
53
|
+
fireEvent.click(link)
|
|
54
|
+
expect(pushSpy).toHaveBeenCalledWith(
|
|
55
|
+
`/${specKey}/methods/${method.schema.tags[0]}/${method.name}`
|
|
56
|
+
)
|
|
61
57
|
})
|
|
62
58
|
|
|
63
59
|
test('it renders missing method and does not navigate on click', () => {
|
|
@@ -68,9 +64,6 @@ describe('DiffMethodLink', () => {
|
|
|
68
64
|
)
|
|
69
65
|
const s = `Missing in ${specKey}`
|
|
70
66
|
expect(screen.getByText(s)).toBeInTheDocument()
|
|
71
|
-
|
|
72
|
-
act(() => {
|
|
73
|
-
expect(pushSpy).not.toHaveBeenCalled()
|
|
74
|
-
})
|
|
67
|
+
expect(screen.queryByRole('link')).not.toBeInTheDocument()
|
|
75
68
|
})
|
|
76
69
|
})
|