2013-10-17 18:46:23 +00:00
$ . fn . clipboardCopy = function ( ) {
var clip = new ZeroClipboard ( $ ( this ) , { 'moviePath' : 'static/lib/ZeroClipboard.swf' } ) ;
clip . on ( 'complete' , function ( ) {
// Resets the animation.
var elem = $ ( '#clipboardCopied' ) [ 0 ] ;
elem . style . display = 'none' ;
// Show the notification.
setTimeout ( function ( ) {
elem . style . display = 'inline-block' ;
} , 1 ) ;
} ) ;
} ;
2013-09-30 23:08:24 +00:00
function getFirstTextLine ( commentString ) {
if ( ! commentString ) { return ; }
var lines = commentString . split ( '\n' ) ;
2013-10-01 23:37:33 +00:00
var MARKDOWN _CHARS = {
'#' : true ,
'-' : true ,
'>' : true ,
'`' : true
} ;
2013-09-30 23:08:24 +00:00
for ( var i = 0 ; i < lines . length ; ++ i ) {
// Skip code lines.
if ( lines [ i ] . indexOf ( ' ' ) == 0 ) {
2013-10-01 23:37:33 +00:00
continue ;
2013-09-30 23:08:24 +00:00
}
// Skip empty lines.
if ( $ . trim ( lines [ i ] ) . length == 0 ) {
continue ;
}
// Skip control lines.
if ( MARKDOWN _CHARS [ $ . trim ( lines [ i ] ) [ 0 ] ] ) {
2013-10-01 23:37:33 +00:00
continue ;
2013-09-30 23:08:24 +00:00
}
return getMarkedDown ( lines [ i ] ) ;
}
return '' ;
}
function getMarkedDown ( string ) {
return Markdown . getSanitizingConverter ( ) . makeHtml ( string || '' ) ;
}
2013-10-14 21:50:07 +00:00
function HeaderCtrl ( $scope , $location , UserService , Restangular ) {
2013-10-17 21:45:08 +00:00
$scope . $watch ( function ( ) { return UserService . currentUser ( ) ; } , function ( currentUser ) {
2013-09-26 23:59:58 +00:00
$scope . user = currentUser ;
} , true ) ;
2013-09-27 23:21:54 +00:00
2013-10-14 21:50:07 +00:00
$scope . signout = function ( ) {
var signoutPost = Restangular . one ( 'signout' ) ;
signoutPost . customPOST ( ) . then ( function ( ) {
UserService . load ( ) ;
$location . path ( '/' ) ;
} ) ;
}
$scope . $on ( '$includeContentLoaded' , function ( ) {
// THIS IS BAD, MOVE THIS TO A DIRECTIVE
$ ( '#repoSearch' ) . typeahead ( {
name : 'repositories' ,
remote : {
url : '/api/find/repository?query=%QUERY' ,
filter : function ( data ) {
var datums = [ ] ;
for ( var i = 0 ; i < data . repositories . length ; ++ i ) {
var repo = data . repositories [ i ] ;
datums . push ( {
'value' : repo . name ,
'tokens' : [ repo . name , repo . namespace ] ,
'repo' : repo
} ) ;
}
return datums ;
}
} ,
template : function ( datum ) {
template = '<div class="repo-mini-listing">' ;
template += '<i class="icon-hdd icon-large"></i>'
template += '<span class="name">' + datum . repo . namespace + '/' + datum . repo . name + '</span>'
if ( datum . repo . description ) {
template += '<span class="description">' + getFirstTextLine ( datum . repo . description ) + '</span>'
2013-10-01 23:37:33 +00:00
}
2013-10-14 21:50:07 +00:00
template += '</div>'
return template ;
} ,
2013-09-27 23:21:54 +00:00
2013-10-14 21:50:07 +00:00
} ) ;
2013-09-27 23:21:54 +00:00
2013-10-14 21:50:07 +00:00
$ ( '#repoSearch' ) . on ( 'typeahead:selected' , function ( e , datum ) {
$ ( '#repoSearch' ) . typeahead ( 'setQuery' , '' ) ;
document . location = '/repository/' + datum . repo . namespace + '/' + datum . repo . name
} ) ;
2013-09-27 23:21:54 +00:00
} ) ;
2013-09-26 23:59:58 +00:00
}
2013-10-14 21:50:07 +00:00
function SigninCtrl ( $scope , $location , $timeout , Restangular , KeyService , UserService ) {
$scope . githubClientId = KeyService . githubClientId ;
var appendMixpanelId = function ( ) {
if ( mixpanel . get _distinct _id !== undefined ) {
$scope . mixpanelDistinctIdClause = "&state=" + mixpanel . get _distinct _id ( ) ;
} else {
// Mixpanel not yet loaded, try again later
$timeout ( appendMixpanelId , 200 ) ;
}
} ;
appendMixpanelId ( ) ;
$scope . signin = function ( ) {
var signinPost = Restangular . one ( 'signin' ) ;
signinPost . customPOST ( $scope . user ) . then ( function ( ) {
$scope . needsEmailVerification = false ;
$scope . invalidCredentials = false ;
// Redirect to the landing page
UserService . load ( ) ;
$location . path ( '/' ) ;
} , function ( result ) {
$scope . needsEmailVerification = result . data . needsEmailVerification ;
$scope . invalidCredentials = result . data . invalidCredentials ;
} ) ;
} ;
$scope . sendRecovery = function ( ) {
var signinPost = Restangular . one ( 'recovery' ) ;
signinPost . customPOST ( $scope . recovery ) . then ( function ( ) {
$scope . invalidEmail = false ;
$scope . sent = true ;
} , function ( result ) {
$scope . invalidEmail = true ;
$scope . sent = false ;
} ) ;
} ;
2013-10-20 17:54:00 +00:00
$scope . status = 'ready' ;
2013-10-14 21:50:07 +00:00
} ;
2013-10-04 18:35:51 +00:00
function PlansCtrl ( $scope , UserService , PlanService ) {
$scope . plans = PlanService . planList ( ) ;
2013-10-02 22:14:51 +00:00
$scope . $watch ( function ( ) { return UserService . currentUser ( ) ; } , function ( currentUser ) {
$scope . user = currentUser ;
} , true ) ;
$scope . buyNow = function ( plan ) {
if ( $scope . user && ! $scope . user . anonymous ) {
2013-10-12 17:24:55 +00:00
document . location = '/user?plan=' + plan ;
2013-10-02 22:14:51 +00:00
} else {
$ ( '#signinModal' ) . modal ( { } ) ;
}
} ;
2013-10-11 03:42:03 +00:00
$scope . status = 'ready' ;
2013-10-02 22:14:51 +00:00
}
2013-10-11 00:53:14 +00:00
function GuideCtrl ( $scope ) {
$scope . status = 'ready' ;
2013-10-02 04:28:24 +00:00
}
2013-10-02 17:29:18 +00:00
function RepoListCtrl ( $scope , Restangular , UserService ) {
$scope . $watch ( function ( ) { return UserService . currentUser ( ) ; } , function ( currentUser ) {
$scope . user = currentUser ;
} , true ) ;
2013-09-30 23:08:24 +00:00
$scope . getCommentFirstLine = function ( commentString ) {
return getMarkedDown ( getFirstTextLine ( commentString ) ) ;
} ;
$scope . getMarkedDown = function ( string ) {
if ( ! string ) { return '' ; }
return getMarkedDown ( string ) ;
} ;
2013-10-01 20:42:20 +00:00
$scope . loading = true ;
2013-10-02 04:28:24 +00:00
$scope . public _repositories = null ;
$scope . private _repositories = null ;
// Load the list of personal repositories.
var repositoryPrivateFetch = Restangular . all ( 'repository/' ) ;
repositoryPrivateFetch . getList ( { 'public' : false , 'sort' : true } ) . then ( function ( resp ) {
$scope . private _repositories = resp . repositories ;
$scope . loading = ! ( $scope . public _repositories && $scope . private _repositories ) ;
} ) ;
2013-10-01 20:42:20 +00:00
2013-10-02 04:28:24 +00:00
// Load the list of public repositories.
var options = { 'public' : true , 'private' : false , 'sort' : true , 'limit' : 10 } ;
var repositoryPublicFetch = Restangular . all ( 'repository/' ) ;
repositoryPublicFetch . getList ( options ) . then ( function ( resp ) {
$scope . public _repositories = resp . repositories ;
$scope . loading = ! ( $scope . public _repositories && $scope . private _repositories ) ;
2013-10-01 20:42:20 +00:00
} ) ;
2013-09-24 22:21:14 +00:00
}
2013-10-10 18:42:14 +00:00
function LandingCtrl ( $scope , $timeout , Restangular , UserService , KeyService ) {
2013-10-01 23:37:33 +00:00
$ ( '.form-signup' ) . popover ( ) ;
2013-09-24 22:21:14 +00:00
2013-10-01 23:37:33 +00:00
$scope . $watch ( function ( ) { return UserService . currentUser ( ) ; } , function ( currentUser ) {
2013-10-02 04:28:24 +00:00
if ( ! currentUser . anonymous ) {
2013-10-08 15:36:45 +00:00
$scope . loadMyRepos ( ) ;
2013-10-02 04:28:24 +00:00
}
2013-10-01 23:37:33 +00:00
$scope . user = currentUser ;
} , true ) ;
2013-10-10 21:32:32 +00:00
angulartics . waitForVendorApi ( mixpanel , 500 , function ( loadedMixpanel ) {
var mixpanelId = loadedMixpanel . get _distinct _id ( ) ;
$scope . github _state _clause = '&state=' + mixpanelId ;
} ) ;
2013-10-10 18:42:14 +00:00
$scope . githubClientId = KeyService . githubClientId ;
2013-10-01 23:37:33 +00:00
$scope . awaitingConfirmation = false ;
2013-10-02 02:13:43 +00:00
$scope . registering = false ;
2013-10-02 04:28:24 +00:00
$scope . getCommentFirstLine = function ( commentString ) {
return getMarkedDown ( getFirstTextLine ( commentString ) ) ;
} ;
2013-10-02 02:28:39 +00:00
$scope . browseRepos = function ( ) {
2013-10-12 17:24:55 +00:00
document . location = '/repository/' ;
2013-10-02 02:28:39 +00:00
} ;
2013-10-01 23:37:33 +00:00
$scope . register = function ( ) {
2013-10-02 02:13:43 +00:00
$ ( '.form-signup' ) . popover ( 'hide' ) ;
$scope . registering = true ;
2013-10-01 23:37:33 +00:00
var newUserPost = Restangular . one ( 'user/' ) ;
newUserPost . customPOST ( $scope . newUser ) . then ( function ( ) {
$scope . awaitingConfirmation = true ;
2013-10-02 02:13:43 +00:00
$scope . registering = false ;
2013-10-08 15:50:34 +00:00
mixpanel . alias ( $scope . newUser . username ) ;
2013-10-01 23:37:33 +00:00
} , function ( result ) {
2013-10-02 02:13:43 +00:00
$scope . registering = false ;
2013-10-01 23:37:33 +00:00
$scope . registerError = result . data . message ;
$timeout ( function ( ) {
$ ( '.form-signup' ) . popover ( 'show' ) ;
} ) ;
} ) ;
} ;
2013-10-02 04:28:24 +00:00
$scope . loadMyRepos = function ( ) {
$scope . loadingmyrepos = true ;
// Load the list of repositories.
var params = {
'limit' : 5 ,
'public' : false ,
'sort' : true
} ;
var repositoryFetch = Restangular . all ( 'repository/' ) ;
repositoryFetch . getList ( params ) . then ( function ( resp ) {
$scope . myrepos = resp . repositories ;
$scope . loadingmyrepos = false ;
} ) ;
} ;
2013-10-11 00:53:14 +00:00
$scope . status = 'ready' ;
2013-10-12 01:28:02 +00:00
browserchrome . update ( ) ;
2013-09-24 22:21:14 +00:00
}
2013-09-26 21:59:20 +00:00
2013-10-17 21:59:34 +00:00
function RepoCtrl ( $scope , Restangular , $routeParams , $rootScope , $location , $timeout ) {
2013-09-26 21:59:20 +00:00
$rootScope . title = 'Loading...' ;
2013-09-27 21:01:45 +00:00
2013-10-17 03:09:43 +00:00
// Watch for changes to the tag parameter.
$scope . $on ( '$routeUpdate' , function ( ) {
$scope . setTag ( $location . search ( ) . tag , false ) ;
} ) ;
2013-09-26 21:59:20 +00:00
$scope . editDescription = function ( ) {
2013-09-26 23:07:25 +00:00
if ( ! $scope . repo . can _write ) { return ; }
2013-09-30 23:08:24 +00:00
if ( ! $scope . markdownDescriptionEditor ) {
2013-10-01 23:37:33 +00:00
var converter = Markdown . getSanitizingConverter ( ) ;
var editor = new Markdown . Editor ( converter , '-description' ) ;
editor . run ( ) ;
$scope . markdownDescriptionEditor = editor ;
2013-09-30 23:08:24 +00:00
}
$ ( '#wmd-input-description' ) [ 0 ] . value = $scope . repo . description ;
2013-09-26 23:07:25 +00:00
$ ( '#editModal' ) . modal ( { } ) ;
2013-09-26 21:59:20 +00:00
} ;
$scope . saveDescription = function ( ) {
2013-09-26 23:07:25 +00:00
$ ( '#editModal' ) . modal ( 'hide' ) ;
2013-09-30 23:08:24 +00:00
$scope . repo . description = $ ( '#wmd-input-description' ) [ 0 ] . value ;
2013-09-26 23:07:25 +00:00
$scope . repo . put ( ) ;
2013-09-27 19:26:30 +00:00
} ;
$scope . parseDate = function ( dateString ) {
return Date . parse ( dateString ) ;
} ;
2013-09-30 23:08:24 +00:00
$scope . getCommentFirstLine = function ( commentString ) {
return getMarkedDown ( getFirstTextLine ( commentString ) ) ;
} ;
2013-10-11 00:43:37 +00:00
$scope . getTimeSince = function ( createdTime ) {
2013-10-10 04:40:18 +00:00
return moment ( $scope . parseDate ( createdTime ) ) . fromNow ( ) ;
} ;
2013-09-30 23:08:24 +00:00
$scope . getMarkedDown = function ( string ) {
if ( ! string ) { return '' ; }
return getMarkedDown ( string ) ;
} ;
2013-10-17 02:37:29 +00:00
var getDefaultTag = function ( ) {
if ( $scope . repo === undefined ) {
return undefined ;
} else if ( $scope . repo . tags . hasOwnProperty ( 'latest' ) ) {
return $scope . repo . tags [ 'latest' ] ;
} else {
for ( key in $scope . repo . tags ) {
return $scope . repo . tags [ key ] ;
}
}
} ;
2013-10-17 18:29:47 +00:00
$scope . $watch ( 'repo' , function ( ) {
if ( $scope . tree ) {
2013-10-17 21:59:34 +00:00
$timeout ( function ( ) {
$scope . tree . notifyResized ( ) ;
} ) ;
2013-10-17 18:29:47 +00:00
}
} ) ;
2013-10-17 02:37:29 +00:00
var listImages = function ( ) {
2013-10-01 23:37:33 +00:00
if ( $scope . imageHistory ) { return ; }
2013-09-27 21:01:45 +00:00
2013-10-17 02:37:29 +00:00
var imageFetch = Restangular . one ( 'repository/' + namespace + '/' + name + '/image/' ) ;
2013-10-01 23:37:33 +00:00
imageFetch . get ( ) . then ( function ( resp ) {
$scope . imageHistory = resp . images ;
2013-10-17 02:33:35 +00:00
$scope . tree = new ImageHistoryTree ( namespace , name , resp . images ,
2013-10-11 00:43:37 +00:00
$scope . getCommentFirstLine , $scope . getTimeSince ) ;
$scope . tree . draw ( 'image-history-container' ) ;
2013-10-17 02:49:37 +00:00
2013-10-17 02:44:44 +00:00
// If we already have a tag, use it
if ( $scope . currentTag ) {
$scope . tree . setTag ( $scope . currentTag . name ) ;
}
2013-10-11 00:43:37 +00:00
$ ( $scope . tree ) . bind ( 'tagChanged' , function ( e ) {
2013-10-17 03:09:43 +00:00
$scope . $apply ( function ( ) { $scope . setTag ( e . tag , true ) ; } ) ;
2013-10-11 00:43:37 +00:00
} ) ;
$ ( $scope . tree ) . bind ( 'imageChanged' , function ( e ) {
$scope . $apply ( function ( ) { $scope . setImage ( e . image ) ; } ) ;
} ) ;
2013-10-01 23:37:33 +00:00
} ) ;
2013-09-27 21:01:45 +00:00
} ;
2013-09-26 21:59:20 +00:00
2013-10-18 21:59:26 +00:00
$scope . loadImageChanges = function ( image ) {
$scope . currentImageChanges = null ;
var changesFetch = Restangular . one ( 'repository/' + namespace + '/' + name + '/image/' + image . id + '/changes' ) ;
changesFetch . get ( ) . then ( function ( changeInfo ) {
$scope . currentImageChanges = changeInfo ;
} , function ( ) {
$scope . currentImageChanges = { } ;
} ) ;
} ;
$scope . getMoreCount = function ( changes ) {
if ( ! changes ) { return 0 ; }
2013-10-19 00:23:41 +00:00
var addedDisplayed = Math . min ( 5 , changes . added . length ) ;
var removedDisplayed = Math . min ( 5 , changes . removed . length ) ;
var changedDisplayed = Math . min ( 5 , changes . changed . length ) ;
2013-10-18 21:59:26 +00:00
return ( changes . added . length + changes . removed . length + changes . changed . length ) -
addedDisplayed - removedDisplayed - changedDisplayed ;
} ;
2013-10-11 00:43:37 +00:00
$scope . setImage = function ( image ) {
$scope . currentImage = image ;
2013-10-18 21:59:26 +00:00
$scope . loadImageChanges ( image ) ;
2013-10-11 00:43:37 +00:00
if ( $scope . tree ) {
$scope . tree . setImage ( $scope . currentImage . id ) ;
}
} ;
2013-10-17 03:09:43 +00:00
$scope . setTag = function ( tagName , opt _updateURL ) {
2013-10-11 00:43:37 +00:00
var repo = $scope . repo ;
2013-10-17 02:37:29 +00:00
var proposedTag = repo . tags [ tagName ] ;
if ( ! proposedTag ) {
// We must find a good default
for ( tagName in repo . tags ) {
if ( ! proposedTag || tagName == 'latest' ) {
proposedTag = repo . tags [ tagName ] ;
}
}
2013-10-17 03:09:43 +00:00
}
2013-10-17 02:37:29 +00:00
if ( proposedTag ) {
2013-10-17 02:44:44 +00:00
$scope . currentTag = proposedTag ;
2013-10-17 02:37:29 +00:00
$scope . currentImage = $scope . currentTag . image ;
2013-10-18 21:59:26 +00:00
$scope . loadImageChanges ( $scope . currentImage ) ;
2013-10-17 02:37:29 +00:00
if ( $scope . tree ) {
$scope . tree . setTag ( $scope . currentTag . name ) ;
2013-10-17 03:12:00 +00:00
}
if ( opt _updateURL ) {
$location . search ( 'tag' , $scope . currentTag . name ) ;
}
2013-10-11 00:43:37 +00:00
}
} ;
2013-10-02 05:05:36 +00:00
$scope . getTagCount = function ( repo ) {
if ( ! repo ) { return 0 ; }
var count = 0 ;
for ( var tag in repo . tags ) {
++ count ;
}
return count ;
} ;
2013-09-26 21:59:20 +00:00
var namespace = $routeParams . namespace ;
var name = $routeParams . name ;
2013-10-01 20:42:20 +00:00
$scope . loading = true ;
2013-10-11 00:43:37 +00:00
// Fetch the repo.
2013-09-26 21:59:20 +00:00
var repositoryFetch = Restangular . one ( 'repository/' + namespace + '/' + name ) ;
repositoryFetch . get ( ) . then ( function ( repo ) {
2013-09-26 23:07:25 +00:00
$rootScope . title = namespace + '/' + name ;
$scope . repo = repo ;
2013-10-17 02:37:29 +00:00
$scope . setTag ( $routeParams . tag ) ;
2013-09-27 20:12:51 +00:00
2013-10-17 18:46:23 +00:00
$ ( '#copyClipboard' ) . clipboardCopy ( ) ;
2013-10-01 20:42:20 +00:00
$scope . loading = false ;
2013-09-26 21:59:20 +00:00
} , function ( ) {
2013-09-26 23:07:25 +00:00
$scope . repo = null ;
2013-10-01 20:42:20 +00:00
$scope . loading = false ;
2013-09-26 23:07:25 +00:00
$rootScope . title = 'Unknown Repository' ;
2013-09-26 21:59:20 +00:00
} ) ;
2013-10-11 00:43:37 +00:00
// Fetch the image history.
2013-10-17 02:37:29 +00:00
listImages ( ) ;
2013-09-26 23:59:58 +00:00
}
2013-09-27 00:34:58 +00:00
2013-09-27 19:26:16 +00:00
function RepoAdminCtrl ( $scope , Restangular , $routeParams , $rootScope ) {
2013-10-17 18:46:23 +00:00
$ ( '.info-icon' ) . popover ( {
'trigger' : 'hover' ,
'html' : true
} ) ;
$ ( '#copyClipboard' ) . clipboardCopy ( ) ;
2013-09-27 19:26:16 +00:00
var namespace = $routeParams . namespace ;
var name = $routeParams . name ;
2013-10-14 21:50:07 +00:00
$scope . $on ( '$viewContentLoaded' , function ( ) {
// THIS IS BAD, MOVE THIS TO A DIRECTIVE
$ ( '#userSearch' ) . typeahead ( {
name : 'users' ,
remote : {
url : '/api/users/%QUERY' ,
filter : function ( data ) {
var datums = [ ] ;
for ( var i = 0 ; i < data . users . length ; ++ i ) {
var user = data . users [ i ] ;
datums . push ( {
'value' : user ,
'tokens' : [ user ] ,
'username' : user
} ) ;
}
return datums ;
2013-10-01 23:37:33 +00:00
}
2013-10-14 21:50:07 +00:00
} ,
template : function ( datum ) {
template = '<div class="user-mini-listing">' ;
template += '<i class="icon-user icon-large"></i>'
template += '<span class="name">' + datum . username + '</span>'
template += '</div>'
return template ;
} ,
} ) ;
2013-09-28 05:23:00 +00:00
2013-10-14 21:50:07 +00:00
$ ( '#userSearch' ) . on ( 'typeahead:selected' , function ( e , datum ) {
$ ( '#userSearch' ) . typeahead ( 'setQuery' , '' ) ;
$scope . addNewPermission ( datum . username ) ;
} ) ;
2013-09-28 05:23:00 +00:00
} ) ;
$scope . addNewPermission = function ( username ) {
// Don't allow duplicates.
if ( $scope . permissions [ username ] ) { return ; }
// Need the $scope.apply for both the permission stuff to change and for
// the XHR call to be made.
$scope . $apply ( function ( ) {
2013-10-01 23:37:33 +00:00
$scope . addRole ( username , 'read' )
2013-09-28 05:23:00 +00:00
} ) ;
} ;
$scope . deleteRole = function ( username ) {
var permissionDelete = Restangular . one ( 'repository/' + namespace + '/' + name + '/permissions/' + username ) ;
permissionDelete . customDELETE ( ) . then ( function ( ) {
2013-10-01 23:37:33 +00:00
delete $scope . permissions [ username ] ;
2013-09-28 05:23:00 +00:00
} , function ( result ) {
2013-10-01 23:37:33 +00:00
if ( result . status == 409 ) {
$ ( '#onlyadminModal' ) . modal ( { } ) ;
} else {
$ ( '#cannotchangeModal' ) . modal ( { } ) ;
}
2013-09-28 05:23:00 +00:00
} ) ;
} ;
$scope . addRole = function ( username , role ) {
var permission = {
2013-10-01 23:37:33 +00:00
'role' : role
2013-09-28 05:23:00 +00:00
} ;
var permissionPost = Restangular . one ( 'repository/' + namespace + '/' + name + '/permissions/' + username ) ;
permissionPost . customPOST ( permission ) . then ( function ( ) {
2013-10-01 23:37:33 +00:00
$scope . permissions [ username ] = permission ;
$scope . permissions = $scope . permissions ;
2013-09-28 05:23:00 +00:00
} , function ( result ) {
2013-10-01 23:37:33 +00:00
$ ( '#cannotchangeModal' ) . modal ( { } ) ;
2013-09-28 05:23:00 +00:00
} ) ;
} ;
2013-09-27 19:26:16 +00:00
$scope . setRole = function ( username , role ) {
var permission = $scope . permissions [ username ] ;
2013-09-28 05:23:00 +00:00
var currentRole = permission . role ;
2013-09-27 19:26:16 +00:00
permission . role = role ;
2013-09-28 05:23:00 +00:00
2013-09-27 19:26:16 +00:00
var permissionPut = Restangular . one ( 'repository/' + namespace + '/' + name + '/permissions/' + username ) ;
2013-09-27 19:48:54 +00:00
permissionPut . customPUT ( permission ) . then ( function ( ) { } , function ( result ) {
2013-10-01 23:37:33 +00:00
if ( result . status == 409 ) {
permission . role = currentRole ;
$ ( '#onlyadminModal' ) . modal ( { } ) ;
} else {
$ ( '#cannotchangeModal' ) . modal ( { } ) ;
}
2013-09-27 19:48:54 +00:00
} ) ;
2013-09-27 19:26:16 +00:00
} ;
2013-10-16 18:24:10 +00:00
$scope . createToken = function ( ) {
var friendlyName = {
'friendlyName' : $scope . newToken . friendlyName
} ;
var permissionPost = Restangular . one ( 'repository/' + namespace + '/' + name + '/tokens/' ) ;
permissionPost . customPOST ( friendlyName ) . then ( function ( newToken ) {
2013-10-17 20:50:58 +00:00
$scope . newToken . friendlyName = '' ;
$scope . createTokenForm . $setPristine ( ) ;
2013-10-16 18:24:10 +00:00
$scope . tokens [ newToken . code ] = newToken ;
} ) ;
} ;
$scope . deleteToken = function ( tokenCode ) {
var deleteAction = Restangular . one ( 'repository/' + namespace + '/' + name + '/tokens/' + tokenCode ) ;
deleteAction . customDELETE ( ) . then ( function ( ) {
delete $scope . tokens [ tokenCode ] ;
} ) ;
} ;
$scope . changeTokenAccess = function ( tokenCode , newAccess ) {
var role = {
'role' : newAccess
} ;
var deleteAction = Restangular . one ( 'repository/' + namespace + '/' + name + '/tokens/' + tokenCode ) ;
deleteAction . customPUT ( role ) . then ( function ( updated ) {
$scope . tokens [ updated . code ] = updated ;
} ) ;
} ;
$scope . showToken = function ( tokenCode ) {
$scope . shownToken = $scope . tokens [ tokenCode ] ;
$ ( '#tokenmodal' ) . modal ( { } ) ;
} ;
2013-09-28 21:11:10 +00:00
$scope . askChangeAccess = function ( newAccess ) {
2013-10-01 23:37:33 +00:00
$ ( '#make' + newAccess + 'Modal' ) . modal ( { } ) ;
2013-09-28 21:11:10 +00:00
} ;
$scope . changeAccess = function ( newAccess ) {
2013-10-01 23:37:33 +00:00
$ ( '#make' + newAccess + 'Modal' ) . modal ( 'hide' ) ;
var visibility = {
'visibility' : newAccess
} ;
var visibilityPost = Restangular . one ( 'repository/' + namespace + '/' + name + '/changevisibility' ) ;
visibilityPost . customPOST ( visibility ) . then ( function ( ) {
$scope . repo . is _public = newAccess == 'public' ;
} , function ( ) {
$ ( '#cannotchangeModal' ) . modal ( { } ) ;
} ) ;
2013-09-28 21:11:10 +00:00
} ;
2013-10-01 18:14:30 +00:00
$scope . askDelete = function ( ) {
2013-10-01 23:37:33 +00:00
$ ( '#confirmdeleteModal' ) . modal ( { } ) ;
2013-10-01 18:14:30 +00:00
} ;
$scope . deleteRepo = function ( ) {
2013-10-01 23:37:33 +00:00
$ ( '#confirmdeleteModal' ) . modal ( 'hide' ) ;
var deleteAction = Restangular . one ( 'repository/' + namespace + '/' + name ) ;
deleteAction . customDELETE ( ) . then ( function ( ) {
$scope . repo = null ;
setTimeout ( function ( ) {
2013-10-12 17:24:55 +00:00
document . location = '/repository/' ;
2013-10-01 23:37:33 +00:00
} , 1000 ) ;
} , function ( ) {
$ ( '#cannotchangeModal' ) . modal ( { } ) ;
} ) ;
2013-10-01 18:14:30 +00:00
} ;
2013-10-02 05:05:36 +00:00
2013-10-01 20:42:20 +00:00
$scope . loading = true ;
2013-10-01 18:14:30 +00:00
2013-09-28 21:11:10 +00:00
// Fetch the repository information.
var repositoryFetch = Restangular . one ( 'repository/' + namespace + '/' + name ) ;
repositoryFetch . get ( ) . then ( function ( repo ) {
$scope . repo = repo ;
2013-10-16 18:24:10 +00:00
$scope . loading = ! ( $scope . permissions && $scope . repo && $scope . tokens ) ;
2013-10-01 20:42:20 +00:00
} , function ( ) {
$scope . permissions = null ;
$rootScope . title = 'Unknown Repository' ;
$scope . loading = false ;
2013-09-28 21:11:10 +00:00
} ) ;
// Fetch the permissions.
2013-09-27 19:26:16 +00:00
var permissionsFetch = Restangular . one ( 'repository/' + namespace + '/' + name + '/permissions' ) ;
permissionsFetch . get ( ) . then ( function ( resp ) {
2013-09-28 05:23:00 +00:00
$rootScope . title = 'Settings - ' + namespace + '/' + name ;
2013-09-27 19:26:16 +00:00
$scope . permissions = resp . permissions ;
2013-10-16 18:24:10 +00:00
$scope . loading = ! ( $scope . permissions && $scope . repo && $scope . tokens ) ;
2013-09-27 19:26:16 +00:00
} , function ( ) {
$scope . permissions = null ;
$rootScope . title = 'Unknown Repository' ;
2013-10-01 20:42:20 +00:00
$scope . loading = false ;
2013-09-27 19:26:16 +00:00
} ) ;
2013-10-16 18:24:10 +00:00
// Fetch the tokens.
var tokensFetch = Restangular . one ( 'repository/' + namespace + '/' + name + '/tokens/' ) ;
tokensFetch . get ( ) . then ( function ( resp ) {
$scope . tokens = resp . tokens ;
$scope . loading = ! ( $scope . permissions && $scope . repo && $scope . tokens ) ;
} , function ( ) {
$scope . tokens = null ;
$scope . loading = false ;
} ) ;
2013-10-02 04:48:03 +00:00
}
2013-10-10 17:44:34 +00:00
function UserAdminCtrl ( $scope , $timeout , Restangular , PlanService , UserService , KeyService , $routeParams ) {
2013-10-04 18:35:51 +00:00
$scope . plans = PlanService . planList ( ) ;
2013-10-02 04:48:03 +00:00
2013-10-10 17:44:34 +00:00
$scope . $watch ( function ( ) { return UserService . currentUser ( ) ; } , function ( currentUser ) {
$scope . askForPassword = currentUser . askForPassword ;
} , true ) ;
2013-10-02 05:40:11 +00:00
var subscribedToPlan = function ( sub ) {
2013-10-02 04:48:03 +00:00
$scope . subscription = sub ;
2013-10-04 18:35:51 +00:00
$scope . subscribedPlan = PlanService . getPlan ( sub . plan ) ;
2013-10-02 05:40:11 +00:00
$scope . planUsagePercent = sub . usedPrivateRepos * 100 / $scope . subscribedPlan . privateRepos ;
2013-10-04 18:35:51 +00:00
if ( sub . usedPrivateRepos > $scope . subscribedPlan . privateRepos ) {
$scope . errorMessage = 'You are using more private repositories than your plan allows, please upgrate your subscription to avoid disruptions in your service.' ;
}
2013-10-02 05:40:11 +00:00
$scope . planLoading = false ;
2013-10-02 06:05:53 +00:00
$scope . planChanging = false ;
2013-10-08 17:57:48 +00:00
mixpanel . people . set ( {
'plan' : sub . plan
} ) ;
2013-10-02 05:40:11 +00:00
}
$scope . planLoading = true ;
var getSubscription = Restangular . one ( 'user/plan' ) ;
getSubscription . get ( ) . then ( subscribedToPlan , function ( ) {
// User has no subscription
$scope . planLoading = false ;
2013-10-02 04:48:03 +00:00
} ) ;
2013-10-02 06:05:53 +00:00
$scope . planChanging = false ;
2013-10-02 04:48:03 +00:00
$scope . subscribe = function ( planId ) {
var submitToken = function ( token ) {
$scope . $apply ( function ( ) {
2013-10-08 17:57:48 +00:00
mixpanel . track ( 'plan_subscribe' ) ;
2013-10-02 06:05:53 +00:00
$scope . planChanging = true ;
$scope . errorMessage = undefined ;
2013-10-02 04:48:03 +00:00
var subscriptionDetails = {
token : token . id ,
plan : planId ,
} ;
var createSubscriptionRequest = Restangular . one ( 'user/plan' ) ;
2013-10-02 05:40:11 +00:00
createSubscriptionRequest . customPUT ( subscriptionDetails ) . then ( subscribedToPlan , function ( ) {
2013-10-02 04:48:03 +00:00
// Failure
2013-10-02 06:05:53 +00:00
$scope . errorMessage = 'Unable to subscribe.' ;
2013-10-02 04:48:03 +00:00
} ) ;
} ) ;
} ;
2013-10-04 18:35:51 +00:00
var planDetails = PlanService . getPlan ( planId )
2013-10-02 04:48:03 +00:00
StripeCheckout . open ( {
2013-10-08 17:57:48 +00:00
key : KeyService . stripePublishableKey ,
2013-10-02 04:48:03 +00:00
address : false , // TODO change to true
amount : planDetails . price ,
currency : 'usd' ,
name : 'Quay ' + planDetails . title + ' Subscription' ,
description : 'Up to ' + planDetails . privateRepos + ' private repositories' ,
panelLabel : 'Subscribe' ,
token : submitToken
} ) ;
} ;
2013-10-02 06:05:53 +00:00
$scope . changeSubscription = function ( planId ) {
$scope . planChanging = true ;
$scope . errorMessage = undefined ;
var subscriptionDetails = {
plan : planId ,
} ;
var changeSubscriptionRequest = Restangular . one ( 'user/plan' ) ;
changeSubscriptionRequest . customPUT ( subscriptionDetails ) . then ( subscribedToPlan , function ( ) {
// Failure
$scope . errorMessage = 'Unable to change subscription.' ;
$scope . planChanging = false ;
} ) ;
} ;
$scope . cancelSubscription = function ( ) {
2013-10-04 18:35:51 +00:00
$scope . changeSubscription ( 'free' ) ;
2013-10-02 06:05:53 +00:00
} ;
2013-10-02 22:14:51 +00:00
// Show the subscribe dialog if a plan was requested.
2013-10-04 18:35:51 +00:00
var requested = $routeParams [ 'plan' ]
if ( requested !== undefined && requested !== 'free' ) {
if ( PlanService . getPlan ( requested ) !== undefined ) {
$scope . subscribe ( requested ) ;
}
2013-10-02 22:14:51 +00:00
}
2013-10-10 17:44:34 +00:00
$scope . updatingUser = false ;
$scope . changePasswordSuccess = false ;
$ ( '.form-change-pw' ) . popover ( ) ;
$scope . changePassword = function ( ) {
$ ( '.form-change-pw' ) . popover ( 'hide' ) ;
$scope . updatingUser = true ;
$scope . changePasswordSuccess = false ;
var changePasswordPost = Restangular . one ( 'user/' ) ;
changePasswordPost . customPUT ( $scope . user ) . then ( function ( ) {
$scope . updatingUser = false ;
$scope . changePasswordSuccess = true ;
2013-10-10 18:02:28 +00:00
// Reset the form
$scope . user . password = '' ;
$scope . user . repeatPassword = '' ;
$scope . changePasswordForm . $setPristine ( ) ;
2013-10-10 17:44:34 +00:00
UserService . load ( ) ;
} , function ( result ) {
$scope . updatingUser = false ;
$scope . changePasswordError = result . data . message ;
$timeout ( function ( ) {
$ ( '.form-change-pw' ) . popover ( 'show' ) ;
} ) ;
} ) ;
} ;
2013-10-17 21:45:08 +00:00
}
2013-10-19 02:28:46 +00:00
function ImageViewCtrl ( $scope , $routeParams , $rootScope , Restangular ) {
var namespace = $routeParams . namespace ;
var name = $routeParams . name ;
var imageid = $routeParams . image ;
$ ( '#copyClipboard' ) . clipboardCopy ( ) ;
$scope . getMarkedDown = function ( string ) {
if ( ! string ) { return '' ; }
return getMarkedDown ( string ) ;
} ;
$scope . parseDate = function ( dateString ) {
return Date . parse ( dateString ) ;
} ;
$scope . getFolder = function ( filepath ) {
var index = filepath . lastIndexOf ( '/' ) ;
if ( index < 0 ) {
return '' ;
}
return filepath . substr ( 0 , index + 1 ) ;
} ;
$scope . getFolders = function ( filepath ) {
var index = filepath . lastIndexOf ( '/' ) ;
if ( index < 0 ) {
return '' ;
}
return filepath . substr ( 0 , index ) . split ( '/' ) ;
} ;
$scope . getFilename = function ( filepath ) {
var index = filepath . lastIndexOf ( '/' ) ;
if ( index < 0 ) {
return filepath ;
}
return filepath . substr ( index + 1 ) ;
} ;
$scope . setFolderFilter = function ( folderPath , index ) {
var parts = folderPath . split ( '/' ) ;
parts = parts . slice ( 0 , index + 1 ) ;
$scope . setFilter ( parts . join ( '/' ) ) ;
} ;
$scope . setFilter = function ( filter ) {
$scope . search = { } ;
$scope . search [ '$' ] = filter ;
document . getElementById ( 'change-filter' ) . value = filter ;
} ;
2013-10-19 23:46:30 +00:00
$scope . initializeTree = function ( ) {
if ( $scope . tree ) { return ; }
$scope . tree = new ImageFileChangeTree ( $scope . image , $scope . combinedChanges ) ;
setTimeout ( function ( ) {
$scope . tree . draw ( 'changes-tree-container' ) ;
} , 10 ) ;
} ;
2013-10-19 02:28:46 +00:00
// Fetch the image.
var imageFetch = Restangular . one ( 'repository/' + namespace + '/' + name + '/image/' + imageid ) ;
imageFetch . get ( ) . then ( function ( image ) {
$scope . loading = false ;
$scope . repo = {
'name' : name ,
'namespace' : namespace
} ;
$scope . image = image ;
$rootScope . title = 'View Image - ' + image . id ;
} , function ( ) {
$rootScope . title = 'Unknown Image' ;
$scope . loading = false ;
} ) ;
// Fetch the image changes.
var changesFetch = Restangular . one ( 'repository/' + namespace + '/' + name + '/image/' + imageid + '/changes' ) ;
changesFetch . get ( ) . then ( function ( changes ) {
var combinedChanges = [ ] ;
var addCombinedChanges = function ( c , kind ) {
for ( var i = 0 ; i < c . length ; ++ i ) {
combinedChanges . push ( {
'kind' : kind ,
'file' : c [ i ]
} ) ;
}
} ;
addCombinedChanges ( changes . added , 'added' ) ;
addCombinedChanges ( changes . removed , 'removed' ) ;
addCombinedChanges ( changes . changed , 'changed' ) ;
$scope . combinedChanges = combinedChanges ;
$scope . imageChanges = changes ;
} ) ;
}
2013-10-17 21:45:08 +00:00
function V1Ctrl ( $scope , UserService ) {
$scope . $watch ( function ( ) { return UserService . currentUser ( ) ; } , function ( currentUser ) {
$scope . user = currentUser ;
} , true ) ;
$scope . browseRepos = function ( ) {
document . location = '/repository/' ;
} ;
2013-09-27 00:34:58 +00:00
}