Group apps by domain

This commit is contained in:
Johannes Zellner
2019-03-25 10:42:31 +01:00
parent ac86b7a954
commit 57a41cde9d
3 changed files with 90 additions and 97 deletions
+14 -19
View File
@@ -245,6 +245,11 @@ h1, h2, h3 {
// Apps view // Apps view
// ---------------------------- // ----------------------------
.app-grid {
display: flex;
flex-wrap: wrap;
}
.grid-item { .grid-item {
padding: 10px; padding: 10px;
min-width: 225px; min-width: 225px;
@@ -260,14 +265,8 @@ h1, h2, h3 {
} }
} }
.grid-item:hover .grid-item-bottom {
@media(min-width:768px) {
opacity: 1;
right: 10px;
}
}
.grid-item-content { .grid-item-content {
position: relative; // required to make action buttons positioned absolute within the element
background-color: white; background-color: white;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1); box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
border-radius: 2px; border-radius: 2px;
@@ -284,21 +283,10 @@ h1, h2, h3 {
font-family: $font-family-heading; font-family: $font-family-heading;
} }
.grid-item-bottom-mobile { .grid-item-actions {
padding: 10px 15px;
border-top: 1px solid #ddd;
background-color: white;
@media(min-width:768px) {
display: none;
}
}
.grid-item-bottom {
display: none; display: none;
position: absolute; position: absolute;
top: 20px; top: 20px;
padding: 10px 15px;
right: -10px; right: -10px;
opacity: 0; opacity: 0;
background-color: transparent; background-color: transparent;
@@ -310,6 +298,13 @@ h1, h2, h3 {
} }
} }
.grid-item:hover .grid-item-actions {
@media(min-width:768px) {
opacity: 1;
right: 10px;
}
}
.app-update-badge { .app-update-badge {
position: absolute; position: absolute;
right: 0; right: 0;
+61 -76
View File
@@ -520,92 +520,77 @@
</div> </div>
<div class="animateMeOpacity ng-hide" ng-show="installedApps.length > 0"> <div class="animateMeOpacity ng-hide" ng-show="installedApps.length > 0">
<div class="col-sm-1 grid-item" ng-repeat="app in installedApps | orderBy:'location'"> <div ng-repeat="domain in domains">
<div style="background-color: white;" class="highlight grid-item-content" uib-tooltip="{{ app.fqdn }}"> <h2 style="padding-left: 15px;">{{ domain.domain }}</h2>
<a ng-href="{{ app | applicationLink }}" ng-click="((app | installError) === true && showError(app)) || ((app | appIsInstalledAndHealthy) && app.pendingPostInstallConfirmation && appPostInstallConfirm.show(app))" target="_blank" ng-class="{ 'hand': (app | appIsInstalledAndHealthy) }"> <div class="app-grid">
<div class="grid-item-top"> <div class="grid-item" ng-repeat="app in installedApps | filter:{domain:domain.domain} | orderBy:'location'">
<div class="row"> <a ng-href="{{ app | applicationLink }}" ng-click="((app | installError) === true && showError(app)) || ((app | appIsInstalledAndHealthy) && app.pendingPostInstallConfirmation && appPostInstallConfirm.show(app))" target="_blank" ng-class="{ 'hand': (app | appIsInstalledAndHealthy) }">
<div class="col-xs-12 text-center" style="padding-left: 5px; padding-right: 5px;"> <div style="background-color: white;" class="highlight grid-item-content" uib-tooltip="{{ app.fqdn }}">
<br/> <div class="grid-item-top">
<img ng-src="{{app.iconUrl || 'img/appicon_fallback.png'}}" fallback-icon="img/appicon_fallback.png" appstore-icon="{{ app.iconUrlStore }}" onerror="imageErrorHandler(this)" class="app-icon"/> <div class="row">
</div> <div class="col-xs-12 text-center" style="padding-left: 5px; padding-right: 5px;">
</div> <br/>
<br/> <img ng-src="{{app.iconUrl || 'img/appicon_fallback.png'}}" fallback-icon="img/appicon_fallback.png" appstore-icon="{{ app.iconUrlStore }}" onerror="imageErrorHandler(this)" class="app-icon"/>
<div class="row">
<div class="col-xs-12 text-center">
<div class="grid-item-top-title" data-fittext>{{ app.location || app.fqdn }}</div>
<div class="text-muted status" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden" uib-tooltip="{{ app.message | shortAppMessage }}">
{{ app | installationStateLabel }}
</div>
<div class="status" ng-style="{ 'visibility': (app | installationActive) ? 'visible' : 'hidden' }">
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{ app.progress }}%"></div>
</div>
</div>
</div>
</div>
</div> </div>
<div class="grid-item-bottom-mobile" ng-show="user.admin || (config.features.spaces && app.ownerId === user.id)"> </div>
<div class="row"> <br/>
<div class="col-xs-4 text-left"> <div class="row">
<a href="" ng-click="appRestore.show(app)" ng-show="backupConfig.provider !== 'noop'"> <div class="col-xs-12 text-center">
<i class="fa fa-undo scale"></i> <div class="grid-item-top-title" data-fittext>{{ app.location || app.fqdn }}</div>
</a> <div class="text-muted status" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden" uib-tooltip="{{ app.message | shortAppMessage }}">
{{ app | installationStateLabel }}
<a href="" ng-click="appConfigure.show(app)" ng-show="app.installationState === 'installed' || app.installationState === 'pending_configure' || (app | installError)"> </div>
<i ng-hide="(app | installError)" class="fa fa-pencil-alt scale"></i> <div class="status" ng-style="{ 'visibility': (app | installationActive) ? 'visible' : 'hidden' }">
<i ng-show="(app | installError)" class="fa fa-wrench scale"></i> <div class="progress progress-striped active">
</a> <div class="progress-bar progress-bar-success" role="progressbar" style="width: {{ app.progress }}%"></div>
</div>
<div class="col-xs-4 text-center"></div>
<div class="col-xs-4 text-right">
<a href="" ng-click="showUninstall(app)">
<i class="fa fa-times scale"></i>
</a>
</div>
</div> </div>
</div>
</div> </div>
<div class="grid-item-bottom" ng-show="user.admin || (config.features.spaces && app.ownerId === user.id)"> </div>
<div style="text-align: center;"> </div>
<a href="" ng-click="showUninstall(app)" uib-tooltip="Uninstall" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-times scale"></i></a> <div class="grid-item-actions" ng-show="user.admin || (config.features.spaces && app.ownerId === user.id)">
</div> <div style="text-align: center;">
<a href="" ng-click="showUninstall(app)" uib-tooltip="Uninstall" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-times scale"></i></a>
</div>
<div style="text-align: center;"> <div style="text-align: center;">
<a href="" ng-click="appRestore.show(app)" ng-show="backupConfig.provider !== 'noop'" uib-tooltip="Backups" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-archive scale"></i></a> <a href="" ng-click="appRestore.show(app)" ng-show="backupConfig.provider !== 'noop'" uib-tooltip="Backups" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-archive scale"></i></a>
</div> </div>
<div ng-show="(app.installationState === 'installed' || app.installationState === 'pending_configure') && !(app | installError)" style="text-align: center;"> <div ng-show="(app.installationState === 'installed' || app.installationState === 'pending_configure') && !(app | installError)" style="text-align: center;">
<a href="" ng-click="appConfigure.show(app)" uib-tooltip="Configure" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-pencil-alt scale"></i></a> <a href="" ng-click="appConfigure.show(app)" uib-tooltip="Configure" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-pencil-alt scale"></i></a>
</div> </div>
<div ng-show="app | installError" style="text-align: center;"> <div ng-show="app | installError" style="text-align: center;">
<a href="" ng-click="appConfigure.show(app)" uib-tooltip="Repair" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-wrench scale"></i></a> <a href="" ng-click="appConfigure.show(app)" uib-tooltip="Repair" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-wrench scale"></i></a>
</div> </div>
<div style="text-align: center;"> <div style="text-align: center;">
<a ng-href="{{ '/terminal.html?id=' + app.id }}" target="_blank" uib-tooltip="Terminal" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-terminal scale"></i></a> <a ng-href="{{ '/terminal.html?id=' + app.id }}" target="_blank" uib-tooltip="Terminal" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-terminal scale"></i></a>
</div> </div>
<div style="text-align: center;"> <div style="text-align: center;">
<a ng-href="{{ '/logs.html?appId=' + app.id }}" target="_blank" uib-tooltip="Logs" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-file-alt scale"></i></a> <a ng-href="{{ '/logs.html?appId=' + app.id }}" target="_blank" uib-tooltip="Logs" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-file-alt scale"></i></a>
</div> </div>
<div style="text-align: center;"> <div style="text-align: center;">
<a href="" ng-click="showInformation(app)" uib-tooltip="Information" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-info-circle scale"></i></a> <a href="" ng-click="showInformation(app)" uib-tooltip="Information" tooltip-placement="right" tooltip-class="app-tooltip"><i class="fa fa-info-circle scale"></i></a>
</div> </div>
</div> </div>
<!-- we check the version here because the box updater does not know when an app gets updated --> <!-- we check the version here because the box updater does not know when an app gets updated -->
<div class="app-update-badge" ng-show="config.update.apps[app.id].manifest.version && config.update.apps[app.id].manifest.version !== app.manifest.version && (app | installSuccess)"> <div class="app-update-badge" ng-show="config.update.apps[app.id].manifest.version && config.update.apps[app.id].manifest.version !== app.manifest.version && (app | installSuccess)">
<a href="" ng-click="showUpdate(app, config.update.apps[app.id].manifest)" title="Update Available"> <a href="" ng-click="showUpdate(app, config.update.apps[app.id].manifest)" title="Update Available">
<span class="fa-stack fa-lg scale-small"> <span class="fa-stack fa-lg scale-small">
<i class="fa fa-circle fa-stack-2x text-success"></i> <i class="fa fa-circle fa-stack-2x text-success"></i>
<i class="fa fa-arrow-alt-circle-up fa-stack-1x fa-inverse"></i> <i class="fa fa-arrow-alt-circle-up fa-stack-1x fa-inverse"></i>
</span> </span>
</a> </a>
</div> </div>
</a> </div>
</div> </a>
</div>
</div> </div>
</div>
</div> </div>
</div> </div>
+15 -2
View File
@@ -10,6 +10,7 @@ angular.module('Application').controller('AppsController', ['$scope', '$location
$scope.config = Client.getConfig(); $scope.config = Client.getConfig();
$scope.user = Client.getUserInfo(); $scope.user = Client.getUserInfo();
$scope.domains = []; $scope.domains = [];
$scope.usedDomains = [];
$scope.groups = []; $scope.groups = [];
$scope.users = []; $scope.users = [];
$scope.backupConfig = {}; $scope.backupConfig = {};
@@ -657,8 +658,20 @@ angular.module('Application').controller('AppsController', ['$scope', '$location
}); });
} }
function refreshInstalledApps() {
Client.refreshInstalledApps();
var tmp = [];
$scope.installedApps.forEach(function (app) {
if (!tmp.find(function (d) { return d.domain === app.domain; })) tmp.push({ domain: app.domain, apps: [] });
tmp.find(function (d) { return d.domain === app.domain; }).apps.push(app);
});
$scope.usedDomains = tmp;
}
Client.onReady(function () { Client.onReady(function () {
Client.refreshInstalledApps(); // refresh the new list immediately when switching from another view (appstore) refreshInstalledApps(); // refresh the new list immediately when switching from another view (appstore)
$scope.spacesSuffix = $scope.user.username.replace(/\./g, '-'); $scope.spacesSuffix = $scope.user.username.replace(/\./g, '-');
@@ -669,7 +682,7 @@ angular.module('Application').controller('AppsController', ['$scope', '$location
if ($scope.user.admin && !$scope.config.managed) getBackupConfig(); // FIXME: detect disabled backups some other way if ($scope.user.admin && !$scope.config.managed) getBackupConfig(); // FIXME: detect disabled backups some other way
} }
var refreshAppsTimer = $interval(Client.refreshInstalledApps.bind(Client), 5000); var refreshAppsTimer = $interval(refreshInstalledApps, 5000);
$scope.$on('$destroy', function () { $scope.$on('$destroy', function () {
$interval.cancel(refreshAppsTimer); $interval.cancel(refreshAppsTimer);