Redo html layout and add styling to import page

api-v2-docs
Anthony Johnson 2015-09-18 17:17:32 -07:00
parent 6174067e23
commit 6141c79832
10 changed files with 307 additions and 127 deletions

View File

@ -40,7 +40,10 @@ var sources = {
'font/fontawesome-webfont.woff': {src: 'bower_components/font-awesome/fonts/fontawesome-webfont.woff'},
'font/FontAwesome.otf': {src: 'bower_components/font-awesome/fonts/FontAwesome.otf'}
},
projects: {'js/tools.js': {}},
projects: {
'js/tools.js': {},
'css/import.less': {},
},
gold: {'js/gold.js': {}},
donate: {'js/donate.js': {}}
};

View File

@ -61,25 +61,16 @@ function Organization (instance) {
var self = this;
self.id = ko.observable(instance.id);
self.name = ko.observable(instance.name);
self.login = ko.observable(instance.login);
self.slug = ko.observable(instance.slug);
self.active = ko.observable(instance.active);
self.avatar_url = ko.observable(
append_url_params(instance.avatar_url, {size: 32})
);
self.display_name = ko.computed(function () {
return self.name() || self.login();
return self.name() || self.slug();
});
}
function Owner (instance) {
var self = this;
self.name = ko.observable(instance.name);
self.avatar_url = ko.observable(
append_url_params(instance.avatar_url, {size: 32})
);
self.login = ko.observable(instance.login);
}
function Project (instance) {
var self = this;
self.id = ko.observable(instance.id);
@ -89,10 +80,18 @@ function Project (instance) {
if (instance.organization) {
self.organization(new Organization(instance.organization));
}
self.owner = ko.observable(new Owner(instance.owner));
self.url = ko.observable(instance.url);
self.http_url = ko.observable(instance.http_url);
self.clone_url = ko.observable(instance.clone_url);
self.ssh_url = ko.observable(instance.ssh_url);
self.private = ko.observable(instance.private);
self.active = ko.observable(instance.active);
self.avatar_url = ko.observable(
append_url_params(instance.avatar_url, {size: 32})
);
self.import_repo = function () {
alert('FUCK');
};
}
function ProjectImportView (instance, urls) {
@ -128,7 +127,7 @@ function ProjectImportView (instance, urls) {
ko.computed(function () {
var org = self.filter_org(),
orgs = self.organizations(),
url = self.page_current() || self.urls['githubproject-list'];
url = self.page_current() || self.urls['oauthrepository-list'];
if (org) {
url = append_url_params(url, {org: org});
@ -153,7 +152,7 @@ function ProjectImportView (instance, urls) {
});
self.get_organizations = function () {
$.getJSON(self.urls['githuborganization-list'])
$.getJSON(self.urls['oauthorganization-list'])
.success(function (organizations) {
self.organizations_raw(organizations.results);
})

View File

@ -1 +1 @@
require=function e(r,n,t){function o(i,s){if(!n[i]){if(!r[i]){var u="function"==typeof require&&require;if(!s&&u)return u(i,!0);if(a)return a(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[i]={exports:{}};r[i][0].call(l.exports,function(e){var n=r[i][1][e];return o(n?n:e)},l,l.exports,e,r,n,t)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}({1:[function(e,r,n){function t(e){return/^(GET|HEAD|OPTIONS|TRACE)$/.test(e)}$.ajaxSetup({beforeSend:function(e,r){function n(e){var r=null;if(document.cookie&&""!=document.cookie)for(var n=document.cookie.split(";"),t=0;t<n.length;t++){var o=jQuery.trim(n[t]);if(o.substring(0,e.length+1)==e+"="){r=decodeURIComponent(o.substring(e.length+1));break}}return r}if(!t(r.type)&&!this.crossDomain){var o=n("csrftoken");e.setRequestHeader("X-CSRFToken",o)}}})},{}],2:[function(e,r,n){function t(e){function r(){a.getJSON(e.url).success(function(e){e.finished?e.success?n.resolve():n.reject(e.error||"Error"):setTimeout(r,2e3)}).error(function(e){console.error("Error polling task:",e),setTimeout(r,2e3)})}var n=a.Deferred();return setTimeout(r,2e3),n}function o(e){var r=a.Deferred();return $.ajax({method:"POST",url:e,success:function(e){t(e).then(function(){r.resolve()}).fail(function(e){r.reject(e)})},error:function(e){r.reject(e)}}),r}var a=e("jquery");r.exports={poll_task:t,trigger_task:o}},{jquery:"jquery"}],"core/projectimport":[function(e,r,t){function o(e){var r=this;r.id=c.observable(e.id),r.name=c.observable(e.name),r.login=c.observable(e.login),r.active=c.observable(e.active),r.avatar_url=c.observable(u(e.avatar_url,{size:32})),r.display_name=c.computed(function(){return r.name()||r.login()})}function a(e){var r=this;r.name=c.observable(e.name),r.avatar_url=c.observable(u(e.avatar_url,{size:32})),r.login=c.observable(e.login)}function i(e){var r=this;r.id=c.observable(e.id),r.name=c.observable(e.name),r.full_name=c.observable(e.full_name),r.organization=c.observable(),e.organization&&r.organization(new o(e.organization)),r.owner=c.observable(new a(e.owner)),r.url=c.observable(e.url),r["private"]=c.observable(e["private"]),r.active=c.observable(e.active)}function s(e,r){var t=this;t.urls=r||{},t.error=c.observable(null),t.is_syncing=c.observable(!1),t.page_count=c.observable(null),t.page_current=c.observable(null),t.page_next=c.observable(null),t.page_previous=c.observable(null),t.filter_org=c.observable(null),t.organizations_raw=c.observableArray(),t.organizations=c.computed(function(){var e=[],r=t.organizations_raw();for(n in r){var a=new o(r[n]);e.push(a)}return e}),t.projects=c.observableArray(),c.computed(function(){var e=t.filter_org(),r=(t.organizations(),t.page_current()||t.urls["githubproject-list"]);e&&(r=u(r,{org:e})),l.getJSON(r).success(function(e){var r=[];t.page_next(e.next),t.page_previous(e.previous);for(n in e.results){var o=new i(e.results[n]);r.push(o)}t.projects(r)}).error(function(e){t.error(e)})}),t.get_organizations=function(){l.getJSON(t.urls["githuborganization-list"]).success(function(e){t.organizations_raw(e.results)}).error(function(e){t.error(e)})},t.sync_projects=function(){var e=t.urls.api_sync_github_repositories;t.error(null),t.is_syncing(!0),f.trigger_task(e).then(function(e){t.get_organizations()}).fail(function(e){e=e||"An error occured",t.error(e)}).always(function(){t.is_syncing(!1)})},t.next_page=function(){t.page_current(t.page_next())},t.previous_page=function(){t.page_current(t.page_previous())}}function u(e,r){var n=l("<a>").attr("href",e).get(0);return Object.keys(r).map(function(e){n.search&&(n.search+="&"),n.search+=e+"="+r[e]}),n.href}var c=e("knockout"),l=e("jquery"),f=e("./tasks");e("./django-csrf.js"),l(function(){var e=l("#id_repo"),r=l("#id_repo_type");e.blur(function(){var n,t=e.val();switch(!0){case/^hg/.test(t):n="hg";break;case/^bzr/.test(t):case/launchpad/.test(t):n="bzr";break;case/trunk/.test(t):case/^svn/.test(t):n="svn";break;default:case/github/.test(t):case/(^git|\.git$)/.test(t):n="git"}r.val(n)}),l("[data-sync-repositories]").each(function(){})}),s.init=function(e,r,n){var t=new s(r,n);return t.get_organizations(),c.applyBindings(t,e),t},r.exports.ProjectImportView=s},{"./django-csrf.js":1,"./tasks":2,jquery:"jquery",knockout:"knockout"}]},{},[]);
require=function e(r,n,t){function o(i,s){if(!n[i]){if(!r[i]){var u="function"==typeof require&&require;if(!s&&u)return u(i,!0);if(a)return a(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[i]={exports:{}};r[i][0].call(l.exports,function(e){var n=r[i][1][e];return o(n?n:e)},l,l.exports,e,r,n,t)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}({1:[function(e,r,n){function t(e){return/^(GET|HEAD|OPTIONS|TRACE)$/.test(e)}$.ajaxSetup({beforeSend:function(e,r){function n(e){var r=null;if(document.cookie&&""!=document.cookie)for(var n=document.cookie.split(";"),t=0;t<n.length;t++){var o=jQuery.trim(n[t]);if(o.substring(0,e.length+1)==e+"="){r=decodeURIComponent(o.substring(e.length+1));break}}return r}if(!t(r.type)&&!this.crossDomain){var o=n("csrftoken");e.setRequestHeader("X-CSRFToken",o)}}})},{}],2:[function(e,r,n){function t(e){function r(){a.getJSON(e.url).success(function(e){e.finished?e.success?n.resolve():n.reject(e.error||"Error"):setTimeout(r,2e3)}).error(function(e){console.error("Error polling task:",e),setTimeout(r,2e3)})}var n=a.Deferred();return setTimeout(r,2e3),n}function o(e){var r=a.Deferred();return $.ajax({method:"POST",url:e,success:function(e){t(e).then(function(){r.resolve()}).fail(function(e){r.reject(e)})},error:function(e){r.reject(e)}}),r}var a=e("jquery");r.exports={poll_task:t,trigger_task:o}},{jquery:"jquery"}],"core/projectimport":[function(e,r,t){function o(e){var r=this;r.id=u.observable(e.id),r.name=u.observable(e.name),r.slug=u.observable(e.slug),r.active=u.observable(e.active),r.avatar_url=u.observable(s(e.avatar_url,{size:32})),r.display_name=u.computed(function(){return r.name()||r.slug()})}function a(e){var r=this;r.id=u.observable(e.id),r.name=u.observable(e.name),r.full_name=u.observable(e.full_name),r.organization=u.observable(),e.organization&&r.organization(new o(e.organization)),r.http_url=u.observable(e.http_url),r.clone_url=u.observable(e.clone_url),r.ssh_url=u.observable(e.ssh_url),r["private"]=u.observable(e["private"]),r.active=u.observable(e.active),r.avatar_url=u.observable(s(e.avatar_url,{size:32})),r.import_repo=function(){alert("FUCK")}}function i(e,r){var t=this;t.urls=r||{},t.error=u.observable(null),t.is_syncing=u.observable(!1),t.page_count=u.observable(null),t.page_current=u.observable(null),t.page_next=u.observable(null),t.page_previous=u.observable(null),t.filter_org=u.observable(null),t.organizations_raw=u.observableArray(),t.organizations=u.computed(function(){var e=[],r=t.organizations_raw();for(n in r){var a=new o(r[n]);e.push(a)}return e}),t.projects=u.observableArray(),u.computed(function(){var e=t.filter_org(),r=(t.organizations(),t.page_current()||t.urls["oauthrepository-list"]);e&&(r=s(r,{org:e})),c.getJSON(r).success(function(e){var r=[];t.page_next(e.next),t.page_previous(e.previous);for(n in e.results){var o=new a(e.results[n]);r.push(o)}t.projects(r)}).error(function(e){t.error(e)})}),t.get_organizations=function(){c.getJSON(t.urls["oauthorganization-list"]).success(function(e){t.organizations_raw(e.results)}).error(function(e){t.error(e)})},t.sync_projects=function(){var e=t.urls.api_sync_github_repositories;t.error(null),t.is_syncing(!0),l.trigger_task(e).then(function(e){t.get_organizations()}).fail(function(e){e=e||"An error occured",t.error(e)}).always(function(){t.is_syncing(!1)})},t.next_page=function(){t.page_current(t.page_next())},t.previous_page=function(){t.page_current(t.page_previous())}}function s(e,r){var n=c("<a>").attr("href",e).get(0);return Object.keys(r).map(function(e){n.search&&(n.search+="&"),n.search+=e+"="+r[e]}),n.href}var u=e("knockout"),c=e("jquery"),l=e("./tasks");e("./django-csrf.js"),c(function(){var e=c("#id_repo"),r=c("#id_repo_type");e.blur(function(){var n,t=e.val();switch(!0){case/^hg/.test(t):n="hg";break;case/^bzr/.test(t):case/launchpad/.test(t):n="bzr";break;case/trunk/.test(t):case/^svn/.test(t):n="svn";break;default:case/github/.test(t):case/(^git|\.git$)/.test(t):n="git"}r.val(n)}),c("[data-sync-repositories]").each(function(){})}),i.init=function(e,r,n){var t=new i(r,n);return t.get_organizations(),u.applyBindings(t,e),t},r.exports.ProjectImportView=i},{"./django-csrf.js":1,"./tasks":2,jquery:"jquery",knockout:"knockout"}]},{},[]);

View File

@ -0,0 +1,90 @@
div.project-import-remote {
h1 {
font-size: 1.2em;
margin: 0em 0em .5em 0em;
}
button.remote-sync {
float: right;
margin: 0em;
}
li.remote-repo {
padding-left: 3em;
padding-right: 3em;
img.remote-repo-avatar {
float: left;
margin-left: -2.25em;
width: 1.5em;
height: 1.5em;
border-radius: .2em;
-moz-border-radius: .2em;
-ms-border-radius: .2em;
-webkit-border-radius: .2em;
}
div.remote-repo-info {
height: 2.625em;
overflow: hidden;
a.remote-repo-name {
line-height: 1.5em;
text-decoration: none;
}
span.remote-repo-url {
display: block;
font-size: .75em;
line-height: 1.5em;
color: #999;
}
}
ul.remote-repo-menu {
top: 10px;
right: 10px;
button.remote-repo-import {
font-size: 1em;
margin: .25em 0em;
width: 2.25em;
height: 2.125em;
}
}
}
}
div.import-remote-sidebar {
h1, h2, h3 {
font-size: 1.1em;
}
li.remote-org {
margin: .5em 0em;
padding-left: 3em;
img.remote-org-avatar {
float: left;
margin-left: -2.25em;
margin-right: .5em;
width: 1.5em;
height: 1.5em;
border-radius: .2em;
-moz-border-radius: .2em;
-ms-border-radius: .2em;
-webkit-border-radius: .2em;
vertical-align: baseline;
}
a.remote-org-name {
font-size: 1em;
text-decoration: none;
line-height: 1.5em;
vertical-align: baseline;
}
}
}

View File

@ -0,0 +1,73 @@
div.project-import-remote h1 {
font-size: 1.2em;
margin: 0em 0em .5em 0em;
}
div.project-import-remote button.remote-sync {
float: right;
margin: 0em;
}
div.project-import-remote li.remote-repo {
padding-left: 3em;
padding-right: 3em;
}
div.project-import-remote li.remote-repo img.remote-repo-avatar {
float: left;
margin-left: -2.25em;
width: 1.5em;
height: 1.5em;
border-radius: .2em;
-moz-border-radius: .2em;
-ms-border-radius: .2em;
-webkit-border-radius: .2em;
}
div.project-import-remote li.remote-repo div.remote-repo-info {
height: 2.625em;
overflow: hidden;
}
div.project-import-remote li.remote-repo div.remote-repo-info a.remote-repo-name {
line-height: 1.5em;
text-decoration: none;
}
div.project-import-remote li.remote-repo div.remote-repo-info span.remote-repo-url {
display: block;
font-size: .75em;
line-height: 1.5em;
color: #999;
}
div.project-import-remote li.remote-repo ul.remote-repo-menu {
top: 10px;
right: 10px;
}
div.project-import-remote li.remote-repo ul.remote-repo-menu button.remote-repo-import {
font-size: 1em;
margin: .25em 0em;
width: 2.25em;
height: 2.125em;
}
div.import-remote-sidebar h1,
div.import-remote-sidebar h2,
div.import-remote-sidebar h3 {
font-size: 1.1em;
}
div.import-remote-sidebar li.remote-org {
margin: .5em 0em;
padding-left: 3em;
}
div.import-remote-sidebar li.remote-org img.remote-org-avatar {
float: left;
margin-left: -2.25em;
margin-right: .5em;
width: 1.5em;
height: 1.5em;
border-radius: .2em;
-moz-border-radius: .2em;
-ms-border-radius: .2em;
-webkit-border-radius: .2em;
vertical-align: baseline;
}
div.import-remote-sidebar li.remote-org a.remote-org-name {
font-size: 1em;
text-decoration: none;
line-height: 1.5em;
vertical-align: baseline;
}

View File

@ -2,8 +2,7 @@ from rest_framework import serializers
from readthedocs.builds.models import Build, BuildCommandResult, Version
from readthedocs.projects.models import Project, Domain
from readthedocs.oauth.models import (GithubOrganization, GithubProject,
BitbucketTeam, BitbucketProject)
from readthedocs.oauth.models import OAuthOrganization, OAuthRepository
class ProjectSerializer(serializers.ModelSerializer):
@ -84,37 +83,19 @@ class DomainSerializer(serializers.ModelSerializer):
)
class GithubOrganizationSerializer(serializers.ModelSerializer):
avatar_url = serializers.ReadOnlyField()
class OAuthOrganizationSerializer(serializers.ModelSerializer):
class Meta:
model = GithubOrganization
model = OAuthOrganization
exclude = ('json', 'email', 'users')
class GithubProjectSerializer(serializers.ModelSerializer):
class OAuthRepositorySerializer(serializers.ModelSerializer):
"""Github project serializer"""
"""OAuth service repository serializer"""
private = serializers.ReadOnlyField(source='is_private')
owner = serializers.ReadOnlyField()
organization = GithubOrganizationSerializer()
organization = OAuthOrganizationSerializer()
class Meta:
model = GithubProject
model = OAuthRepository
exclude = ('json', 'users')
class BitbucketTeamSerializer(serializers.ModelSerializer):
class Meta:
model = BitbucketTeam
exclude = ('json',)
class BitbucketProjectSerializer(serializers.ModelSerializer):
class Meta:
model = BitbucketProject
exclude = ('json',)

View File

@ -4,9 +4,8 @@ from rest_framework import routers
from .views.model_views import (BuildViewSet, BuildCommandViewSet,
ProjectViewSet, NotificationViewSet,
VersionViewSet, DomainViewSet
GithubOrganizationViewSet, GithubProjectViewSet,
BitbucketTeamViewSet, BitbucketProjectViewSet)
VersionViewSet, DomainViewSet,
OAuthOrganizationViewSet, OAuthRepositoryViewSet)
from readthedocs.comments.views import CommentViewSet
router = routers.DefaultRouter()
@ -16,10 +15,8 @@ router.register(r'version', VersionViewSet)
router.register(r'project', ProjectViewSet)
router.register(r'notification', NotificationViewSet)
router.register(r'domain', DomainViewSet)
router.register(r'github/org', GithubOrganizationViewSet)
router.register(r'github/project', GithubProjectViewSet)
router.register(r'bitbucket/team', BitbucketTeamViewSet)
router.register(r'bitbucket/project', BitbucketProjectViewSet)
router.register(r'oauth/org', OAuthOrganizationViewSet)
router.register(r'oauth/repo', OAuthRepositoryViewSet)
router.register(r'comments', CommentViewSet, base_name="comments")
urlpatterns = patterns(

View File

@ -13,8 +13,7 @@ from readthedocs.builds.models import Build, BuildCommandResult, Version
from readthedocs.restapi import utils as api_utils
from readthedocs.core.utils import trigger_build
from readthedocs.oauth import utils as oauth_utils
from readthedocs.oauth.models import (GithubOrganization, GithubProject,
BitbucketTeam, BitbucketProject)
from readthedocs.oauth.models import OAuthOrganization, OAuthRepository
from readthedocs.builds.constants import STABLE
from readthedocs.projects.filters import ProjectFilter, DomainFilter
from readthedocs.projects.models import Project, EmailHook, Domain
@ -25,8 +24,7 @@ from ..permissions import (APIPermission, APIRestrictedPermission,
from ..serializers import (BuildSerializerFull, BuildSerializer,
BuildCommandSerializer, ProjectSerializer,
VersionSerializer, DomainSerializer,
GithubOrganizationSerializer, GithubProjectSerializer,
BitbucketTeamSerializer, BitbucketProjectSerializer)
OAuthOrganizationSerializer, OAuthRepositorySerializer)
from .. import utils as api_utils
log = logging.getLogger(__name__)
@ -220,21 +218,21 @@ class OAuthServiceMixin(object):
return self.model.objects.filter(users=self.request.user)
class GithubOrganizationViewSet(OAuthServiceMixin, viewsets.ReadOnlyModelViewSet):
class OAuthOrganizationViewSet(OAuthServiceMixin, viewsets.ReadOnlyModelViewSet):
permission_classes = [APIPermission]
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
serializer_class = GithubOrganizationSerializer
model = GithubOrganization
serializer_class = OAuthOrganizationSerializer
model = OAuthOrganization
class GithubProjectViewSet(OAuthServiceMixin, viewsets.ReadOnlyModelViewSet):
class OAuthRepositoryViewSet(OAuthServiceMixin, viewsets.ReadOnlyModelViewSet):
permission_classes = [APIPermission]
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
serializer_class = GithubProjectSerializer
model = GithubProject
serializer_class = OAuthRepositorySerializer
model = OAuthRepository
def get_queryset(self):
query = super(GithubProjectViewSet, self).get_queryset()
query = super(OAuthRepositoryViewSet, self).get_queryset()
org = self.request.query_params.get('org', None)
if org is not None:
query = query.filter(organization__pk=org)
@ -242,17 +240,3 @@ class GithubProjectViewSet(OAuthServiceMixin, viewsets.ReadOnlyModelViewSet):
def get_paginate_by(self):
return self.request.query_params.get('page_size', 25)
class BitbucketProjectViewSet(OAuthServiceMixin, viewsets.ReadOnlyModelViewSet):
permission_classes = [APIPermission]
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
serializer_class = BitbucketProjectSerializer
model = BitbucketProject
class BitbucketTeamViewSet(OAuthServiceMixin, viewsets.ReadOnlyModelViewSet):
permission_classes = [APIPermission]
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
serializer_class = BitbucketTeamSerializer
model = BitbucketTeam

View File

@ -17,10 +17,8 @@ $(document).ready(function() {
var urls = {
'api_sync_github_repositories': '{% url 'api_sync_github_repositories' %}',
'api_sync_bitbucket_repositories': '{% url 'api_sync_bitbucket_repositories' %}',
'bitbucketteam-list': '{% url 'bitbucketteam-list' %}',
'bitbucketproject-list': '{% url 'bitbucketproject-list' %}',
'githuborganization-list': '{% url 'githuborganization-list' %}',
'githubproject-list': '{% url 'githubproject-list' %}',
'oauthorganization-list': '{% url 'oauthorganization-list' %}',
'oauthrepository-list': '{% url 'oauthrepository-list' %}',
},
instance = {}, {# projects_json|safe, #}
view = import_views.ProjectImportView.init(

View File

@ -1,62 +1,98 @@
{% extends "projects/project_import_from_service.html" %}
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}{% trans "Import a Remote Repository" %}{% endblock %}
{% block title %}{% trans "Import a GitHub project" %}{% endblock %}
{% block extra_links %}
<link rel="stylesheet" type="text/css" href="{% static "projects/css/import.css" %}" />
{% endblock %}
{% block extra_scripts %}
<script type="text/javascript" src="{% static "vendor/knockout.js" %}"></script>
<script type="text/javascript" src="{% static "core/js/projectimport.js" %}"></script>
<script type="text/javascript">
var import_views = require('core/projectimport');
$(document).ready(function() {
var urls = {
'api_sync_github_repositories': '{% url 'api_sync_github_repositories' %}',
'api_sync_bitbucket_repositories': '{% url 'api_sync_bitbucket_repositories' %}',
'oauthorganization-list': '{% url 'oauthorganization-list' %}',
'oauthrepository-list': '{% url 'oauthrepository-list' %}',
},
instance = {}, {# projects_json|safe, #}
view = import_views.ProjectImportView.init(
$('body').get(0),
instance,
urls
);
});
</script>
{% endblock %}
{% block content-header %}<h1>{% trans "Import a GitHub project" %}</h1>{% endblock %}
{% block content %}
{% if github_connected %}
{% block top_content %}
{% url 'api_sync_github_repositories' as sync_url %}
<button data-bind="click: function() { sync_projects('{{ sync_url }}') }">
{% trans "Sync your GitHub organizations and projects" %}
</button>
{% endblock top_content %}
<ul class="notifications">
<li class="notification notification-20"
data-bind="visible: is_syncing",
style="display: none;">
{% blocktrans %}Syncing ...{% endblocktrans %}
</li>
<li class="notification notification-40"
data-bind="show: error, text: error">
<ul
class="notifications"
style="display: none;"
data-bind="visible: error">
<li
class="notification notification-40"
data-bind="text: error">
</li>
</ul>
{% block main_content %}
<div class="col-major">
<div class="col-major project-import-remote">
<p>
<a href="#" data-bind="visible: page_previous, click: previous_page">
Previous
</a>
<a href="#" data-bind="visible: page_next, click: next_page">
Next
</a>
</p>
{% url 'api_sync_github_repositories' as sync_url %}
<button
data-bind="click: function() { sync_projects('{{ sync_url }}') }"
class="remote-sync">
{% trans "Refresh your accounts" %}
</button>
<!--
<li class="notification notification-20"
data-bind="visible: is_syncing",
style="display: none;">
{% blocktrans %}Syncing ...{% endblocktrans %}
</li>
-->
<h1>{% trans "Import a Remote Repository" %}</h1>
<div class="module repository-list">
<div class="module-wrapper">
<div class="module-list">
<div class="module-list-wrapper">
<ul data-bind="foreach: projects">
<li class="module-item">
<ul data-bind="foreach: projects" class="remote-repos">
<li class="module-item remote-repo">
<span data-bind="with: owner">
<img data-bind="attr: {src: avatar_url}" height=24 />
</span>
<img
data-bind="attr: {src: avatar_url}"
height="24"
class="remote-repo-avatar" />
<a data-bind="attr: {href: url}, text: name"></a>
<div class="remote-repo-info">
<a
data-bind="attr: {href: ssh_url}, text: full_name"
class="remote-repo-name">
</a>
<span
data-bind="text: ssh_url"
class="remote-repo-url">
</span>
</div>
<ul class="module-item-menu">
<button style="margin: 0px;">
{% trans "Create" %}
<ul class="module-item-menu remote-repo-menu">
<button
data-bind="click: import_repo"
class="remote-repo-import">
+
</button>
</ul>
@ -68,24 +104,43 @@
</div>
</div>
<p>
<a href="#" data-bind="visible: page_previous, click: previous_page">
Previous
<div class="pagination">
<span data-bind="visible: !page_previous()" class="disabled prev">
{% trans "previous" %}
</span>
<a
href="#"
data-bind="visible: page_previous, click: previous_page"
class="prev">
{% trans "previous" %}
</a>
<a href="#" data-bind="visible: page_next, click: next_page">
Next
<span data-bind="visible: !page_next()" class="disabled next">
{% trans "next" %}
</span>
<a
href="#"
data-bind="visible: page_next, click: next_page"
class="next">
{% trans "next" %}
</a>
</p>
</div>
</div>
{% endblock main_content %}
{% block sidebar_content %}
<div class="col-minor">
<ul data-bind="foreach: organizations">
<li>
<img data-bind="attr: {src: avatar_url}" height=32 />
<a href="#" data-bind="text: display_name, click: function () { $root.filter_org(id()); }"></a>
<div class="col-minor import-remote-sidebar">
<h3>{% trans "Remote Organizations" %}</h3>
<ul data-bind="foreach: organizations" class="remote-orgs">
<li class="remote-org">
<img data-bind="attr: {src: avatar_url}" class="remote-org-avatar" />
<a
href="#"
data-bind="text: display_name, click: function () { $root.filter_org(id()); }"
class="remote-org-name">
</a>
</li>
</ul>
</div>