@@ -20,7 +20,7 @@ | |||
import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | |||
import throwGlobalError from '../app/utils/throwGlobalError'; | |||
import { BranchParameters } from '../types/branch-like'; | |||
import { ComponentQualifier } from '../types/component'; | |||
import { ComponentQualifier, TreeComponent, TreeComponentWithPath } from '../types/component'; | |||
export interface BaseSearchProjectsParameters { | |||
analyzedBefore?: string; | |||
@@ -132,20 +132,6 @@ export function getComponent( | |||
return getJSON('/api/measures/component', data); | |||
} | |||
export interface TreeComponent extends T.LightComponent { | |||
id?: string; | |||
name: string; | |||
path?: string; | |||
refId?: string; | |||
refKey?: string; | |||
tags?: string[]; | |||
visibility: T.Visibility; | |||
} | |||
export interface TreeComponentWithPath extends TreeComponent { | |||
path: string; | |||
} | |||
type GetTreeParams = { | |||
asc?: boolean; | |||
component: string; |
@@ -928,7 +928,7 @@ export default class App extends React.PureComponent<Props, State> { | |||
} | |||
renderFacets() { | |||
const { component, currentUser, userOrganizations } = this.props; | |||
const { component, currentUser, userOrganizations, branchLike } = this.props; | |||
const { query } = this.state; | |||
const organizationKey = | |||
@@ -953,6 +953,7 @@ export default class App extends React.PureComponent<Props, State> { | |||
)} | |||
<FiltersHeader displayReset={this.isFiltered()} onReset={this.handleReset} /> | |||
<Sidebar | |||
branchLike={branchLike} | |||
component={component} | |||
facets={this.state.facets} | |||
hideAuthorFacet={hideAuthorFacet} |
@@ -23,11 +23,15 @@ import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { collapsePath } from 'sonar-ui-common/helpers/path'; | |||
import { highlightTerm } from 'sonar-ui-common/helpers/search'; | |||
import { getDirectories, TreeComponentWithPath } from '../../../api/components'; | |||
import { getDirectories } from '../../../api/components'; | |||
import ListStyleFacet from '../../../components/facet/ListStyleFacet'; | |||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||
import { BranchLike } from '../../../types/branch-like'; | |||
import { TreeComponentWithPath } from '../../../types/component'; | |||
import { Facet, Query } from '../utils'; | |||
interface Props { | |||
branchLike?: BranchLike; | |||
componentKey: string; | |||
directories: string[]; | |||
fetching: boolean; | |||
@@ -53,8 +57,11 @@ export default class DirectoryFacet extends React.PureComponent<Props> { | |||
}; | |||
handleSearch = (query: string, page: number) => { | |||
const { branchLike } = this.props; | |||
return getDirectories({ | |||
component: this.props.componentKey, | |||
...getBranchLikeQuery(branchLike), | |||
q: query, | |||
p: page, | |||
ps: 30 |
@@ -24,11 +24,15 @@ import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { collapsePath } from 'sonar-ui-common/helpers/path'; | |||
import { highlightTerm } from 'sonar-ui-common/helpers/search'; | |||
import { isDefined } from 'sonar-ui-common/helpers/types'; | |||
import { getFiles, TreeComponentWithPath } from '../../../api/components'; | |||
import { getFiles } from '../../../api/components'; | |||
import ListStyleFacet from '../../../components/facet/ListStyleFacet'; | |||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||
import { BranchLike } from '../../../types/branch-like'; | |||
import { TreeComponentWithPath } from '../../../types/component'; | |||
import { Facet, Query, ReferencedComponent } from '../utils'; | |||
interface Props { | |||
branchLike?: BranchLike; | |||
componentKey: string; | |||
fetching: boolean; | |||
fileUuids: string[]; | |||
@@ -72,8 +76,11 @@ export default class FileFacet extends React.PureComponent<Props> { | |||
}; | |||
handleSearch = (query: string, page: number) => { | |||
const { branchLike } = this.props; | |||
return getFiles({ | |||
component: this.props.componentKey, | |||
...getBranchLikeQuery(branchLike), | |||
q: query, | |||
p: page, | |||
ps: 30 |
@@ -20,6 +20,8 @@ | |||
import * as React from 'react'; | |||
import { connect } from 'react-redux'; | |||
import { getGlobalSettingValue, Store } from '../../../store/rootReducer'; | |||
import { BranchLike } from '../../../types/branch-like'; | |||
import { ComponentQualifier } from '../../../types/component'; | |||
import { Facet, Query, ReferencedComponent, ReferencedLanguage, ReferencedRule } from '../utils'; | |||
import AssigneeFacet from './AssigneeFacet'; | |||
import AuthorFacet from './AuthorFacet'; | |||
@@ -37,6 +39,7 @@ import TagFacet from './TagFacet'; | |||
import TypeFacet from './TypeFacet'; | |||
export interface Props { | |||
branchLike?: BranchLike; | |||
component: T.Component | undefined; | |||
facets: T.Dict<Facet | undefined>; | |||
hideAuthorFacet?: boolean; | |||
@@ -58,7 +61,7 @@ export interface Props { | |||
export class Sidebar extends React.PureComponent<Props> { | |||
renderComponentFacets() { | |||
const { component, facets, loadingFacets, openFacets, query } = this.props; | |||
const { component, facets, loadingFacets, openFacets, query, branchLike } = this.props; | |||
if (!component) { | |||
return null; | |||
} | |||
@@ -71,8 +74,9 @@ export class Sidebar extends React.PureComponent<Props> { | |||
}; | |||
return ( | |||
<> | |||
{component.qualifier !== 'DIR' && ( | |||
{component.qualifier !== ComponentQualifier.Directory && ( | |||
<DirectoryFacet | |||
branchLike={branchLike} | |||
directories={query.directories} | |||
fetching={loadingFacets.directories === true} | |||
open={!!openFacets.directories} | |||
@@ -81,6 +85,7 @@ export class Sidebar extends React.PureComponent<Props> { | |||
/> | |||
)} | |||
<FileFacet | |||
branchLike={branchLike} | |||
fetching={loadingFacets.files === true} | |||
fileUuids={query.files} | |||
open={!!openFacets.files} |
@@ -19,10 +19,23 @@ | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { TreeComponentWithPath } from '../../../../api/components'; | |||
import { getDirectories } from '../../../../api/components'; | |||
import ListStyleFacet from '../../../../components/facet/ListStyleFacet'; | |||
import { mockBranch } from '../../../../helpers/mocks/branch-like'; | |||
import { mockComponent } from '../../../../helpers/testMocks'; | |||
import { TreeComponentWithPath } from '../../../../types/component'; | |||
import { Query } from '../../utils'; | |||
import DirectoryFacet from '../DirectoryFacet'; | |||
jest.mock('../../../../api/components', () => ({ | |||
getDirectories: jest.fn().mockResolvedValue({}) | |||
})); | |||
beforeEach(() => jest.clearAllMocks()); | |||
const branch = mockBranch(); | |||
const component = mockComponent(); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
const instance = wrapper.instance(); | |||
@@ -33,6 +46,25 @@ it('should render correctly', () => { | |||
expect(instance.renderFacetItem('foo/bar')).toMatchSnapshot(); | |||
}); | |||
it('should properly search for directory', () => { | |||
const wrapper = shallowRender(); | |||
const query = 'foo'; | |||
wrapper | |||
.find(ListStyleFacet) | |||
.props() | |||
.onSearch(query); | |||
expect(getDirectories).toHaveBeenCalledWith({ | |||
branch: branch.name, | |||
component: component.key, | |||
q: query, | |||
ps: 30, | |||
p: undefined | |||
}); | |||
}); | |||
describe("ListStyleFacet's callback props", () => { | |||
const wrapper = shallowRender(); | |||
const instance = wrapper.instance(); | |||
@@ -55,7 +87,8 @@ describe("ListStyleFacet's callback props", () => { | |||
function shallowRender(props: Partial<DirectoryFacet['props']> = {}) { | |||
return shallow<DirectoryFacet>( | |||
<DirectoryFacet | |||
componentKey="foo" | |||
branchLike={branch} | |||
componentKey={component.key} | |||
directories={['foo/', 'bar/baz/']} | |||
fetching={false} | |||
loadSearchResultCount={jest.fn()} |
@@ -19,10 +19,23 @@ | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { TreeComponentWithPath } from '../../../../api/components'; | |||
import { getFiles } from '../../../../api/components'; | |||
import ListStyleFacet from '../../../../components/facet/ListStyleFacet'; | |||
import { mockBranch } from '../../../../helpers/mocks/branch-like'; | |||
import { mockComponent } from '../../../../helpers/testMocks'; | |||
import { TreeComponentWithPath } from '../../../../types/component'; | |||
import { Query, ReferencedComponent } from '../../utils'; | |||
import FileFacet from '../FileFacet'; | |||
jest.mock('../../../../api/components', () => ({ | |||
getFiles: jest.fn().mockResolvedValue({}) | |||
})); | |||
beforeEach(() => jest.clearAllMocks()); | |||
const branch = mockBranch(); | |||
const component = mockComponent(); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
const instance = wrapper.instance(); | |||
@@ -33,6 +46,25 @@ it('should render correctly', () => { | |||
expect(instance.renderFacetItem('fooUuid')).toMatchSnapshot(); | |||
}); | |||
it('should properly search for file', () => { | |||
const wrapper = shallowRender(); | |||
const query = 'foo'; | |||
wrapper | |||
.find(ListStyleFacet) | |||
.props() | |||
.onSearch(query); | |||
expect(getFiles).toHaveBeenCalledWith({ | |||
branch: branch.name, | |||
component: component.key, | |||
q: query, | |||
ps: 30, | |||
p: undefined | |||
}); | |||
}); | |||
describe("ListStyleFacet's callback props", () => { | |||
const wrapper = shallowRender(); | |||
const instance = wrapper.instance(); | |||
@@ -57,7 +89,8 @@ describe("ListStyleFacet's callback props", () => { | |||
function shallowRender(props: Partial<FileFacet['props']> = {}) { | |||
return shallow<FileFacet>( | |||
<FileFacet | |||
componentKey="foo" | |||
branchLike={branch} | |||
componentKey={component.key} | |||
fetching={false} | |||
fileUuids={['foo', 'bar']} | |||
loadSearchResultCount={jest.fn()} |
@@ -42,6 +42,20 @@ export enum ProjectKeyValidationResult { | |||
OnlyDigits = 'only_digits' | |||
} | |||
export interface TreeComponent extends T.LightComponent { | |||
id?: string; | |||
name: string; | |||
path?: string; | |||
refId?: string; | |||
refKey?: string; | |||
tags?: string[]; | |||
visibility: T.Visibility; | |||
} | |||
export interface TreeComponentWithPath extends TreeComponent { | |||
path: string; | |||
} | |||
export function isPortfolioLike(componentQualifier?: string | ComponentQualifier) { | |||
return Boolean( | |||
componentQualifier && |