Skip to content

Commit

Permalink
portal: much simpler browse page (handsontable)
Browse files Browse the repository at this point in the history
  • Loading branch information
tschaume committed Aug 8, 2021
1 parent 3cd7382 commit 828db63
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 137 deletions.
7 changes: 6 additions & 1 deletion mpcontribs-portal/mpcontribs/portal/assets/css/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
@import "~select2/dist/css/select2.min.css";
@import "~@fortawesome/fontawesome-free/css/all.css";
@import '~handsontable/dist/handsontable.full.css';
@import "~intro.js/introjs.css";

$family-sans-serif: "Nunito", sans-serif;
$tooltip-background-opacity: 1;
Expand Down Expand Up @@ -98,3 +97,9 @@ table { white-space: nowrap; }
.dropdown-content { max-height: 13em; overflow: auto; }
#component-modal { z-index: 300; }
pre code.hljs { padding: 0px; }

.navbar-item.center {
flex-grow: 1;
flex-direction: column;
justify-content: center;
}
122 changes: 97 additions & 25 deletions mpcontribs-portal/mpcontribs/portal/assets/js/browse.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import Handsontable from "handsontable";

var li = $('#browse-toggle').parent();
li.siblings().removeClass('is-active');
li.addClass('is-active');

function prep_download(query) {
const url = "/contributions/download/create";
const project = query["project"];
Expand All @@ -21,32 +27,98 @@ function prep_download(query) {
});
}

$(document).ready(function () {
var li = $('#browse-toggle').parent();
li.siblings().removeClass('is-active');
li.addClass('is-active');

$('a[name="download"]').click(function(e) {
const project = $(this).data('project');
const fmt = $(this).data('format');
var hide_id = "#download_" + project;
if (fmt === "json") { hide_id += "_csv" } else { hide_id += "_json"; }
$(hide_id).addClass("is-hidden");
$(this).addClass('is-loading');
$("#download_" + project + "_progress").text("0%").removeClass("is-hidden");
var download_query = {
"format": fmt, "project": project,
"include": "structures,tables,attachments"
};
prep_download(download_query);
$('a[name="download"]').click(function(e) {
const project = $(this).data('project');
const fmt = $(this).data('format');
var hide_id = "#download_" + project;
if (fmt === "json") { hide_id += "_csv" } else { hide_id += "_json"; }
$(hide_id).addClass("is-hidden");
$(this).addClass('is-loading');
$("#download_" + project + "_progress").text("0%").removeClass("is-hidden");
var download_query = {
"format": fmt, "project": project,
"include": "structures,tables,attachments"
};
prep_download(download_query);
});

$('a[name="get_download"]').click(function() {
const project = $(this).data('project');
const prefix = "#download_" + project + "_";
$(prefix + "json").removeClass("is-hidden");
$(prefix + "csv").removeClass("is-hidden");
$(prefix + "progress").addClass("is-hidden");
$(this).addClass("is-hidden");
});

const main_columns = ["title", "public", "author"];
const stats_columns = ["columns", "contributions", "structures", "tables", "attachments"];
const colHeaders = main_columns.concat(stats_columns);
const url = window.api['host'] + 'projects/';
const container = document.getElementById("main_table");
const query = {
_fields: "name,title,is_public,authors,owner,stats",
_sort: "-stats.contributions"
}
var columnSummary = [];
var columns = [];

for (var c = 0; c < main_columns.length; c++) {
columns.push({"type": "text", "renderer": "html"});
}

for (var c = 0; c < stats_columns.length; c++) {
columns.push({
"type": "numeric", "renderer": "numeric", readOnly: true
});
columnSummary.push({
destinationRow: 0,
destinationColumn: c + main_columns.length,
reversedRowCoords: true,
type: 'sum'
});
}

$('a[name="get_download"]').click(function() {
const project = $(this).data('project');
const prefix = "#download_" + project + "_";
$(prefix + "json").removeClass("is-hidden");
$(prefix + "csv").removeClass("is-hidden");
$(prefix + "progress").addClass("is-hidden");
$(this).addClass("is-hidden");
$.get({
contentType: "json", dataType: "json", url: url,
headers: window.api['headers'], data: query
}).done(function(response) {
var data = [];
var rlen = response.data.length;
for (var r = 0; r < rlen; r++) {
var doc = response['data'][r];
var d = ["<a class='has-text-weight-bold' href='/projects/"];
d[0] += doc["name"] + "'>" + doc["title"] + "</a>";
var symbol = doc["is_public"] ? "check" : "times";
var is_public = '<i class="fas fa-' + symbol +'"></i>';
d.push(is_public);
var author = doc["authors"].split(",")[0].substring(0,30);
var owner = doc["owner"].split(":")[1];
var mailto = 'mailto:' + owner + ',contribs@materialsproject.org';
var at = '<a href="' + mailto + '">';
at += '<span class="icon-text"><span class="icon"><i class="fas fa-at"></i></span><span>';
at += author + '</span></span></a>';
d.push(at);
for (var c = 0; c < stats_columns.length; c++) {
var col = stats_columns[c];
d.push(doc["stats"][col]);
}
data.push(d);
}
data.push([]);
console.log(data);
const hot = new Handsontable(container, {
data,
colHeaders: colHeaders,
columns: columns,
columnSummary: columnSummary,
rowHeaders: false,
width: '100%',
stretchH: 'all',
preventOverflow: 'horizontal',
licenseKey: 'non-commercial-and-evaluation',
disableVisualSelection: true,
className: "htCenter htMiddle",
//columnSorting: {initialConfig: {column: 4, sortOrder: 'desc'}}
});
});
50 changes: 7 additions & 43 deletions mpcontribs-portal/mpcontribs/portal/assets/js/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import logo from 'images/logo.png';
import 'select2/dist/js/select2';
import '@fortawesome/fontawesome-free/js/all';
import '@vizuaalog/bulmajs/dist/dropdown';
import introJs from 'intro.js/intro';
require('css/main.scss');

var api_key = $('#api_key').val();
Expand All @@ -17,57 +15,23 @@ $(document).ready(function () {
document.getElementById("logo").src = logo;
$('a[name="api_url"]').attr('href', window.api['host']);

// quick nav
$('#jump').select2({
ajax: {
url: window.api['host'] + 'projects/',
headers: window.api['headers'],
delay: 400,
minimumInputLength: 3,
maximumSelectionLength: 3,
multiple: true,
width: 'style',
data: function (params) {
if (typeof params.term == 'undefined') { $("[name=cards]").removeClass('is-hidden'); }
var query = {_fields: "name,title"};
if (params.term) { query['description__icontains'] = params.term; }
return query;
},
processResults: function (data) {
$("[name=cards]").addClass('is-hidden');
var results = [];
$.each(data['data'], function(index, element) {
var entry = {id: index, text: element['title'], value: element['name']};
$('#'+element['name']).removeClass('is-hidden');
results.push(entry);
});
return {results: results};
}
}
});
$('#jump').on('select2:select', function(ev) {
var project = ev.params.data["value"];
window.location.href = '/projects/'+project+'/';
});

// navbar burger for mobile
$(".navbar-burger").click(function() {
$(".navbar-burger").toggleClass("is-active");
$(".navbar-menu").toggleClass("is-active");
});

$('.select2').css({width: '100%'});
$('.select2-search').css({width: 'auto'});
$('.select2-search__field').css({width: '100%'});
// profile dropdown
$(".navbar-item.has-dropdown").click(function() {
$(this).toggleClass("is-active");
});
$('body').click(function(e) {
$(".navbar-item.has-dropdown").removeClass('is-active');
});

// close all dropdowns on body click
$('body').click(function(e) {
var dropdowns = $(".dropdown");
dropdowns.not(dropdowns.has(e.target)).removeClass('is-active');
});

$("#help").click(function() {
// TODO use toggle name to decide which help/tour to show
introJs().setOptions({"showStepNumbers": false, "overlayOpacity": 0.2}).start();
});
});
2 changes: 1 addition & 1 deletion mpcontribs-portal/mpcontribs/portal/templates/browse.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
{% endif %}
-->

{% if simple_table %}{{ simple_table|safe }}{% endif %}
<div id=main_table></div>
</section>
{% endblock %}

Expand Down
47 changes: 12 additions & 35 deletions mpcontribs-portal/mpcontribs/portal/templates/header_footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,44 +28,20 @@
</div>
</div>
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-start">
<div class="navbar-item has-text-centered">
<div class="tabs is-toggle is-toggle-rounded has-text-weight-semibold">
<ul>
<li data-intro="Browse a list of all available projects."
data-step="2">
<a id="browse-toggle" href="/browse">Browse</a>
</li>
<li data-intro="Search contributions and render their cards."
data-step="3">
<a id="search-toggle" href="/search">Search</a>
</li>
<li data-intro="Apply for your own project."
data-step="4">
<a id="apply-toggle" href="/contribute">Contribute</a>
</li>
<li>
<!-- TODO link to local docs in dev -->
<a id=docs_url target="_blank" href="https://docs.mpcontribs.org">
Docs
</a>
</li>
</ul>
</div>
</div>
<div class="navbar-item has-text-centered"
data-intro="Use this dropdown menu to quickly jump to specific projects, or to search for keywords in their descriptions. The search will reduce the list of projects shown on the <i>Browse</i> tab to those matching the keyword."
data-step="1">
<select id="jump" data-placeholder="Search or jump to projects ...">
<option></option>
</select>
<div class="navbar-item has-text-centered center">
<div class="tabs is-toggle is-toggle-rounded has-text-weight-semibold">
<ul>
<li><a id="browse-toggle" href="/browse">Browse</a></li>
<li><a id="search-toggle" href="/search">Search</a></li>
<li><a id="apply-toggle" href="/contribute">Contribute</a></li>
</ul>
</div>
</div>
<div class="navbar-end">
{% if request.META.HTTP_X_ANONYMOUS_CONSUMER %}
<a class="navbar-item" href="{{ OAUTH_URL }}">Login</a>
{% else %}
<div class="navbar-item has-dropdown is-hoverable">
<div class="navbar-item has-dropdown">
<a class="navbar-link">
<span class="icon"><i class="fas fa-user-check"></i></span>
</a>
Expand All @@ -84,9 +60,10 @@
<span class="is-family-code">{{ request.META.HTTP_X_AUTHENTICATED_GROUPS }}</span>
</p>
{% endif %}
<a class="navbar-item" id=help>
<span class="icon"><i class="fas fa-question"></i></span>
<span>Tour the page</span>
<!-- TODO link to local docs in dev -->
<a class="navbar-item" id=docs_url href="https://docs.mpcontribs.org" target="_blank">
<span class="icon"><i class="fas fa-book"></i></span>
<span>Documentation</span>
</a>
<a class="navbar-item" name=api_url target="_blank">
<span class="icon"><i class="fas fa-code"></i></span>
Expand Down
32 changes: 0 additions & 32 deletions mpcontribs-portal/mpcontribs/portal/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,39 +169,7 @@ def apply(request):


def browse(request):
# NOTE visibility governed by is_public flag and X-Authenticated-Groups header
ctx = get_context(request)
stats_keys = ["columns", "contributions", "structures", "tables", "attachments"]
simple_table = []
ckwargs = client_kwargs(request)

with Client(**ckwargs) as client:
entries = client.projects.get_entries(
_fields=["name", "title", "is_public", "authors", "owner", "stats"],
_sort="-stats.contributions"
).result()["data"]

for entry in entries:
author = entry.pop("authors").strip().split(",", 1)[0][:20]
owner = entry["owner"].split(":", 1)[-1]
href = f"/projects/{entry['name']}"

row = {
"title": f"<a href='{href}'>{entry['title']}</a>",
"public": entry["is_public"],
"author": f"<a href='mailto:{owner},contribs@materialsproject.org'>{author}</a>."
}

for k in stats_keys:
row[k] = entry["stats"][k]

simple_table.append(row)

# TODO simple table just for testing
ctx["simple_table"] = j2h.convert(
json=simple_table,
table_attributes='class="table is-narrow is-fullwidth has-background-light"',
)
return render(request, "browse.html", ctx.flatten())


Expand Down

0 comments on commit 828db63

Please sign in to comment.