mirror of
https://github.com/harness/drone.git
synced 2025-05-04 15:01:18 +08:00
feat: [code-2061]: add recursive search toggle (#2180)
* feat: [code-2075]: fix issue * feat: [code-2061]: fixed search * feat: [code-2061]: add support for enable recursive * feat: [code-2061]: fix text * feat: [code-2061]: add recursive search toggle
This commit is contained in:
parent
0cb3c8a4cf
commit
e1724bfd5e
@ -8,6 +8,7 @@ export interface StringsMap {
|
|||||||
accessControl: string
|
accessControl: string
|
||||||
accountEmail: string
|
accountEmail: string
|
||||||
accountSetting: string
|
accountSetting: string
|
||||||
|
accounts: string
|
||||||
active: string
|
active: string
|
||||||
activeBranches: string
|
activeBranches: string
|
||||||
add: string
|
add: string
|
||||||
@ -904,6 +905,8 @@ export interface StringsMap {
|
|||||||
readMe: string
|
readMe: string
|
||||||
reader: string
|
reader: string
|
||||||
rebaseMerge: string
|
rebaseMerge: string
|
||||||
|
recursiveSearchLabel: string
|
||||||
|
recursiveSearchTooltip: string
|
||||||
refresh: string
|
refresh: string
|
||||||
reject: string
|
reject: string
|
||||||
rejected: string
|
rejected: string
|
||||||
@ -962,6 +965,13 @@ export interface StringsMap {
|
|||||||
searchExamples: string
|
searchExamples: string
|
||||||
searchHeader: string
|
searchHeader: string
|
||||||
searchResult: string
|
searchResult: string
|
||||||
|
'searchScope.accOnly': string
|
||||||
|
'searchScope.allScopes': string
|
||||||
|
'searchScope.base': string
|
||||||
|
'searchScope.orgAndProj': string
|
||||||
|
'searchScope.orgOnly': string
|
||||||
|
'searchScope.placeholder': string
|
||||||
|
'searchScope.title': string
|
||||||
secret: string
|
secret: string
|
||||||
'secrets.create': string
|
'secrets.create': string
|
||||||
'secrets.createSecret': string
|
'secrets.createSecret': string
|
||||||
|
@ -1275,3 +1275,13 @@ sshCard:
|
|||||||
personalAccessToken: Personal Access Token
|
personalAccessToken: Personal Access Token
|
||||||
noTokensText: There are no personal access tokens associated with this account
|
noTokensText: There are no personal access tokens associated with this account
|
||||||
lastUsed: Last Used
|
lastUsed: Last Used
|
||||||
|
recursiveSearchTooltip: Disabling recursive search will only search at the account level and exclude organization and project repositories.
|
||||||
|
recursiveSearchLabel: 'Recursive search: show results across Repositories within {account} Organization and Projects'
|
||||||
|
accounts: "Account's"
|
||||||
|
searchScope:
|
||||||
|
base: 'Search scope: {scope}'
|
||||||
|
allScopes: Account, organizations and projects
|
||||||
|
accOnly: Account Only
|
||||||
|
orgOnly: Organizations only
|
||||||
|
orgAndProj: Organizations and Projects
|
||||||
|
title: Search scope
|
||||||
|
@ -246,7 +246,7 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||||||
return {
|
return {
|
||||||
commitTitle: messageTitle,
|
commitTitle: messageTitle,
|
||||||
commitMessage: mergeOption.method === MergeStrategy.SQUASH ? messageString : ''
|
commitMessage: mergeOption.method === MergeStrategy.SQUASH ? messageString : ''
|
||||||
}
|
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [pullReqCommits, mergeOption, pullReqMetadata])
|
}, [pullReqCommits, mergeOption, pullReqMetadata])
|
||||||
|
|
||||||
if (pullReqMetadata.state === PullRequestFilterOption.MERGED) {
|
if (pullReqMetadata.state === PullRequestFilterOption.MERGED) {
|
||||||
|
@ -79,7 +79,10 @@ const Search = () => {
|
|||||||
const [selectedRepositories, setSelectedRepositories] = useState<SelectOption[]>([])
|
const [selectedRepositories, setSelectedRepositories] = useState<SelectOption[]>([])
|
||||||
const [selectedLanguages, setSelectedLanguages] = useState<(SelectOption & { extension?: string })[]>([])
|
const [selectedLanguages, setSelectedLanguages] = useState<(SelectOption & { extension?: string })[]>([])
|
||||||
const [keywordSearchResults, setKeyowordSearchResults] = useState<KeywordSearchResponse>()
|
const [keywordSearchResults, setKeyowordSearchResults] = useState<KeywordSearchResponse>()
|
||||||
|
const projectId = space?.split('/')[2]
|
||||||
|
|
||||||
|
const [recursiveSearchEnabled, setRecursiveSearchEnabled] = useState(!projectId ? true : false)
|
||||||
|
const [curScopeLabel, setCurScopeLabel] = useState<SelectOption>()
|
||||||
//semantic
|
//semantic
|
||||||
// const [loadingSearch, setLoadingSearch] = useState(false)
|
// const [loadingSearch, setLoadingSearch] = useState(false)
|
||||||
const [semanticSearchResult, setSemanticSearchResult] = useState<SemanticSearchResultType[]>([])
|
const [semanticSearchResult, setSemanticSearchResult] = useState<SemanticSearchResultType[]>([])
|
||||||
@ -121,11 +124,14 @@ const Search = () => {
|
|||||||
query += ` case:no`
|
query += ` case:no`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear previous results
|
||||||
|
setKeyowordSearchResults(undefined)
|
||||||
const res = await mutate({
|
const res = await mutate({
|
||||||
repo_paths: repoPath ? [repoPath] : repoPaths,
|
repo_paths: repoPath ? [repoPath] : repoPaths,
|
||||||
space_paths: !repoPath && !repoPaths.length ? [space] : [],
|
space_paths: !repoPath && !repoPaths.length ? [space] : [],
|
||||||
query,
|
query,
|
||||||
max_result_count: maxResultCount
|
max_result_count: maxResultCount,
|
||||||
|
recursive: recursiveSearchEnabled
|
||||||
})
|
})
|
||||||
|
|
||||||
setKeyowordSearchResults(res)
|
setKeyowordSearchResults(res)
|
||||||
@ -136,7 +142,7 @@ const Search = () => {
|
|||||||
showError(getErrorMessage(error))
|
showError(getErrorMessage(error))
|
||||||
}
|
}
|
||||||
}, 300),
|
}, 300),
|
||||||
[selectedLanguages, selectedRepositories, repoPath, mode]
|
[selectedLanguages, selectedRepositories, repoPath, mode, recursiveSearchEnabled]
|
||||||
)
|
)
|
||||||
|
|
||||||
const performSemanticSearch = useCallback(() => {
|
const performSemanticSearch = useCallback(() => {
|
||||||
@ -154,7 +160,7 @@ const Search = () => {
|
|||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
// setLoadingSearch(false)
|
// setLoadingSearch(false)
|
||||||
})
|
}) // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [searchTerm, history, location, repoPath, sendSemanticSearch, showError, mode])
|
}, [searchTerm, history, location, repoPath, sendSemanticSearch, showError, mode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -162,8 +168,15 @@ const Search = () => {
|
|||||||
debouncedSearch(searchTerm)
|
debouncedSearch(searchTerm)
|
||||||
} else if (searchTerm && repoMetadata?.path && mode === SEARCH_MODE.SEMANTIC) {
|
} else if (searchTerm && repoMetadata?.path && mode === SEARCH_MODE.SEMANTIC) {
|
||||||
performSemanticSearch()
|
performSemanticSearch()
|
||||||
}
|
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [selectedLanguages, selectedRepositories, repoMetadata?.path])
|
}, [selectedLanguages, selectedRepositories, repoMetadata?.path])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
debouncedSearch(searchTerm)
|
||||||
|
}, 0) // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [setRecursiveSearchEnabled, recursiveSearchEnabled])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className={css.main}>
|
<Container className={css.main}>
|
||||||
<Container padding="medium" border={{ bottom: true }} flex className={css.header}>
|
<Container padding="medium" border={{ bottom: true }} flex className={css.header}>
|
||||||
@ -210,6 +223,10 @@ const Search = () => {
|
|||||||
selectedRepositories={selectedRepositories}
|
selectedRepositories={selectedRepositories}
|
||||||
setLanguages={setSelectedLanguages}
|
setLanguages={setSelectedLanguages}
|
||||||
setRepositories={setSelectedRepositories}
|
setRepositories={setSelectedRepositories}
|
||||||
|
recursiveSearchEnabled={recursiveSearchEnabled}
|
||||||
|
setRecursiveSearchEnabled={setRecursiveSearchEnabled}
|
||||||
|
curScopeLabel={curScopeLabel}
|
||||||
|
setCurScopeLabel={setCurScopeLabel}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -279,6 +296,11 @@ interface CodeBlock {
|
|||||||
|
|
||||||
export const SearchResult = ({ fileMatch, searchTerm }: { fileMatch: FileMatch; searchTerm: string }) => {
|
export const SearchResult = ({ fileMatch, searchTerm }: { fileMatch: FileMatch; searchTerm: string }) => {
|
||||||
const { routes } = useAppContext()
|
const { routes } = useAppContext()
|
||||||
|
const space = useGetSpaceParam()
|
||||||
|
const accId = space?.split('/')[0]
|
||||||
|
|
||||||
|
const projectId = space?.split('/')[2]
|
||||||
|
const orgId = space?.split('/')[1]
|
||||||
|
|
||||||
const [isCollapsed, setIsCollapsed] = useToggle(false)
|
const [isCollapsed, setIsCollapsed] = useToggle(false)
|
||||||
const [showMoreMatchs, setShowMoreMatches] = useState(false)
|
const [showMoreMatchs, setShowMoreMatches] = useState(false)
|
||||||
@ -326,8 +348,18 @@ export const SearchResult = ({ fileMatch, searchTerm }: { fileMatch: FileMatch;
|
|||||||
}, [fileMatch])
|
}, [fileMatch])
|
||||||
|
|
||||||
const collapsedCodeBlocks = showMoreMatchs ? codeBlocks.slice(0, 25) : codeBlocks.slice(0, 2)
|
const collapsedCodeBlocks = showMoreMatchs ? codeBlocks.slice(0, 25) : codeBlocks.slice(0, 2)
|
||||||
const repoName = fileMatch.repo_path.split('/').pop()
|
const repoPathParts = fileMatch.repo_path.split('/')
|
||||||
|
let repoName = ''
|
||||||
|
|
||||||
|
if (accId && !orgId && !projectId) {
|
||||||
|
repoName = repoPathParts.slice(1).join('/')
|
||||||
|
} else if (accId && orgId && !projectId) {
|
||||||
|
repoName = repoPathParts.slice(2).join('/')
|
||||||
|
} else if (accId && orgId && projectId) {
|
||||||
|
repoName = fileMatch.repo_path.split('/').pop() as string
|
||||||
|
} else {
|
||||||
|
repoName = fileMatch.repo_path.split('/').pop() as string
|
||||||
|
}
|
||||||
const isFileMatch = fileMatch.matches?.[0]?.line_num === 0
|
const isFileMatch = fileMatch.matches?.[0]?.line_num === 0
|
||||||
|
|
||||||
const flattenedMatches = flatten(codeBlocks.map(codeBlock => codeBlock.fragmentMatches))
|
const flattenedMatches = flatten(codeBlocks.map(codeBlock => codeBlock.fragmentMatches))
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
import React, { Dispatch, SetStateAction } from 'react'
|
import React, { Dispatch, SetStateAction, useMemo, useState } from 'react'
|
||||||
import { Container, Text, type SelectOption, MultiSelectDropDown, Button, ButtonVariation } from '@harnessio/uicore'
|
import {
|
||||||
|
Container,
|
||||||
|
Text,
|
||||||
|
type SelectOption,
|
||||||
|
MultiSelectDropDown,
|
||||||
|
Button,
|
||||||
|
ButtonVariation,
|
||||||
|
DropDown
|
||||||
|
} from '@harnessio/uicore'
|
||||||
import { Color, FontVariation } from '@harnessio/design-system'
|
import { Color, FontVariation } from '@harnessio/design-system'
|
||||||
import { useGet } from 'restful-react'
|
import { useGet } from 'restful-react'
|
||||||
|
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||||
import type { RepoRepositoryOutput } from 'services/code'
|
import type { RepoRepositoryOutput } from 'services/code'
|
||||||
|
import { ScopeLevelEnum } from 'utils/Utils'
|
||||||
import css from './Search.module.scss'
|
import css from './Search.module.scss'
|
||||||
|
|
||||||
const languageOptions = [
|
const languageOptions = [
|
||||||
@ -32,6 +39,10 @@ interface KeywordSearchFiltersProps {
|
|||||||
setRepositories: Dispatch<SetStateAction<SelectOption[]>>
|
setRepositories: Dispatch<SetStateAction<SelectOption[]>>
|
||||||
selectedLanguages: SelectOption[]
|
selectedLanguages: SelectOption[]
|
||||||
setLanguages: Dispatch<SetStateAction<SelectOption[]>>
|
setLanguages: Dispatch<SetStateAction<SelectOption[]>>
|
||||||
|
recursiveSearchEnabled: boolean
|
||||||
|
setRecursiveSearchEnabled: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
|
curScopeLabel: SelectOption | undefined
|
||||||
|
setCurScopeLabel: React.Dispatch<React.SetStateAction<SelectOption | undefined>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const KeywordSearchFilters: React.FC<KeywordSearchFiltersProps> = ({
|
const KeywordSearchFilters: React.FC<KeywordSearchFiltersProps> = ({
|
||||||
@ -39,15 +50,27 @@ const KeywordSearchFilters: React.FC<KeywordSearchFiltersProps> = ({
|
|||||||
selectedLanguages,
|
selectedLanguages,
|
||||||
selectedRepositories,
|
selectedRepositories,
|
||||||
setLanguages,
|
setLanguages,
|
||||||
setRepositories
|
setRepositories,
|
||||||
|
recursiveSearchEnabled,
|
||||||
|
setRecursiveSearchEnabled,
|
||||||
|
curScopeLabel,
|
||||||
|
setCurScopeLabel
|
||||||
}) => {
|
}) => {
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
const space = useGetSpaceParam()
|
const space = useGetSpaceParam()
|
||||||
|
const accId = space?.split('/')[0]
|
||||||
|
const orgId = space?.split('/')[1]
|
||||||
|
|
||||||
|
const projectId = space?.split('/')[2]
|
||||||
|
const enabledRecursive = useMemo(() => recursiveSearchEnabled, [recursiveSearchEnabled])
|
||||||
const { data } = useGet<RepoRepositoryOutput[]>({
|
const { data } = useGet<RepoRepositoryOutput[]>({
|
||||||
path: `/api/v1/spaces/${space}/+/repos`,
|
path: `/api/v1/spaces/${space}/+/repos`,
|
||||||
debounce: 500,
|
debounce: 500,
|
||||||
lazy: isRepoLevelSearch
|
|
||||||
|
lazy: isRepoLevelSearch,
|
||||||
|
queryParams: {
|
||||||
|
recursive: enabledRecursive
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const repositoryOptions =
|
const repositoryOptions =
|
||||||
@ -56,8 +79,47 @@ const KeywordSearchFilters: React.FC<KeywordSearchFiltersProps> = ({
|
|||||||
value: String(repository.path)
|
value: String(repository.path)
|
||||||
})) || []
|
})) || []
|
||||||
|
|
||||||
|
const scopeOption = [
|
||||||
|
accId && !orgId
|
||||||
|
? {
|
||||||
|
label: getString('searchScope.allScopes'),
|
||||||
|
value: ScopeLevelEnum.ALL
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
accId && !orgId ? { label: getString('searchScope.accOnly'), value: ScopeLevelEnum.CURRENT } : null,
|
||||||
|
orgId ? { label: getString('searchScope.orgAndProj'), value: ScopeLevelEnum.ALL } : null,
|
||||||
|
orgId ? { label: getString('searchScope.orgOnly'), value: ScopeLevelEnum.CURRENT } : null
|
||||||
|
].filter(Boolean) as SelectOption[]
|
||||||
|
|
||||||
|
const [scopeLabel, setScopeLabel] = useState<SelectOption>(curScopeLabel ? curScopeLabel : scopeOption[0])
|
||||||
return (
|
return (
|
||||||
<div className={css.filtersCtn}>
|
<div className={css.filtersCtn}>
|
||||||
|
{projectId ? null : (
|
||||||
|
<>
|
||||||
|
<Container>
|
||||||
|
<Text font={{ variation: FontVariation.SMALL_SEMI }} color={Color.GREY_600} margin={{ bottom: 'xsmall' }}>
|
||||||
|
{getString('searchScope.title')}
|
||||||
|
</Text>
|
||||||
|
<DropDown
|
||||||
|
placeholder={scopeLabel.label}
|
||||||
|
className={css.dropdown}
|
||||||
|
value={scopeLabel}
|
||||||
|
items={scopeOption}
|
||||||
|
onChange={e => {
|
||||||
|
if (e.value === ScopeLevelEnum.ALL) {
|
||||||
|
setRecursiveSearchEnabled(true)
|
||||||
|
} else if (e.value === ScopeLevelEnum.CURRENT) {
|
||||||
|
setRecursiveSearchEnabled(false)
|
||||||
|
}
|
||||||
|
setScopeLabel(e)
|
||||||
|
setCurScopeLabel(e)
|
||||||
|
}}
|
||||||
|
popoverClassName={css.branchDropdown}
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{isRepoLevelSearch ? null : (
|
{isRepoLevelSearch ? null : (
|
||||||
<Container>
|
<Container>
|
||||||
<Text font={{ variation: FontVariation.SMALL_SEMI }} color={Color.GREY_600} margin={{ bottom: 'xsmall' }}>
|
<Text font={{ variation: FontVariation.SMALL_SEMI }} color={Color.GREY_600} margin={{ bottom: 'xsmall' }}>
|
||||||
@ -84,14 +146,16 @@ const KeywordSearchFilters: React.FC<KeywordSearchFiltersProps> = ({
|
|||||||
items={languageOptions}
|
items={languageOptions}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
<Button
|
<Container>
|
||||||
variation={ButtonVariation.LINK}
|
<Button
|
||||||
text={getString('clear')}
|
variation={ButtonVariation.LINK}
|
||||||
onClick={() => {
|
text={getString('clear')}
|
||||||
setRepositories([])
|
onClick={() => {
|
||||||
setLanguages([])
|
setRepositories([])
|
||||||
}}
|
setLanguages([])
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@
|
|||||||
.filtersCtn {
|
.filtersCtn {
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: max-content max-content min-content;
|
grid-template-columns: max-content max-content min-content min-content;
|
||||||
column-gap: var(--spacing-medium);
|
column-gap: var(--spacing-medium);
|
||||||
margin-bottom: var(--spacing-large);
|
margin-bottom: var(--spacing-large);
|
||||||
|
|
||||||
@ -275,6 +275,9 @@
|
|||||||
.multiSelect {
|
.multiSelect {
|
||||||
min-width: 203px;
|
min-width: 203px;
|
||||||
}
|
}
|
||||||
|
.dropdown {
|
||||||
|
min-width: 303px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchResult {
|
.searchResult {
|
||||||
@ -360,3 +363,39 @@
|
|||||||
.aidaFeedback {
|
.aidaFeedback {
|
||||||
padding: 5px 10px !important;
|
padding: 5px 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.searchContainer {
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid var(--grey-200) !important;
|
||||||
|
padding: 3px var(--spacing-small) !important;
|
||||||
|
|
||||||
|
:global {
|
||||||
|
.bp3-popover-wrapper {
|
||||||
|
justify-content: center !important;
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
> svg {
|
||||||
|
fill: var(--primary-7) !important;
|
||||||
|
|
||||||
|
> path {
|
||||||
|
fill: var(--primary-7) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
flex-grow: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.branchDropdown {
|
||||||
|
min-width: 303px !important;
|
||||||
|
:global {
|
||||||
|
.bp3-input-group {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
4
web/src/pages/Search/Search.module.scss.d.ts
vendored
4
web/src/pages/Search/Search.module.scss.d.ts
vendored
@ -18,6 +18,8 @@
|
|||||||
// This is an auto-generated file
|
// This is an auto-generated file
|
||||||
export declare const aidaFeedback: string
|
export declare const aidaFeedback: string
|
||||||
export declare const aiLabel: string
|
export declare const aiLabel: string
|
||||||
|
export declare const branchDropdown: string
|
||||||
|
export declare const dropdown: string
|
||||||
export declare const editorCtn: string
|
export declare const editorCtn: string
|
||||||
export declare const fileContent: string
|
export declare const fileContent: string
|
||||||
export declare const filename: string
|
export declare const filename: string
|
||||||
@ -26,6 +28,7 @@ export declare const filtersCtn: string
|
|||||||
export declare const header: string
|
export declare const header: string
|
||||||
export declare const highlight: string
|
export declare const highlight: string
|
||||||
export declare const highlightLineNumber: string
|
export declare const highlightLineNumber: string
|
||||||
|
export declare const icon: string
|
||||||
export declare const isCollapsed: string
|
export declare const isCollapsed: string
|
||||||
export declare const layout: string
|
export declare const layout: string
|
||||||
export declare const loadingSpinner: string
|
export declare const loadingSpinner: string
|
||||||
@ -41,6 +44,7 @@ export declare const result: string
|
|||||||
export declare const resultHeader: string
|
export declare const resultHeader: string
|
||||||
export declare const resultTitle: string
|
export declare const resultTitle: string
|
||||||
export declare const searchBox: string
|
export declare const searchBox: string
|
||||||
|
export declare const searchContainer: string
|
||||||
export declare const searchResult: string
|
export declare const searchResult: string
|
||||||
export declare const selected: string
|
export declare const selected: string
|
||||||
export declare const semanticStamp: string
|
export declare const semanticStamp: string
|
||||||
|
@ -638,6 +638,10 @@ export function formatBytes(bytes: number, decimals = 2) {
|
|||||||
|
|
||||||
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
|
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
|
||||||
}
|
}
|
||||||
|
export enum ScopeLevelEnum {
|
||||||
|
ALL = 'all',
|
||||||
|
CURRENT = 'current'
|
||||||
|
}
|
||||||
|
|
||||||
export enum PullRequestCheckType {
|
export enum PullRequestCheckType {
|
||||||
EMPTY = '',
|
EMPTY = '',
|
||||||
|
Loading…
Reference in New Issue
Block a user