mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
Split category selection and app browsing into two separate pages
This commit is contained in:
parent
9636c200ac
commit
4f9c47eab5
6 changed files with 94 additions and 90 deletions
|
@ -709,12 +709,31 @@ input[type='radio'].nice-radio {
|
||||||
.app-category-card .panel-body {
|
.app-category-card .panel-body {
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
height: 10em;
|
height: 10em;
|
||||||
|
color: #333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtag-selector {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-category-card {
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-category-card:hover {
|
||||||
|
border-color: #777;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-category-title {
|
.app-category-title {
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-category-card-desc {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Groups View **/
|
/** Groups View **/
|
||||||
#view-groups {
|
#view-groups {
|
||||||
.panel-heading a {
|
.panel-heading a {
|
||||||
|
|
|
@ -107,15 +107,34 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display app catalog
|
|
||||||
|
// Display catalog home page where users chooses to browse a specific category
|
||||||
app.get('#/apps/catalog', function (c) {
|
app.get('#/apps/catalog', function (c) {
|
||||||
c.api('GET', '/appscatalog?full&with_categories', {}, function (data) {
|
c.api('GET', '/appscatalog?full&with_categories', {}, function (data) {
|
||||||
var apps = []
|
c.view('app/app_catalog_home', {categories: data["categories"]}, function() {
|
||||||
|
// Configure layout / rendering for app-category-cards
|
||||||
|
$('#category-selector').isotope({
|
||||||
|
itemSelector: '.app-category-card',
|
||||||
|
layoutMode: 'fitRows',
|
||||||
|
transitionDuration: 200
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Display app catalog for a specific category
|
||||||
|
app.get('#/apps/catalog/:category', function (c) {
|
||||||
|
var category_id = c.params['category'];
|
||||||
|
c.api('GET', '/appscatalog?full&with_categories', {}, function (data) {
|
||||||
|
var apps = [];
|
||||||
$.each(data['apps'], function(name, app) {
|
$.each(data['apps'], function(name, app) {
|
||||||
|
|
||||||
// Ignore not working apps
|
// Ignore not working apps
|
||||||
if (app.state === 'notworking') { return; }
|
if (app.state === 'notworking') { return; }
|
||||||
|
|
||||||
|
// Ignore apps not in this category
|
||||||
|
if ((category_id !== "all") && (app.category !== category_id)) { return; }
|
||||||
|
|
||||||
app.id = app.manifest.id;
|
app.id = app.manifest.id;
|
||||||
app.level = parseInt(app.level);
|
app.level = parseInt(app.level);
|
||||||
|
|
||||||
|
@ -152,6 +171,15 @@
|
||||||
apps.push(app);
|
apps.push(app);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var category = undefined;
|
||||||
|
$.each(data['categories'], function(i, this_category) {
|
||||||
|
if (this_category.id === category_id) { category = this_category; }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (category_id === "all") {
|
||||||
|
category = {title: y18n.t("all_apps"), icon: "search"};
|
||||||
|
}
|
||||||
|
|
||||||
// Sort app list
|
// Sort app list
|
||||||
c.arraySortById(apps);
|
c.arraySortById(apps);
|
||||||
|
|
||||||
|
@ -167,75 +195,21 @@
|
||||||
// Default filter is 'decent quality apps'
|
// Default filter is 'decent quality apps'
|
||||||
cardGrid.isotope({ filter: '.decentQuality' });
|
cardGrid.isotope({ filter: '.decentQuality' });
|
||||||
|
|
||||||
var categoryGrid = jQuery('#category-selector').isotope({
|
|
||||||
itemSelector: '.app-category-card',
|
|
||||||
layoutMode: 'fitRows',
|
|
||||||
transitionDuration: 200
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#category-selector").show();
|
|
||||||
$("#current-category-filter").hide();
|
|
||||||
$("#current-category-separator").hide();
|
|
||||||
$("#back-to-category-selection").hide();
|
|
||||||
$(".subtag-selector").hide();
|
|
||||||
|
|
||||||
$("#category-selector button").on("click", function() {
|
|
||||||
var category = $(this).data("category");
|
|
||||||
var title = $("h2", this).html();
|
|
||||||
|
|
||||||
// Feed info and display the selecter category next to the search bar
|
|
||||||
$("#current-category-filter").html(title);
|
|
||||||
$("#current-category-filter").data("category", category);
|
|
||||||
$("#current-category-filter").show();
|
|
||||||
$("#back-to-category-selection").show();
|
|
||||||
$("#current-category-separator").show();
|
|
||||||
|
|
||||||
// Hide the category selector
|
|
||||||
$("#category-selector").hide();
|
|
||||||
|
|
||||||
// Display the subtags selector
|
|
||||||
$(".subtag-selector").hide();
|
|
||||||
$(".subtag-selector[data-app-category='"+category+"']").show();
|
|
||||||
cardGrid.isotope({ filter: filterApps });
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#back-to-category-selection").on("click", function() {
|
|
||||||
|
|
||||||
// Hide / reset selected cateory next to the search bar
|
|
||||||
$("#current-category-filter").hide();
|
|
||||||
$("#current-category-filter").data("category", "");
|
|
||||||
$("#back-to-category-selection").hide();
|
|
||||||
$("#current-category-separator").hide();
|
|
||||||
|
|
||||||
// Display the category selector
|
|
||||||
$("#category-selector").show();
|
|
||||||
|
|
||||||
// Hide subtag selector
|
|
||||||
$(".subtag-selector").hide();
|
|
||||||
cardGrid.isotope({ filter: filterApps });
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".subtag-selector button").on("click", function() {
|
$(".subtag-selector button").on("click", function() {
|
||||||
var selector = $(this).parent();
|
var selector = $(this).parent();
|
||||||
var category = selector.data("app-category");
|
|
||||||
$("button", selector).removeClass("active");
|
$("button", selector).removeClass("active");
|
||||||
$(this).addClass("active");
|
$(this).addClass("active");
|
||||||
cardGrid.isotope({ filter: filterApps });
|
cardGrid.isotope({ filter: filterApps });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
filterApps = function () {
|
filterApps = function () {
|
||||||
|
|
||||||
// Check text search
|
// Check text search
|
||||||
var input = jQuery("#filter-app-cards").val().toLowerCase();
|
var input = jQuery("#filter-app-cards").val().toLowerCase();
|
||||||
if (jQuery(this).find('.app-title').text().toLowerCase().indexOf(input) <= -1) return false;
|
if (jQuery(this).find('.app-title').text().toLowerCase().indexOf(input) <= -1) return false;
|
||||||
|
|
||||||
// Check category
|
|
||||||
var category = $("#current-category-filter").data("category");
|
|
||||||
if ((category !== '') && (jQuery(this).data("category") !== category)) return false;
|
|
||||||
|
|
||||||
// Check subtags
|
// Check subtags
|
||||||
var subtag = $(".subtag-selector[data-app-category='"+category+"'] button.active").data("subtag");
|
var subtag = $(".subtag-selector button.active").data("subtag");
|
||||||
var this_subtags = jQuery(this).data("subtags");
|
var this_subtags = jQuery(this).data("subtags");
|
||||||
if ((subtag !== undefined) && (subtag !== "all")) {
|
if ((subtag !== undefined) && (subtag !== "all")) {
|
||||||
if ((subtag === "others") && (this_subtags !== "")) return false;
|
if ((subtag === "others") && (this_subtags !== "")) return false;
|
||||||
|
@ -264,7 +238,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// render
|
// render
|
||||||
c.view('app/app_catalog', {apps: apps, categories: data["categories"]}, setupFilterEvents);
|
c.view('app/app_catalog_category', {apps: apps, category: category}, setupFilterEvents);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
"begin": "Begin",
|
"begin": "Begin",
|
||||||
"both": "Both",
|
"both": "Both",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
|
"catalog": "Catalog",
|
||||||
"check": "Check",
|
"check": "Check",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"configuration": "Configuration",
|
"configuration": "Configuration",
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<div class="btn-breadcrumb">
|
<div class="btn-breadcrumb">
|
||||||
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
||||||
<a href="#/apps">{{t 'applications'}}</a>
|
<a href="#/apps">{{t 'applications'}}</a>
|
||||||
<a href="#/apps/catalog">{{t 'install'}}</a>
|
<a href="#/apps/catalog">{{t 'catalog'}}</a>
|
||||||
|
<a href="#/apps/catalog/{{category.id}}">{{category.title}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
|
|
||||||
<div class="input-group" id="app-filter-input">
|
<div class="input-group" id="app-filter-input">
|
||||||
<div id="back-to-category-selection" class="input-group-btn"><button class="btn btn-primary"><i class="fa-arrow-left"></i></button></div>
|
<div class="input-group-btn"><a class="btn btn-primary" href="#/apps/catalog"><i class="fa-arrow-left"></i></a></div>
|
||||||
<span id="current-category-filter" class="input-group-addon"></span>
|
<span class="input-group-addon"><i class="fa-fw fa-{{category.icon}}"></i> {{category.title}}</span>
|
||||||
<span id="current-category-separator" class="input-group-addon" style="background: white;border: none;"> </span>
|
<span class="input-group-addon" style="background: white;border: none;"> </span>
|
||||||
<span class="input-group-addon"><i class="fa-search"></i></span>
|
<span class="input-group-addon"><i class="fa-search"></i></span>
|
||||||
<input type="text" id="filter-app-cards" class="form-control" role="textbox" placeholder="{{t 'search_for_apps'}}" aria-describedby="basic-addon0"/>
|
<input type="text" id="filter-app-cards" class="form-control" role="textbox" placeholder="{{t 'search_for_apps'}}" aria-describedby="basic-addon0"/>
|
||||||
<div class="input-group-btn">
|
<div class="input-group-btn">
|
||||||
|
@ -27,37 +28,23 @@
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
|
|
||||||
<div id="category-selector" class="list-group grid">
|
<div class="subtag-selector">
|
||||||
{{#categories}}
|
{{#if category.subtags}}
|
||||||
<button class="app-category-card panel panel-default" data-category="{{id}}">
|
|
||||||
<div class="panel-body">
|
|
||||||
<h2 class="app-category-title" style="white-space: normal"><span class="fa-fw fa-{{icon}}"></span> {{title}}</h2>
|
|
||||||
<h3 class="app-category-card-desc" style="white-space: normal">{{description}}</h3>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
{{/categories}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#categories}}
|
|
||||||
<div class="subtag-selector" data-app-category="{{id}}" style="text-align: center">
|
|
||||||
{{#if subtags}}
|
|
||||||
<button class="btn btn-default active" data-subtag="all">All</button>
|
<button class="btn btn-default active" data-subtag="all">All</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#subtags}}
|
{{#category.subtags}}
|
||||||
<button class="btn btn-default" data-subtag="{{.}}">{{.}}</button>
|
<button class="btn btn-default" data-subtag="{{.}}">{{.}}</button>
|
||||||
{{/subtags}}
|
{{/category.subtags}}
|
||||||
{{#if subtags}}
|
{{#if category.subtags}}
|
||||||
<button class="btn btn-default" data-subtag="others">Others</button>
|
<button class="btn btn-default" data-subtag="others">Others</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/categories}}
|
|
||||||
|
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
|
|
||||||
<div id="apps" class="list-group grid">
|
<div id="apps" class="list-group grid">
|
||||||
{{#apps}}
|
{{#apps}}
|
||||||
<div class="app-card panel panel-default {{state}} {{isWorking}} {{isHighQuality}} {{decentQuality}} {{level}}-level" data-category="{{category}}" data-subtags="{{#subtags}}{{.}}{{#unless @last}},{{/unless}}{{/subtags}}">
|
<div class="app-card panel panel-default {{state}} {{isWorking}} {{isHighQuality}} {{decentQuality}} {{level}}-level" data-subtags="{{#subtags}}{{.}}{{#unless @last}},{{/unless}}{{/subtags}}">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<h2 class="app-title">
|
<h2 class="app-title">
|
||||||
{{manifest.name}}
|
{{manifest.name}}
|
||||||
|
@ -73,19 +60,19 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="app-card-date-maintainer">
|
<div class="app-card-date-maintainer">
|
||||||
{{#if (eq maintainedColor 'danger') }}
|
{{#if (eq maintainedColor 'danger') }}
|
||||||
<span class="text text-warning maintained-status" title="{{t (concat maintained '_details') }}"><i class="fa-warning"></i> {{t maintained}}</span>
|
<span class="text text-warning maintained-status" title="{{t (concat maintained '_details') }}"><i class="fa-fw fa-warning"></i> {{t maintained}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<a href="{{git.url}}" target="_BLANK" type="button" role="button" class="btn btn-default col-xs-4">
|
<a href="{{git.url}}" target="_BLANK" type="button" role="button" class="btn btn-default col-xs-4">
|
||||||
<i class="fa-code"></i> Code
|
<i class="fa-fw fa-code"></i> Code
|
||||||
</a>
|
</a>
|
||||||
<a href="{{git.url}}/blob/master/README.md" target="_BLANK" type="button" role="button" class="btn btn-default col-xs-4">
|
<a href="{{git.url}}/blob/master/README.md" target="_BLANK" type="button" role="button" class="btn btn-default col-xs-4">
|
||||||
<i class="fa-book"></i> Readme
|
<i class="fa-fw fa-book"></i> Readme
|
||||||
</a>
|
</a>
|
||||||
{{#installable}}
|
{{#installable}}
|
||||||
<a href="#/apps/install/{{manifest.id}}" type="button" role="button" class="btn btn-{{installColor}} col-xs-4 active">
|
<a href="#/apps/install/{{manifest.id}}" type="button" role="button" class="btn btn-{{installColor}} col-xs-4 active">
|
||||||
<i class="fa-plus"></i> {{t 'install'}}{{^isSafe}} <i class="fa-warning"></i>{{/isSafe}}
|
<i class="fa-fw fa-plus"></i> {{t 'install'}}{{^isSafe}} <i class="fa-fw fa-warning"></i>{{/isSafe}}
|
||||||
</a>
|
</a>
|
||||||
{{/installable}}
|
{{/installable}}
|
||||||
{{^installable}}
|
{{^installable}}
|
||||||
|
@ -102,7 +89,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p class="alert alert-warning">
|
<p class="alert alert-warning">
|
||||||
<span class="fa-warning"></span>
|
<span class="fa-fw fa-warning"></span>
|
||||||
{{t 'confirm_install_custom_app'}}
|
{{t 'confirm_install_custom_app'}}
|
||||||
</p>
|
</p>
|
||||||
<form action="#/apps/install/custom" method="POST" class="form-horizontal">
|
<form action="#/apps/install/custom" method="POST" class="form-horizontal">
|
||||||
|
@ -111,7 +98,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<input type="url" id="url" name="url" class="form-control" value="" placeholder="https://github.com/USER/REPOSITORY" required pattern="^https://github.com/[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_.]+[/]?$">
|
<input type="url" id="url" name="url" class="form-control" value="" placeholder="https://github.com/USER/REPOSITORY" required pattern="^https://github.com/[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_.]+[/]?$">
|
||||||
<p class="text-warning">
|
<p class="text-warning">
|
||||||
<span class="fa-github"></span> {{t 'custom_app_url_only_github'}}
|
<span class="fa-fw fa-github"></span> {{t 'custom_app_url_only_github'}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
23
src/views/app/app_catalog_home.ms
Normal file
23
src/views/app/app_catalog_home.ms
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<div class="btn-breadcrumb">
|
||||||
|
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
||||||
|
<a href="#/apps">{{t 'applications'}}</a>
|
||||||
|
<a href="#/apps/catalog">{{t 'catalog'}}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="separator"></div>
|
||||||
|
|
||||||
|
<div id="category-selector" class="list-group grid">
|
||||||
|
{{#categories}}
|
||||||
|
<a class="app-category-card panel panel-default" href="#/apps/catalog/{{id}}">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h2 class="app-category-title"><span class="fa-fw fa-{{icon}}"></span> {{title}}</h2>
|
||||||
|
<h3 class="app-category-card-desc">{{description}}</h3>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{/categories}}
|
||||||
|
<a class="app-category-card" href="#/apps/catalog/all">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h2 class="app-category-title" style="padding-top: 3em'"><span class="fa-fw fa-search"></span> {{t 'all_apps'}}</h2>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
|
@ -1,8 +1,8 @@
|
||||||
<div class="btn-breadcrumb">
|
<div class="btn-breadcrumb">
|
||||||
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
||||||
<a href="#/apps">{{t 'applications'}}</a>
|
<a href="#/apps">{{t 'applications'}}</a>
|
||||||
<a href="#/apps/catalog">{{t 'install'}}</a>
|
<a href="#/apps/catalog">{{t 'catalog'}}</a>
|
||||||
<a href="#/apps/install/{{id}}">{{manifest.name}}</a>
|
<a href="#/apps/install/{{id}}">{{t 'install_name' manifest.name}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
|
|
Loading…
Reference in a new issue