2021-10-15 05:35:26 +03:00
import Vue from 'vue' ;
import { initVueSvg , vueDelimiters } from './VueComponentLoader.js' ;
2021-10-21 10:37:43 +03:00
const { appSubUrl , assetUrlPrefix , pageData } = window . config ;
2021-10-15 05:35:26 +03:00
function initVueComponents ( ) {
Vue . component ( 'repo-search' , {
delimiters : vueDelimiters ,
props : {
searchLimit : {
type : Number ,
default : 10
} ,
subUrl : {
type : String ,
required : true
} ,
uid : {
type : Number ,
default : 0
} ,
teamId : {
type : Number ,
required : false ,
default : 0
} ,
organizations : {
type : Array ,
default : ( ) => [ ] ,
} ,
isOrganization : {
type : Boolean ,
default : true
} ,
canCreateOrganization : {
type : Boolean ,
default : false
} ,
organizationsTotalCount : {
type : Number ,
default : 0
} ,
moreReposLink : {
type : String ,
default : ''
}
} ,
data ( ) {
const params = new URLSearchParams ( window . location . search ) ;
let tab = params . get ( 'repo-search-tab' ) ;
if ( ! tab ) {
tab = 'repos' ;
}
let reposFilter = params . get ( 'repo-search-filter' ) ;
if ( ! reposFilter ) {
reposFilter = 'all' ;
}
let privateFilter = params . get ( 'repo-search-private' ) ;
if ( ! privateFilter ) {
privateFilter = 'both' ;
}
let archivedFilter = params . get ( 'repo-search-archived' ) ;
if ( ! archivedFilter ) {
archivedFilter = 'unarchived' ;
}
let searchQuery = params . get ( 'repo-search-query' ) ;
if ( ! searchQuery ) {
searchQuery = '' ;
}
let page = 1 ;
try {
page = parseInt ( params . get ( 'repo-search-page' ) ) ;
} catch {
// noop
}
if ( ! page ) {
page = 1 ;
}
return {
tab ,
repos : [ ] ,
reposTotalCount : 0 ,
reposFilter ,
archivedFilter ,
privateFilter ,
page ,
finalPage : 1 ,
searchQuery ,
isLoading : false ,
2021-10-21 10:37:43 +03:00
staticPrefix : assetUrlPrefix ,
2021-10-15 05:35:26 +03:00
counts : { } ,
repoTypes : {
all : {
searchMode : '' ,
} ,
forks : {
searchMode : 'fork' ,
} ,
mirrors : {
searchMode : 'mirror' ,
} ,
sources : {
searchMode : 'source' ,
} ,
collaborative : {
searchMode : 'collaborative' ,
} ,
}
} ;
} ,
computed : {
// used in `repolist.tmpl`
showMoreReposLink ( ) {
return this . repos . length > 0 && this . repos . length < this . counts [ ` ${ this . reposFilter } : ${ this . archivedFilter } : ${ this . privateFilter } ` ] ;
} ,
searchURL ( ) {
return ` ${ this . subUrl } /api/v1/repos/search?sort=updated&order=desc&uid= ${ this . uid } &team_id= ${ this . teamId } &q= ${ this . searchQuery
} & page = $ { this . page } & limit = $ { this . searchLimit } & mode = $ { this . repoTypes [ this . reposFilter ] . searchMode
} $ { this . reposFilter !== 'all' ? '&exclusive=1' : ''
} $ { this . archivedFilter === 'archived' ? '&archived=true' : '' } $ { this . archivedFilter === 'unarchived' ? '&archived=false' : ''
} $ { this . privateFilter === 'private' ? '&is_private=true' : '' } $ { this . privateFilter === 'public' ? '&is_private=false' : ''
} ` ;
} ,
repoTypeCount ( ) {
return this . counts [ ` ${ this . reposFilter } : ${ this . archivedFilter } : ${ this . privateFilter } ` ] ;
}
} ,
mounted ( ) {
this . changeReposFilter ( this . reposFilter ) ;
$ ( this . $el ) . find ( '.poping.up' ) . popup ( ) ;
$ ( this . $el ) . find ( '.dropdown' ) . dropdown ( ) ;
this . setCheckboxes ( ) ;
Vue . nextTick ( ( ) => {
this . $refs . search . focus ( ) ;
} ) ;
} ,
methods : {
changeTab ( t ) {
this . tab = t ;
this . updateHistory ( ) ;
} ,
setCheckboxes ( ) {
switch ( this . archivedFilter ) {
case 'unarchived' :
$ ( '#archivedFilterCheckbox' ) . checkbox ( 'set unchecked' ) ;
break ;
case 'archived' :
$ ( '#archivedFilterCheckbox' ) . checkbox ( 'set checked' ) ;
break ;
case 'both' :
$ ( '#archivedFilterCheckbox' ) . checkbox ( 'set indeterminate' ) ;
break ;
default :
this . archivedFilter = 'unarchived' ;
$ ( '#archivedFilterCheckbox' ) . checkbox ( 'set unchecked' ) ;
break ;
}
switch ( this . privateFilter ) {
case 'public' :
$ ( '#privateFilterCheckbox' ) . checkbox ( 'set unchecked' ) ;
break ;
case 'private' :
$ ( '#privateFilterCheckbox' ) . checkbox ( 'set checked' ) ;
break ;
case 'both' :
$ ( '#privateFilterCheckbox' ) . checkbox ( 'set indeterminate' ) ;
break ;
default :
this . privateFilter = 'both' ;
$ ( '#privateFilterCheckbox' ) . checkbox ( 'set indeterminate' ) ;
break ;
}
} ,
changeReposFilter ( filter ) {
this . reposFilter = filter ;
this . repos = [ ] ;
this . page = 1 ;
Vue . set ( this . counts , ` ${ filter } : ${ this . archivedFilter } : ${ this . privateFilter } ` , 0 ) ;
this . searchRepos ( ) ;
} ,
updateHistory ( ) {
const params = new URLSearchParams ( window . location . search ) ;
if ( this . tab === 'repos' ) {
params . delete ( 'repo-search-tab' ) ;
} else {
params . set ( 'repo-search-tab' , this . tab ) ;
}
if ( this . reposFilter === 'all' ) {
params . delete ( 'repo-search-filter' ) ;
} else {
params . set ( 'repo-search-filter' , this . reposFilter ) ;
}
if ( this . privateFilter === 'both' ) {
params . delete ( 'repo-search-private' ) ;
} else {
params . set ( 'repo-search-private' , this . privateFilter ) ;
}
if ( this . archivedFilter === 'unarchived' ) {
params . delete ( 'repo-search-archived' ) ;
} else {
params . set ( 'repo-search-archived' , this . archivedFilter ) ;
}
if ( this . searchQuery === '' ) {
params . delete ( 'repo-search-query' ) ;
} else {
params . set ( 'repo-search-query' , this . searchQuery ) ;
}
if ( this . page === 1 ) {
params . delete ( 'repo-search-page' ) ;
} else {
params . set ( 'repo-search-page' , ` ${ this . page } ` ) ;
}
const queryString = params . toString ( ) ;
if ( queryString ) {
window . history . replaceState ( { } , '' , ` ? ${ queryString } ` ) ;
} else {
window . history . replaceState ( { } , '' , window . location . pathname ) ;
}
} ,
toggleArchivedFilter ( ) {
switch ( this . archivedFilter ) {
case 'both' :
this . archivedFilter = 'unarchived' ;
break ;
case 'unarchived' :
this . archivedFilter = 'archived' ;
break ;
case 'archived' :
this . archivedFilter = 'both' ;
break ;
default :
this . archivedFilter = 'unarchived' ;
break ;
}
this . page = 1 ;
this . repos = [ ] ;
this . setCheckboxes ( ) ;
Vue . set ( this . counts , ` ${ this . reposFilter } : ${ this . archivedFilter } : ${ this . privateFilter } ` , 0 ) ;
this . searchRepos ( ) ;
} ,
togglePrivateFilter ( ) {
switch ( this . privateFilter ) {
case 'both' :
this . privateFilter = 'public' ;
break ;
case 'public' :
this . privateFilter = 'private' ;
break ;
case 'private' :
this . privateFilter = 'both' ;
break ;
default :
this . privateFilter = 'both' ;
break ;
}
this . page = 1 ;
this . repos = [ ] ;
this . setCheckboxes ( ) ;
Vue . set ( this . counts , ` ${ this . reposFilter } : ${ this . archivedFilter } : ${ this . privateFilter } ` , 0 ) ;
this . searchRepos ( ) ;
} ,
changePage ( page ) {
this . page = page ;
if ( this . page > this . finalPage ) {
this . page = this . finalPage ;
}
if ( this . page < 1 ) {
this . page = 1 ;
}
this . repos = [ ] ;
Vue . set ( this . counts , ` ${ this . reposFilter } : ${ this . archivedFilter } : ${ this . privateFilter } ` , 0 ) ;
this . searchRepos ( ) ;
} ,
searchRepos ( ) {
this . isLoading = true ;
if ( ! this . reposTotalCount ) {
const totalCountSearchURL = ` ${ this . subUrl } /api/v1/repos/search?sort=updated&order=desc&uid= ${ this . uid } &team_id= ${ this . teamId } &q=&page=1&mode= ` ;
$ . getJSON ( totalCountSearchURL , ( _result , _textStatus , request ) => {
this . reposTotalCount = request . getResponseHeader ( 'X-Total-Count' ) ;
} ) ;
}
const searchedMode = this . repoTypes [ this . reposFilter ] . searchMode ;
const searchedURL = this . searchURL ;
const searchedQuery = this . searchQuery ;
$ . getJSON ( searchedURL , ( result , _textStatus , request ) => {
if ( searchedURL === this . searchURL ) {
this . repos = result . data ;
const count = request . getResponseHeader ( 'X-Total-Count' ) ;
if ( searchedQuery === '' && searchedMode === '' && this . archivedFilter === 'both' ) {
this . reposTotalCount = count ;
}
Vue . set ( this . counts , ` ${ this . reposFilter } : ${ this . archivedFilter } : ${ this . privateFilter } ` , count ) ;
this . finalPage = Math . ceil ( count / this . searchLimit ) ;
this . updateHistory ( ) ;
}
} ) . always ( ( ) => {
if ( searchedURL === this . searchURL ) {
this . isLoading = false ;
}
} ) ;
} ,
repoIcon ( repo ) {
if ( repo . fork ) {
return 'octicon-repo-forked' ;
} else if ( repo . mirror ) {
return 'octicon-mirror' ;
} else if ( repo . template ) {
return ` octicon-repo-template ` ;
} else if ( repo . private ) {
return 'octicon-lock' ;
} else if ( repo . internal ) {
return 'octicon-repo' ;
}
return 'octicon-repo' ;
}
}
} ) ;
}
2021-10-16 20:28:04 +03:00
export function initDashboardRepoList ( ) {
2021-10-15 05:35:26 +03:00
const el = document . getElementById ( 'dashboard-repo-list' ) ;
const dashboardRepoListData = pageData . dashboardRepoList || null ;
if ( ! el || ! dashboardRepoListData ) return ;
initVueSvg ( ) ;
initVueComponents ( ) ;
new Vue ( {
el ,
delimiters : vueDelimiters ,
data : ( ) => {
return {
searchLimit : dashboardRepoListData . searchLimit || 0 ,
2021-10-21 10:37:43 +03:00
subUrl : appSubUrl ,
2021-10-19 07:38:33 +03:00
uid : dashboardRepoListData . uid || 0 ,
2021-10-15 05:35:26 +03:00
} ;
} ,
} ) ;
}