add AppList view/route

This commit is contained in:
Axolotle 2020-09-28 00:28:42 +02:00
parent 2dfe5746af
commit fd13c58250
4 changed files with 110 additions and 2 deletions

View file

@ -285,9 +285,13 @@
"search": { "search": {
"domain": "Search for domains...", "domain": "Search for domains...",
"group": "Search for groups...", "group": "Search for groups...",
"installed_app": "Search for installed apps...",
"service": "Search for services", "service": "Search for services",
"user": "Search for users...", "user": "Search for users...",
"logs": "Search in logs..." "logs": "Search in logs...",
"not_found": {
"installed_app": "There is no apps matching your search query."
}
}, },
"search_for_apps": "Search for apps...", "search_for_apps": "Search for apps...",
"select_all": "Select all", "select_all": "Select all",

View file

@ -156,6 +156,16 @@ const routes = [
} }
}, },
/*
APPS
*/
{
name: 'app-list',
path: '/apps',
component: () => import(/* webpackChunkName: "views/apps" */ '@/views/app/AppList'),
meta: { breadcrumb: [{ name: 'app-list', trad: 'applications' }] }
},
/* /*
SYSTEM UPDATE SYSTEM UPDATE
*/ */

View file

@ -23,7 +23,7 @@ export default {
menu: [ menu: [
{ id: 0, routeName: 'user-list', icon: 'users', translation: 'users' }, { id: 0, routeName: 'user-list', icon: 'users', translation: 'users' },
{ id: 1, routeName: 'domain-list', icon: 'globe', translation: 'domains' }, { id: 1, routeName: 'domain-list', icon: 'globe', translation: 'domains' },
{ id: 2, routeName: 'apps', icon: 'cubes', translation: 'applications' }, { id: 2, routeName: 'app-list', icon: 'cubes', translation: 'applications' },
{ id: 3, routeName: 'update', icon: 'refresh', translation: 'system_update' }, { id: 3, routeName: 'update', icon: 'refresh', translation: 'system_update' },
{ id: 4, routeName: 'service-list', icon: 'cog', translation: 'services' }, { id: 4, routeName: 'service-list', icon: 'cog', translation: 'services' },
{ id: 5, routeName: 'tool-list', icon: 'wrench', translation: 'tools' }, { id: 5, routeName: 'tool-list', icon: 'wrench', translation: 'tools' },

View file

@ -0,0 +1,94 @@
<template>
<div class="app-list">
<div class="actions">
<b-input-group>
<b-input-group-prepend is-text>
<icon iname="search" />
</b-input-group-prepend>
<b-form-input
:disabled="!apps"
id="search-app" v-model="search"
:placeholder="$t('search.installed_app')"
/>
</b-input-group>
<div class="buttons">
<b-button variant="success" :to="{ name: 'app-catalog' }">
<icon iname="plus" /> {{ $t('install') }}
</b-button>
</div>
</div>
<b-alert v-if="apps === null" variant="warning" show>
<icon iname="exclamation-triangle" /> {{ $t('no_installed_apps') }}
</b-alert>
<b-list-group v-else-if="filteredApps && filteredApps.length">
<b-list-group-item
v-for="{ id, name, description, settings } in filteredApps" :key="id"
:to="{ name: 'app-info', params: { id }}"
class="d-flex justify-content-between align-items-center pr-0"
>
<div>
<h5>{{ settings.label }} <small>{{ name }}</small></h5>
<p class="m-0">
{{ description }}
</p>
</div>
<icon iname="chevron-right" class="lg fs-sm ml-auto" />
</b-list-group-item>
</b-list-group>
<b-alert v-else-if="filteredApps" variant="warning" show>
<icon iname="exclamation-triangle" /> {{ $t('search.not_found.installed_app') }}
</b-alert>
</div>
</template>
<script>
import api from '@/helpers/api'
export default {
name: 'AppList',
data () {
return {
search: '',
apps: undefined
}
},
computed: {
filteredApps () {
if (!this.apps) return
const search = this.search.toLowerCase()
const keys = ['id', 'name', 'description']
const match = (item) => item.toLowerCase().includes(search)
return this.apps.filter(app => {
if (match(app.settings.label)) return true
for (const key of keys) {
if (match(app[key])) return true
}
})
}
},
methods: {
fetchData () {
api.get('apps?full').then(({ apps }) => {
if (apps.length === 0) this.apps = null
this.apps = apps.sort((prev, app) => {
return prev.id > app.id ? 1 : -1
})
})
}
},
created () {
this.fetchData()
}
}
</script>
<style>
</style>