-
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
work-in-progress fulltext part of plugin, jsonnet building/vendoring …
…updated
- Loading branch information
Showing
116 changed files
with
7,698 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
module.exports = { | ||
...require("./node_modules/@grafana/toolkit/src/config/prettier.plugin.config.json"), | ||
...require('./node_modules/@grafana/toolkit/src/config/prettier.plugin.config.json'), | ||
// If this is not here, prettier takes default 'always', which doesnt seem to be the rule that grafana-toolkit is linting by | ||
arrowParens: 'avoid', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,20 +2,24 @@ | |
# build grafana-pcp | ||
# | ||
YARN = yarn | ||
JSONNET_PATH = ../grafonnet-lib | ||
DASHBOARD_DIR := src/dashboards | ||
DASHBOARDS := $(addprefix $(DASHBOARD_DIR)/,pcp-vector-host-overview.json pcp-vector-bcc-overview.json) | ||
JSONNET_DEPS := src/dashboard/jsonnetfile.json | ||
DASHBOARDS := $(addprefix $(DASHBOARD_DIR)/,pcp-vector-host-overview.json pcp-vector-bcc-overview.json fulltext-graph-preview.json fulltext-table-preview.json) | ||
|
||
default: build | ||
|
||
node_modules: package.json | ||
$(YARN) install | ||
sed -i '[email protected](createIgnoreResult(filePath, cwd));@// &@' node_modules/eslint/lib/cli-engine/cli-engine.js | ||
|
||
$(JSONNET_DEPS): | ||
cd $(DASHBOARD_DIR) && jb install | ||
|
||
$(DASHBOARD_DIR)/%.json: $(DASHBOARD_DIR)/%.jsonnet | ||
jsonnet -J $(JSONNET_PATH) -o $@ $< | ||
cd src/dashboards && jb install | ||
jsonnet -o $@ $< | ||
|
||
dist: node_modules $(DASHBOARDS) | ||
dist: node_modules $(JSONNET_DEPS) $(DASHBOARDS) | ||
$(YARN) run build | ||
|
||
build: dist | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import Enzyme from 'enzyme'; | ||
import EnzymeAdapter from 'enzyme-adapter-react-16'; | ||
|
||
// Setup enzyme's react adapter | ||
Enzyme.configure({ adapter: new EnzymeAdapter() }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { shallow } from 'enzyme'; | ||
import React from 'react'; | ||
import { App, AppProps } from './App'; | ||
import { ViewState } from './store/slices/search/slices/view/state'; | ||
|
||
describe('<App/>', () => { | ||
let appProps: AppProps; | ||
|
||
beforeEach(() => { | ||
appProps = { view: ViewState.Index }; | ||
}); | ||
|
||
test('renders without crashing', () => { | ||
shallow(<App {...appProps} />); | ||
}); | ||
|
||
test('can render detail page', () => { | ||
const wrapper = shallow(<App {...{ ...appProps, view: ViewState.Detail }} />); | ||
expect(wrapper.exists('[data-test="detail-page"]')).toBe(true); | ||
}); | ||
|
||
test('can render search page', () => { | ||
const wrapper = shallow(<App {...{ ...appProps, view: ViewState.Search }} />); | ||
expect(wrapper.exists('[data-test="search-page"]')).toBe(true); | ||
}); | ||
|
||
test('can render index page', () => { | ||
const wrapper = shallow(<App {...{ ...appProps, view: ViewState.Index }} />); | ||
expect(wrapper.exists('[data-test="index-page"]')).toBe(true); | ||
}); | ||
|
||
test('renders search form', () => { | ||
const wrapper = shallow(<App {...appProps} />); | ||
expect(wrapper.exists('[data-test="search-form"]')).toBe(true); | ||
}); | ||
|
||
test('renders actions', () => { | ||
const wrapper = shallow(<App {...appProps} />); | ||
expect(wrapper.exists('[data-test="actions"]')).toBe(true); | ||
}); | ||
|
||
test('renders aside', () => { | ||
const wrapper = shallow(<App {...appProps} />); | ||
expect(wrapper.exists('[data-test="aside"]')).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React from 'react'; | ||
import { RootState } from './store/reducer'; | ||
import { ViewState } from './store/slices/search/slices/view/state'; | ||
import DetailPage from './pages/Detail/DetailPage'; | ||
import SearchPage from './pages/Search/SearchPage'; | ||
import IndexPage from './pages/Index/IndexPage'; | ||
import { appLayout } from './styles'; | ||
import SearchForm from './partials/SearchForm/SearchForm'; | ||
import Actions from './partials/Actions/Actions'; | ||
import Aside from './partials/Aside/Aside'; | ||
import { connect } from 'react-redux'; | ||
|
||
const mapStateToProps = (state: RootState) => ({ | ||
view: state.search.view, | ||
}); | ||
|
||
export type AppReduxStateProps = ReturnType<typeof mapStateToProps>; | ||
|
||
export type AppProps = AppReduxStateProps; | ||
|
||
export class App extends React.Component<AppProps, {}> { | ||
constructor(props: AppProps) { | ||
super(props); | ||
} | ||
|
||
renderPageComponent() { | ||
const { view } = this.props; | ||
|
||
switch (view) { | ||
case ViewState.Detail: | ||
return <DetailPage data-test="detail-page" />; | ||
case ViewState.Search: | ||
return <SearchPage data-test="search-page" />; | ||
case ViewState.Index: | ||
return <IndexPage data-test="index-page" />; | ||
default: | ||
return; | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<div className={appLayout}> | ||
<SearchForm data-test="search-form" /> | ||
<Actions data-test="actions" /> | ||
<Aside data-test="aside" /> | ||
{this.renderPageComponent()} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default connect(mapStateToProps, {})(App); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import React from 'react'; | ||
import { AppRootProps } from '@grafana/data'; | ||
import { Provider } from 'react-redux'; | ||
import App from './App'; | ||
import { PersistGate } from 'redux-persist/integration/react'; | ||
import { Persistor } from 'redux-persist'; | ||
import Loader from './components/Loader/Loader'; | ||
import { initStore } from './store/store'; | ||
import { Store, AnyAction } from 'redux'; | ||
import { initServices, Services } from './services/services'; | ||
import ServicesContext from './contexts/services'; | ||
|
||
interface AppRootState { | ||
store: Store<any, AnyAction> | null; | ||
services: Services | null; | ||
persistor: Persistor | null; | ||
loading: boolean; | ||
errorMsg: string; | ||
} | ||
|
||
export class Search extends React.Component<AppRootProps, AppRootState> { | ||
state: AppRootState = { | ||
store: null, | ||
services: null, | ||
persistor: null, | ||
loading: true, | ||
errorMsg: '', | ||
}; | ||
|
||
constructor(props: AppRootProps) { | ||
super(props); | ||
} | ||
|
||
componentDidMount() { | ||
// Bloat for Grafana App plugin tabs, which we don't actually use in app itself, hence this wrapper | ||
this.updateNav(); | ||
initServices() | ||
.then(services => { | ||
this.setState({ services }); | ||
return initStore(services); | ||
}) | ||
.then(({ store, persistor }) => { | ||
this.setState({ store, persistor, loading: false }); | ||
}) | ||
.catch((err: Error) => { | ||
this.setState({ loading: false, errorMsg: err.message }); | ||
}); | ||
} | ||
|
||
componentDidUpdate(prevProps: AppRootProps) { | ||
if (this.props.query !== prevProps.query) { | ||
if (this.props.query.tab !== prevProps.query.tab) { | ||
this.updateNav(); | ||
} | ||
} | ||
} | ||
|
||
updateNav() { | ||
const { path, onNavChanged, meta } = this.props; | ||
const node = { | ||
text: 'Performance Co-Pilot', | ||
img: meta.info.logos.large, | ||
subTitle: 'Full-Text Search', | ||
url: path, | ||
}; | ||
onNavChanged({ | ||
node, | ||
main: node, | ||
}); | ||
} | ||
|
||
// Render main App component without above bloat | ||
render() { | ||
const { store, loading, persistor, errorMsg, services } = this.state; | ||
if (loading) { | ||
return <Loader loaded={false} />; | ||
} | ||
if (store === null || services === null) { | ||
return <p>{errorMsg}</p>; | ||
} | ||
return ( | ||
<Provider store={store}> | ||
{/* Seems like redux-persist has really buggy typings | ||
// @ts-ignore */} | ||
<PersistGate persistor={persistor}> | ||
{loaded => ( | ||
<Loader loaded={loaded}> | ||
<ServicesContext.Provider value={services}> | ||
<App /> | ||
</ServicesContext.Provider> | ||
</Loader> | ||
)} | ||
</PersistGate> | ||
</Provider> | ||
); | ||
} | ||
} | ||
|
||
export default Search; |
104 changes: 104 additions & 0 deletions
104
src/components/search/components/BookmarkList/BookmarkList.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
import { BookmarkList } from './BookmarkList'; | ||
import { GrafanaThemeType } from '@grafana/data'; | ||
import { getTheme } from '@grafana/ui'; | ||
import { BookmarkItem } from '../../store/slices/search/slices/bookmarks/state'; | ||
import { EntityType } from '../../models/endpoints/search'; | ||
|
||
describe('<BookmarkList/>', () => { | ||
const placeholderCallbacks = { | ||
onBookmarkClick: () => void 0, | ||
onClearBookmarksClick: () => void 0, | ||
}; | ||
const theme = getTheme(GrafanaThemeType.Light); | ||
|
||
const bookmarkItems: BookmarkItem[] = [ | ||
{ | ||
id: 'statsd.settings.dropped', | ||
type: EntityType.Metric, | ||
}, | ||
{ | ||
id: '60.2', | ||
type: EntityType.InstanceDomain, | ||
}, | ||
]; | ||
|
||
test('renders without crashing', () => { | ||
shallow(<BookmarkList bookmarks={[]} {...placeholderCallbacks} theme={theme} />); | ||
}); | ||
|
||
test('renders multiple columns by default', () => { | ||
const component = shallow(<BookmarkList bookmarks={bookmarkItems} {...placeholderCallbacks} theme={theme} />); | ||
expect(component.exists('[data-test="multicol"]')).toBe(true); | ||
}); | ||
|
||
test('renders clear button by default', () => { | ||
const component = shallow(<BookmarkList bookmarks={bookmarkItems} {...placeholderCallbacks} theme={theme} />); | ||
expect(component.exists('[data-test="bookmark-reset"]')).toBe(true); | ||
}); | ||
|
||
test('accepts both single column and multi column prop settings', () => { | ||
const singleCol = shallow( | ||
<BookmarkList bookmarks={bookmarkItems} multiCol={false} {...placeholderCallbacks} theme={theme} /> | ||
); | ||
expect(singleCol.exists('[data-test="singlecol"]')).toBe(true); | ||
|
||
const multiCol = shallow( | ||
<BookmarkList bookmarks={bookmarkItems} multiCol={true} {...placeholderCallbacks} theme={theme} /> | ||
); | ||
expect(multiCol.exists('[data-test="multicol"]')).toBe(true); | ||
}); | ||
|
||
test('accepts conditional showing of clear button', () => { | ||
const hasClear = shallow( | ||
<BookmarkList bookmarks={bookmarkItems} showClearBtn={true} {...placeholderCallbacks} theme={theme} /> | ||
); | ||
expect(hasClear.exists('[data-test="bookmark-reset"]')).toBe(true); | ||
|
||
const lacksClear = shallow( | ||
<BookmarkList bookmarks={bookmarkItems} showClearBtn={false} {...placeholderCallbacks} theme={theme} /> | ||
); | ||
expect(lacksClear.exists('[data-test="bookmark-reset"]')).toBe(false); | ||
}); | ||
|
||
test('calls onBookmarkClick properly', () => { | ||
const onBookmarkClickMock = jest.fn(() => void 0); | ||
const component = shallow( | ||
<BookmarkList | ||
bookmarks={bookmarkItems} | ||
{...placeholderCallbacks} | ||
onBookmarkClick={onBookmarkClickMock} | ||
theme={theme} | ||
/> | ||
); | ||
const buttons = component.find('[data-test="bookmark-go"]'); | ||
buttons.forEach(button => button.simulate('click')); | ||
expect(onBookmarkClickMock).toHaveBeenCalledTimes(bookmarkItems.length); | ||
}); | ||
|
||
test('calls onClearBookmarksClick properly', () => { | ||
const onClearBookmarksClickMock = jest.fn(() => void 0); | ||
const component = shallow( | ||
<BookmarkList | ||
bookmarks={bookmarkItems} | ||
{...placeholderCallbacks} | ||
onClearBookmarksClick={onClearBookmarksClickMock} | ||
theme={theme} | ||
/> | ||
); | ||
const button = component.find('[data-test="bookmark-reset"]'); | ||
button.simulate('click'); | ||
expect(onClearBookmarksClickMock).toHaveBeenCalled(); | ||
}); | ||
|
||
test('renders passed all bookmarks items', () => { | ||
const component = shallow(<BookmarkList bookmarks={bookmarkItems} {...placeholderCallbacks} theme={theme} />); | ||
expect(component.find('[data-test="bookmark-go"]').length).toBe(bookmarkItems.length); | ||
}); | ||
|
||
test('handles no bookmarks items', () => { | ||
const component = shallow(<BookmarkList bookmarks={[]} {...placeholderCallbacks} theme={theme} />); | ||
expect(component.exists('[data-test="bookmark-go"]')).toBe(false); | ||
}); | ||
}); |
Oops, something went wrong.