diff --git a/client/components/admin.vue b/client/components/admin.vue
index 92684c7a..3c35e55a 100644
--- a/client/components/admin.vue
+++ b/client/components/admin.vue
@@ -68,6 +68,9 @@
v-list-item(to='/editor', disabled)
v-list-item-avatar(size='24', tile): v-icon(color='grey lighten-2') mdi-playlist-edit
v-list-item-title {{ $t('admin:editor.title') }}
+ v-list-item(to='/extensions')
+ v-list-item-avatar(size='24', tile): v-icon mdi-chip
+ v-list-item-title {{ $t('admin:extensions.title') }}
v-list-item(to='/logging', disabled)
v-list-item-avatar(size='24', tile): v-icon(color='grey lighten-2') mdi-script-text-outline
v-list-item-title {{ $t('admin:logging.title') }}
@@ -170,6 +173,7 @@ const router = new VueRouter({
{ path: '/auth', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-auth.vue') },
{ path: '/rendering', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-rendering.vue') },
{ path: '/editor', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-editor.vue') },
+ { path: '/extensions', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-extensions.vue') },
{ path: '/logging', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-logging.vue') },
{ path: '/search', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-search.vue') },
{ path: '/storage', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-storage.vue') },
diff --git a/client/components/admin/admin-extensions.vue b/client/components/admin/admin-extensions.vue
new file mode 100644
index 00000000..f1186b72
--- /dev/null
+++ b/client/components/admin/admin-extensions.vue
@@ -0,0 +1,170 @@
+
+ v-container(fluid, grid-list-lg)
+ v-layout(row wrap)
+ v-flex(xs12)
+ .admin-header
+ img.animated.fadeInUp(src='/svg/icon-installing-updates.svg', alt='Extensions', style='width: 80px;')
+ .admin-header-title
+ .headline.primary--text.animated.fadeInLeft {{ $t('admin:extensions.title') }}
+ .subtitle-1.grey--text.animated.fadeInLeft {{ $t('admin:extensions.subtitle') }}
+ v-form.pt-3
+ v-layout(row wrap)
+ v-flex(xl6 lg8 xs12)
+ v-alert.mb-4(outlined, color='error', icon='mdi-alert')
+ span New extensions cannot be installed at the moment. This feature is coming in a future release.
+ v-expansion-panels.admin-extensions-exp(hover, popout)
+ v-expansion-panel(v-for='ext of extensions')
+ v-expansion-panel-header(disable-icon-rotate)
+ span {{ext.title}}
+ template(v-slot:actions)
+ v-chip(label, color='success', small, v-if='ext.installed') Installed
+ v-chip(label, color='warning', small, v-else) Not Installed
+ v-expansion-panel-content.pa-0
+ v-card.grey.lighten-5.radius-7(flat)
+ v-card-text
+ .body-2 {{ext.description}}
+ v-divider.my-4
+ .body-2
+ strong.mr-3 Supported Platforms:
+ v-chip.mr-1(label, small, :color='ext.platforms[`linux-amd64`] ? `success` : `error`') Linux (x64)
+ v-chip.mr-1(label, small, :color='ext.platforms[`linux-arm64`] ? `success` : `error`') Linux (arm64)
+ v-chip.mr-1(label, small, :color='ext.platforms[`linux-armv7`] ? `success` : `error`') Linux (armv7)
+ v-chip.mr-1(label, small, :color='ext.platforms.macos ? `success` : `error`') MacOS
+ v-chip.mr-1(label, small, :color='ext.platforms.windows ? `success` : `error`') Windows
+ v-card-chin
+ v-spacer
+ v-btn(disabled)
+ v-icon(left) mdi-plus
+ span Install
+
+
+
+
+
+
diff --git a/client/static/svg/icon-installing-updates.svg b/client/static/svg/icon-installing-updates.svg
new file mode 100644
index 00000000..3859fb2e
--- /dev/null
+++ b/client/static/svg/icon-installing-updates.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/package.json b/package.json
index dd6e1943..7ec3e7b1 100644
--- a/package.json
+++ b/package.json
@@ -162,6 +162,7 @@
"scim-query-filter-parser": "2.0.4",
"semver": "7.3.2",
"serve-favicon": "2.5.0",
+ "sharp": "0.25.2",
"simple-git": "1.132.0",
"solr-node": "1.2.1",
"sqlite3": "4.1.1",
diff --git a/yarn.lock b/yarn.lock
index 45b2fb0a..782de0bd 100644
Binary files a/yarn.lock and b/yarn.lock differ