mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
Merge pull request #242 from YunoHost/high-quality-apps-and-maintained-states
High quality apps and maintained states
This commit is contained in:
commit
8e8113d743
5 changed files with 130 additions and 41 deletions
|
@ -588,6 +588,10 @@ input[type='radio'].nice-radio {
|
|||
}
|
||||
}
|
||||
|
||||
.label-best {
|
||||
background-color: darkorchid;
|
||||
}
|
||||
|
||||
// only one card for small screens
|
||||
.app-card {
|
||||
width: 100%;
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
});
|
||||
|
||||
function levelToColor(level) {
|
||||
if (level >= 3) {
|
||||
if (level >= 8) {
|
||||
return 'best';
|
||||
}
|
||||
else if (level > 4) {
|
||||
return 'success';
|
||||
}
|
||||
else if (level >= 1) {
|
||||
|
@ -32,7 +35,10 @@
|
|||
}
|
||||
|
||||
function stateToColor(state) {
|
||||
if (state === "working" || state === "official") {
|
||||
if (state === "high-quality") {
|
||||
return 'best';
|
||||
}
|
||||
else if (state === "working") {
|
||||
return 'success';
|
||||
}
|
||||
else {
|
||||
|
@ -40,6 +46,21 @@
|
|||
}
|
||||
}
|
||||
|
||||
function maintainedStateToColor(state) {
|
||||
if ( state === "request_help" ) {
|
||||
return 'info';
|
||||
}
|
||||
else if ( state === "request_adoption" ) {
|
||||
return 'warning';
|
||||
}
|
||||
else if ( state === "orphaned" ) {
|
||||
return 'danger';
|
||||
}
|
||||
else {
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
|
||||
function combineColors(stateColor, levelColor, installable) {
|
||||
if (stateColor === "danger" || levelColor === "danger") {
|
||||
return 'danger';
|
||||
|
@ -53,36 +74,83 @@
|
|||
}
|
||||
}
|
||||
|
||||
function extractMaintainer(manifest) {
|
||||
if (manifest.maintainer === undefined)
|
||||
{
|
||||
if ((manifest.developer !== undefined) && (manifest.developer.name !== undefined))
|
||||
{
|
||||
return manifest.developer.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
else if (Array.isArray(manifest.maintainer))
|
||||
{
|
||||
maintainers = [];
|
||||
manifest.maintainer.forEach(function(maintainer) {
|
||||
if (maintainer.name !== undefined)
|
||||
{
|
||||
maintainers.push(maintainer.name);
|
||||
}
|
||||
});
|
||||
return maintainers.join(', ');
|
||||
}
|
||||
else if (manifest.maintainer.name !== undefined)
|
||||
{
|
||||
return manifest.maintainer.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
// List available apps
|
||||
app.get('#/apps/install', function (c) {
|
||||
c.api('/apps', function (data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
||||
c.api('/apps?raw', function (dataraw) { // http://api.yunohost.org/#!/app/app_list_get_8
|
||||
var apps = []
|
||||
$.each(data['apps'], function(k, v) {
|
||||
if (dataraw[v['id']]['state'] === "validated")
|
||||
app = dataraw[v['id']];
|
||||
app.level = parseInt(app.level);
|
||||
|
||||
if (app.high_quality && app.level > 7)
|
||||
{
|
||||
dataraw[v['id']]['state'] = "official";
|
||||
app.state = "high-quality";
|
||||
}
|
||||
if ( app.maintained === false )
|
||||
{
|
||||
app.maintained = "orphaned";
|
||||
}
|
||||
else if ( app.maintained === true )
|
||||
{
|
||||
app.maintained = "maintained";
|
||||
}
|
||||
var state = dataraw[v['id']]['state'];
|
||||
var levelFormatted = parseInt(dataraw[v['id']]['level']);
|
||||
var isWorking = (state === 'working' || state === 'official') && levelFormatted > 0;
|
||||
// Keep only the first instance of each app and remove community not working apps
|
||||
if (!v['id'].match(/__[0-9]{1,5}$/) && (dataraw[v['id']]['repository'] === 'yunohost' || state !== 'notworking')) {
|
||||
|
||||
dataraw[v['id']]['installable'] = (!v['installed'] || dataraw[v['id']].manifest.multi_instance)
|
||||
dataraw[v['id']]['isCommunity'] = !(dataraw[v['id']]['repository'] === 'yunohost');
|
||||
dataraw[v['id']]['levelFormatted'] = isNaN(levelFormatted) ? '?' : levelFormatted;
|
||||
dataraw[v['id']]['levelColor'] = levelToColor(levelFormatted);
|
||||
dataraw[v['id']]['stateColor'] = stateToColor(state);
|
||||
dataraw[v['id']]['installColor'] = combineColors(dataraw[v['id']]['stateColor'], dataraw[v['id']]['levelColor']);
|
||||
dataraw[v['id']]['displayLicense'] = (dataraw[v['id']]['manifest']['license'] !== undefined
|
||||
&& dataraw[v['id']]['manifest']['license'] !== 'free');
|
||||
dataraw[v['id']]['updateDate'] = dataraw[v['id']]['lastUpdate'] * 1000 || 0;
|
||||
dataraw[v['id']]['isSafe'] = (dataraw[v['id']]['installColor'] !== 'danger');
|
||||
dataraw[v['id']]['isWorking'] = isWorking ? "isworking" : "notFullyWorking";
|
||||
app.manifest.maintainer = extractMaintainer(app.manifest);
|
||||
var isWorking = (app.state === 'working' || app.state === "high-quality") && app.level > 0;
|
||||
|
||||
jQuery.extend(dataraw[v['id']], v);
|
||||
apps.push(dataraw[v['id']]);
|
||||
// Keep only the first instance of each app and remove not working apps
|
||||
if (!v['id'].match(/__[0-9]{1,5}$/) && (app.state !== 'notworking')) {
|
||||
|
||||
app.installable = (!v.installed || app.manifest.multi_instance)
|
||||
app.levelFormatted = isNaN(app.level) ? '?' : app.level;
|
||||
|
||||
app.levelColor = levelToColor(app.level);
|
||||
app.stateColor = stateToColor(app.state);
|
||||
app.maintainedColor = maintainedStateToColor(app.maintained);
|
||||
app.installColor = combineColors(app.stateColor, app.levelColor);
|
||||
|
||||
app.updateDate = app.lastUpdate * 1000 || 0;
|
||||
app.isSafe = (app.installColor !== 'danger');
|
||||
app.isWorking = isWorking ? "isworking" : "notFullyWorking";
|
||||
app.isHighQuality = (app.state === "high-quality") ? "isHighQuality" : "";
|
||||
app.decentQuality = (app.level > 4)?"decentQuality":"badQuality";
|
||||
|
||||
jQuery.extend(app, v);
|
||||
apps.push(app);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -107,8 +175,8 @@
|
|||
return inputMatch && classMatch;
|
||||
},
|
||||
|
||||
// Keep only official apps at first render
|
||||
cardGrid.isotope({ filter: '.isworking' });
|
||||
// Default filter is 'decent quality apps'
|
||||
cardGrid.isotope({ filter: '.decentQuality' });
|
||||
|
||||
jQuery('.dropdownFilter').on('click', function() {
|
||||
// change dropdown label
|
||||
|
@ -472,7 +540,8 @@
|
|||
app.helper('appInstallForm', function(appId, manifest, params) {
|
||||
var data = {
|
||||
id: appId,
|
||||
manifest: manifest
|
||||
manifest: manifest,
|
||||
displayLicense: (manifest['license'] !== undefined && manifest['license'] !== 'free')
|
||||
};
|
||||
|
||||
formatYunoHostStyleArguments(data.manifest.arguments.install, params);
|
||||
|
|
|
@ -29,16 +29,19 @@
|
|||
"app_install_cancel": "Installation cancelled.",
|
||||
"app_install_custom_no_manifest": "No manifest.json file",
|
||||
"app_list": "App list",
|
||||
"app_license": "License of the app",
|
||||
"app_level": "App level",
|
||||
"app_make_default": "Make default",
|
||||
"app_no_actions": "This application doesn't have any actions",
|
||||
"app_repository": "Application origin: ",
|
||||
"app_state": "Application state: ",
|
||||
"app_state_inprogress": "In progress",
|
||||
"app_state_notworking": "Not working",
|
||||
"app_state_official": "Official",
|
||||
"app_state_working": "Working",
|
||||
"app_state_inprogress": "in progress",
|
||||
"app_state_inprogress_explanation": "This maintainer of this app declared that this application is not ready yet for production use. BE CAREFUL!",
|
||||
"app_state_notworking": "not working",
|
||||
"app_state_notworking_explanation": "This maintainer of this app declared it as 'not working'. IT WILL BREAK YOUR SYSTEM!",
|
||||
"app_state_high-quality": "high quality",
|
||||
"app_state_high-quality_explanation": "This app is well-integrated with YunoHost. It has been (and is!) peer-reviewed by the YunoHost app team. It can be expected to be safe and maintained on the long-term.",
|
||||
"app_state_working": "working",
|
||||
"app_state_working_explanation": "The maintainer of this app declared it as 'working'. It means that it should be functional (c.f. application level) but is not necessarily peer-reviewed, it may still contain issues or is not fully integrated with YunoHost.",
|
||||
"application": "Application",
|
||||
"applications": "Applications",
|
||||
"archive_empty": "Empty archive",
|
||||
|
@ -189,6 +192,7 @@
|
|||
"label": "Label",
|
||||
"label_for_manifestname": "Label for %s",
|
||||
"level": "level",
|
||||
"license": "License",
|
||||
"loading": "Loading …",
|
||||
"local_archives": "Local archives",
|
||||
"local_ip": "Local IP",
|
||||
|
@ -199,6 +203,8 @@
|
|||
"logout": "Logout",
|
||||
"mailbox_quota_description": "For example, 700M is a CD, 4700M is a DVD.",
|
||||
"mailbox_quota_placeholder": "Leave empty or set to 0 to disable.",
|
||||
"maintained": "maintained",
|
||||
"maintained_details": "This app was maintained by its maintainer in the last few months.",
|
||||
"manage_apps": "Manage apps",
|
||||
"manage_domains": "Manage domains",
|
||||
"manage_users": "Manage users",
|
||||
|
@ -226,10 +232,13 @@
|
|||
"no_user_to_add": "No more users to add.",
|
||||
"non_compatible_api": "Non-compatible API",
|
||||
"ok": "OK",
|
||||
"only_official_apps": "Only official apps",
|
||||
"only_highquality_apps": "Only high-quality apps",
|
||||
"only_working_apps": "Only working apps",
|
||||
"only_decent_quality_apps": "Only decent quality apps",
|
||||
"open": "Open",
|
||||
"operations": "Operations",
|
||||
"orphaned": "not maintained",
|
||||
"orphaned_details": "This app is not maintained anymore. It may still be working but won't receive any upgrade. Feel free to come and revive it!",
|
||||
"os": "OS",
|
||||
"password": "Password",
|
||||
"password_confirmation": "Password confirmation",
|
||||
|
@ -279,6 +288,10 @@
|
|||
"reception": "Reception",
|
||||
"refresh_app_list": "Refresh list",
|
||||
"remove_access": "Remove access",
|
||||
"request_adoption": "waiting adoption",
|
||||
"request_adoption_details": "The current maintainer would like to stop maintaining this app. Feel free to propose yourself as the new maintainer!",
|
||||
"request_help": "need help",
|
||||
"request_help_details": "The current maintainer would like some help with the maintainance of this app. Feel free to come contribute on it!",
|
||||
"restore": "Restore",
|
||||
"run": "Run",
|
||||
"running": "Running",
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
<dd>{{id}}</dd>
|
||||
<dt>{{t 'description'}}</dt>
|
||||
<dd>{{description}}</dd>
|
||||
{{#displayLicense}}
|
||||
<dt>{{t 'license'}}</dt>
|
||||
<dd>{{manifest.license}}</dd>
|
||||
{{/displayLicense}}
|
||||
<dt>{{t 'version'}}</dt>
|
||||
<dd>{{manifest.version}}</dd>
|
||||
<dt>{{t 'multi_instance'}}</dt>
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
<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">
|
||||
<button type="button" role="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span id="app-cards-list-filter-text">{{t 'only_working_apps'}}</span> <span class="caret"></span>
|
||||
<span id="app-cards-list-filter-text">{{t 'only_decent_quality_apps'}}</span> <span class="caret"></span>
|
||||
</button>
|
||||
<ul id="dropdownFilter" class="dropdown-menu" data-filter="isworking" role="menu">
|
||||
<ul id="dropdownFilter" class="dropdown-menu" data-filter="decentQuality" role="menu">
|
||||
<li role="presentation" class="button dropdownFilter" data-filter="isHighQuality"><a class="menu-item" role="menu-item" tabindex="-1">{{t 'only_highquality_apps'}}</a></li>
|
||||
<li role="presentation" class="button dropdownFilter" data-filter="decentQuality"><a class="menu-item" role="menu-item" tabindex="-1">{{t 'only_decent_quality_apps'}}</a></li>
|
||||
<li role="presentation" class="button dropdownFilter" data-filter="isworking"><a class="menu-item" role="menu-item" tabindex="-1">{{t 'only_working_apps'}}</a></li>
|
||||
<li role="presentation" class="button dropdownFilter" data-filter="official"><a class="menu-item" role="menu-item" tabindex="-1">{{t 'only_official_apps'}}</a></li>
|
||||
<li role="presentation" class="button dropdownFilter" data-filter="*"><a class="menu-item" role="menu-item" tabindex="-1">{{t 'all_apps'}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -34,21 +35,19 @@
|
|||
|
||||
<div class="list-group grid">
|
||||
{{#apps}}
|
||||
<div class="app-card panel panel-default {{status}} {{state}} {{isWorking}} {{level}}-level">
|
||||
<div class="app-card panel panel-default {{status}} {{state}} {{isWorking}} {{isHighQuality}} {{decentQuality}} {{level}}-level">
|
||||
<div class="panel-body">
|
||||
<h2 class="app-title">{{name}}</h2>
|
||||
<div class="category">
|
||||
{{#isCommunity}} <span class="label label-info label-as-badge app-status">{{t 'community'}}</span>{{/isCommunity}}
|
||||
<span class="label label-{{stateColor}} label-as-badge app-state">{{t state}}</span>
|
||||
<span class="label label-{{stateColor}} label-as-badge app-state" title="{{t (concat 'app_state_' state '_explanation') }}">{{t (concat 'app_state_' state) }}</span>
|
||||
<a target="_BLANK" href="https://yunohost.org/#/packaging_apps_levels"><span class="label label-{{levelColor}} label-as-badge app-level" title="{{t 'app_level'}}">{{t 'level'}} {{levelFormatted}}</span></a>
|
||||
{{#displayLicense}}<span class="label label-default app-license" title="{{t 'app_license'}}">{{license}}</span>{{/displayLicense}}
|
||||
<span class="label label-{{maintainedColor}} label-as-badge maintained-status" title="{{t (concat maintained '_details') }}"> {{t maintained}}</span>
|
||||
</div>
|
||||
<div class="app-card-desc">{{description}}</div>
|
||||
</div>
|
||||
<div class="app-card-date-maintainer">
|
||||
<i class="fa-refresh"></i> {{formatDate updateDate day="numeric" month="long" year="numeric"}} -
|
||||
{{#maintained}}<span title="{{t 'current_maintainer_title'}}" class="maintained"></span><i class="fa-user"></i> {{manifest.maintainer.name}}</span>{{/maintained}}
|
||||
{{^maintained}}<i class="fas fa-warning"></i> {{t 'unmaintained'}}{{/maintained}}
|
||||
<span title="{{t 'current_maintainer_title'}}" class="maintained"></span><i class="fa-user"></i> {{manifest.maintainer}}</span>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{git.url}}" target="_BLANK" type="button" role="button" class="btn btn-default col-xs-4">
|
||||
|
|
Loading…
Add table
Reference in a new issue