Skip to content

Commit c23a75f

Browse files
committed
Use one list for all filters (organizations and own accounts)
1 parent a9d98a2 commit c23a75f

File tree

3 files changed

+100
-77
lines changed

3 files changed

+100
-77
lines changed

readthedocs/projects/static-src/projects/js/import.js

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,35 @@ function Organization (instance, view) {
4949
self.display_name = ko.computed(function () {
5050
return self.name() || self.slug();
5151
});
52+
self.filter_id = ko.computed(function () {
53+
return self.id();
54+
});
55+
self.filter_type = 'org';
5256
self.filtered = ko.computed(function () {
53-
var id = view.filter_org();
54-
return id && id != self.id();
57+
var filter = view.filter_by();
58+
return (filter.id && filter.id != self.filter_id()) || (filter.type && filter.type != self.filter_type);
59+
});
60+
}
61+
62+
function Account (instance, view) {
63+
var self = this;
64+
self.id = ko.observable(instance.id);
65+
self.username = ko.observable(instance.username);
66+
self.active = ko.observable(instance.active);
67+
self.avatar_url = ko.observable(
68+
append_url_params(instance.avatar_url, {size: 32})
69+
);
70+
self.provider = ko.observable(instance.provider);
71+
self.display_name = ko.computed(function () {
72+
return self.username();
73+
});
74+
self.filter_id = ko.computed(function () {
75+
return self.provider().id;
76+
});
77+
self.filter_type = 'own';
78+
self.filtered = ko.computed(function () {
79+
var filter = view.filter_by();
80+
return (filter.id && filter.id != self.filter_id()) || (filter.type && filter.type != self.filter_type);
5581
});
5682
}
5783

@@ -62,7 +88,7 @@ function Project (instance, view) {
6288
self.full_name = ko.observable(instance.full_name);
6389
self.description = ko.observable(instance.description);
6490
self.vcs = ko.observable(instance.vcs);
65-
self.organization = ko.observable();
91+
self.organization = ko.observable(instance.organization);
6692
self.html_url = ko.observable(instance.html_url);
6793
self.clone_url = ko.observable(instance.clone_url);
6894
self.ssh_url = ko.observable(instance.ssh_url);
@@ -140,38 +166,44 @@ function ProjectImportView (instance, config) {
140166
self.page_current = ko.observable(null);
141167
self.page_next = ko.observable(null);
142168
self.page_previous = ko.observable(null);
143-
self.filter_org = ko.observable(null);
144-
self.filter_own = ko.observable(null);
169+
// organization slug or account provider name
170+
// { id: 'GitHub', type: 'own' }
171+
self.filter_by = ko.observable({ id: null, type: null });
145172

173+
self.accounts_raw = ko.observableArray();
146174
self.organizations_raw = ko.observableArray();
147-
self.organizations = ko.computed(function () {
148-
var organizations = [],
175+
self.filters = ko.computed(function () {
176+
var filters = [],
177+
accounts_raw = self.accounts_raw(),
149178
organizations_raw = self.organizations_raw();
179+
for (n in accounts_raw) {
180+
var account = new Account(accounts_raw[n], self);
181+
filters.push(account);
182+
}
150183
for (n in organizations_raw) {
151184
var organization = new Organization(organizations_raw[n], self);
152-
organizations.push(organization);
185+
filters.push(organization);
153186
}
154-
return organizations;
187+
return filters;
155188
});
156189
self.projects = ko.observableArray();
157190

158191
ko.computed(function () {
159-
var org = self.filter_org(),
160-
own = self.filter_own(),
192+
var filter = self.filter_by(),
161193
url = self.page_current() || self.urls['remoterepository-list'];
162194

163195
if (!self.page_current()) {
164-
if (org) {
196+
if (filter.type == 'org') {
165197
url = append_url_params(
166198
self.urls['remoterepository-list'],
167-
{org: org}
199+
{org: filter.id}
168200
);
169201
}
170202

171-
if (own) {
203+
if (filter.type == 'own') {
172204
url = append_url_params(
173205
self.urls['remoterepository-list'],
174-
{own: own}
206+
{own: filter.id}
175207
);
176208
}
177209
}
@@ -210,6 +242,17 @@ function ProjectImportView (instance, config) {
210242
});
211243
};
212244

245+
self.get_accounts = function () {
246+
$.getJSON(self.urls['remoteaccount-list'])
247+
.success(function (accounts) {
248+
self.accounts_raw(accounts.results);
249+
})
250+
.error(function (error) {
251+
var error_msg = error.responseJSON.detail || error.statusText;
252+
self.error({message: error_msg});
253+
});
254+
};
255+
213256
self.sync_projects = function () {
214257
var url = self.urls.api_sync_remote_repositories;
215258

@@ -219,6 +262,7 @@ function ProjectImportView (instance, config) {
219262
tasks.trigger_task({url: url, token: self.csrf_token})
220263
.then(function (data) {
221264
self.get_organizations();
265+
self.get_accounts();
222266
})
223267
.fail(function (error) {
224268
self.error(error);
@@ -240,27 +284,23 @@ function ProjectImportView (instance, config) {
240284
self.page_current(self.page_previous());
241285
};
242286

243-
self.set_filter_org = function (id) {
244-
var current_id = self.filter_org();
245-
if (current_id == id) {
246-
id = null;
287+
self.set_filter_by = function (id, type) {
288+
var filter = self.filter_by();
289+
if (filter.id == id) {
290+
filter.id = null;
291+
filter.type = null;
247292
}
248-
// This needs to use deferred updates
249-
self.filter_org(id);
250-
self.filter_own(false);
251-
self.page_current(null);
252-
};
253-
254-
self.set_filter_own = function (account) {
255-
var current_account = self.filter_own();
256-
if (current_account == account) {
257-
account = null;
293+
else {
294+
filter.id = id;
295+
filter.type = type;
258296
}
259297

260-
// This needs to use deferred updates
261-
self.filter_own(account);
262-
self.filter_org(null);
263-
self.page_current(null);
298+
// This needs to use deferred updates because we are setting
299+
// `filter_by` and `page_current`
300+
self.filter_by(filter);
301+
if (filter.id) {
302+
self.page_current(null);
303+
}
264304
};
265305
}
266306

@@ -278,6 +318,7 @@ function append_url_params (url, params) {
278318

279319
ProjectImportView.init = function (domobj, instance, config) {
280320
var view = new ProjectImportView(instance, config);
321+
view.get_accounts();
281322
view.get_organizations();
282323
ko.applyBindings(view, domobj);
283324
return view;

readthedocs/restapi/serializers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def get_matches(self, obj):
163163

164164
class ProviderSerializer(serializers.Serializer):
165165

166+
id = serializers.CharField(max_length=20)
166167
name = serializers.CharField(max_length=20)
167168

168169

readthedocs/templates/projects/project_import.html

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,25 @@
1313
<script type="text/javascript" src="{% static "vendor/knockout.js" %}"></script>
1414
<script type="text/javascript" src="{% static "projects/js/import.js" %}"></script>
1515
<script type="text/javascript">
16-
var import_views = require('projects/import');
17-
$(document).ready(function() {
18-
var instance = {},
19-
config = {
20-
'csrf_token': '{{ view_csrf_token }}',
21-
'urls': {
22-
'api_sync_remote_repositories': '{% url 'api_sync_remote_repositories' %}',
23-
'remoteorganization-list': '{% url 'remoteorganization-list' %}',
24-
'remoterepository-list': '{% url 'remoterepository-list' %}',
25-
'projects_import': '{% url 'projects_import' %}'
26-
}
27-
},
28-
view = import_views.ProjectImportView.init(
29-
$('body').get(0),
30-
instance,
31-
config
32-
);
33-
});
16+
var import_views = require('projects/import');
17+
$(document).ready(function() {
18+
var instance = {},
19+
config = {
20+
'csrf_token': '{{ view_csrf_token }}',
21+
'urls': {
22+
'api_sync_remote_repositories': '{% url 'api_sync_remote_repositories' %}',
23+
'remoteorganization-list': '{% url 'remoteorganization-list' %}',
24+
'remoterepository-list': '{% url 'remoterepository-list' %}',
25+
'remoteaccount-list': '{% url 'remoteaccount-list' %}',
26+
'projects_import': '{% url 'projects_import' %}'
27+
}
28+
},
29+
view = import_views.ProjectImportView.init(
30+
$('body').get(0),
31+
instance,
32+
config
33+
);
34+
});
3435
</script>
3536
{% endblock %}
3637

@@ -209,34 +210,14 @@ <h1>{% trans "Import a Repository" %}</h1>
209210
</div>
210211
{% endblock %}
211212

212-
{# accounts is a dictionary with the provider as key and a list of connected accounts of that provider #}
213-
{% get_social_accounts user as accounts %}
214-
{% if accounts %}
215-
<h3>{% trans "Filter by Own Repositories" %}</h3>
216-
{% for type, list in accounts.items %}
217-
{% for account in list %}
218-
<li
219-
class="remote-org"
220-
data-bind="click: function () { $root.set_filter_own('{{ account.provider }}'); }">
221-
<img src="{{ account.get_avatar_url }}" class="remote-org-avatar" />
222-
223-
<!-- TODO: get the proper username for the connected account -->
224-
<span>{{ account.user.username }} ({{ account.get_provider_display }})</span>
225-
226-
</li>
227-
{% endfor %}
228-
{% endfor %}
229-
{% endif %}
230-
213+
{% block filter-repositories %}
214+
<div data-bind="visible: filters().length > 0">
215+
<h3>{% trans "Filter repositories" %}</h3>
231216

232-
{% block organizations %}
233-
<div data-bind="visible: organizations().length > 0">
234-
<h3>{% trans "Filter by Organization" %}</h3>
235-
236-
<ul data-bind="foreach: organizations" class="remote-orgs">
217+
<ul data-bind="foreach: filters" class="remote-orgs">
237218
<li
238-
class="remote-org"
239-
data-bind="css: {'remote-org-hidden': filtered()}, click: function () { $root.set_filter_org(id()); }">
219+
class="remote-org"
220+
data-bind="css: {'remote-org-hidden': filtered()}, click: function () { $root.set_filter_by(filter_id(), filter_type); }">
240221
<img data-bind="attr: {src: avatar_url}" class="remote-org-avatar" />
241222
<span data-bind="text: display_name" class="remote-org-name"></span>
242223
</li>

0 commit comments

Comments
 (0)