diff --git a/CHANGELOG.md b/CHANGELOG.md
index c160a876..061b637b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add ability to configure Media Preview Proxy, User Backup, Websocket based federation and Pleroma.Web.Endpoint.MetricsExporter settings
- Mobile and Tablet UI for Single Report show page
- Ability to set rules and conditions for rendering settings (e.g. `:proxy_remote` setting is hidden if `:uploader` setting is set to `Pleroma.Uploaders.Local`)
+- Ability to install new frontends from the Frontend tab in the Settings section
+
### Changed
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
diff --git a/src/api/settings.js b/src/api/settings.js
index 8c543a7e..f07ece4d 100644
--- a/src/api/settings.js
+++ b/src/api/settings.js
@@ -1,6 +1,7 @@
import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'
+import _ from 'lodash'
export async function deleteInstanceDocument(name, authHost, token) {
return await request({
@@ -68,4 +69,24 @@ export async function removeSettings(configs, authHost, token) {
})
}
+export async function fetchFrontends(authHost, token) {
+ return await request({
+ baseURL: baseName(authHost),
+ url: `/api/pleroma/admin/frontends`,
+ method: 'get',
+ headers: authHeaders(token)
+ })
+}
+
+export async function installFrontend(data, authHost, token) {
+ const filteredData = _.pickBy(data)
+ return await request({
+ baseURL: baseName(authHost),
+ url: `/api/pleroma/admin/frontends/install`,
+ method: 'post',
+ headers: authHeaders(token),
+ data: filteredData
+ })
+}
+
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
diff --git a/src/lang/en.js b/src/lang/en.js
index 51269dc3..04ae5356 100644
--- a/src/lang/en.js
+++ b/src/lang/en.js
@@ -416,6 +416,7 @@ export default {
moderationLog: 'Moderation Log'
},
settings: {
+ submit: 'Submit',
settings: 'Settings',
instance: 'Instance',
upload: 'Upload',
@@ -460,7 +461,27 @@ export default {
uploadImage: 'Upload image',
remove: 'Remove',
instancePanel: 'Instance Panel Document',
- termsOfServices: 'Terms of Service'
+ termsOfServices: 'Terms of Service',
+ availableFrontends: 'Available Frontends',
+ installFrontends: 'This is the list of available frontends. You can switch to one of the listed frontends or specify all the required options and install another frontend',
+ install: 'Install',
+ installed: 'Installed',
+ name: 'Name',
+ git: 'Git',
+ installAnotherFrontend: 'Install another frontend',
+ addKeyValuePair: 'Add another `key - value` pair to this icon',
+ addIconConfig: 'Add another icon configuration',
+ setLimits: 'Set different limits for unauthenticated and authenticated users',
+ unauthenticatedUsers: 'Unauthenticated users',
+ authenticatedUsers: 'Authenticated users',
+ setLimitsForAll: 'Set limit for all users',
+ ref: 'Ref',
+ file: 'File',
+ buildUrl: 'Build URL',
+ buildDir: 'Build Directory',
+ frontendSuccess: 'Frontend installed successfully!',
+ frontendStartedInstallation: 'Installation started',
+ inProcess: 'In process'
},
invites: {
inviteTokens: 'Invite tokens',
@@ -546,6 +567,5 @@ export default {
emptyPack: 'This emoji pack is empty',
emojiWarning: 'Pack names cannot include any of the following characters: # / < > & +',
image: 'Image'
-
}
}
diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js
index 6e30a21f..61738507 100644
--- a/src/store/modules/settings.js
+++ b/src/store/modules/settings.js
@@ -1,8 +1,10 @@
import {
deleteInstanceDocument,
fetchDescription,
+ fetchFrontends,
fetchSettings,
getInstanceDocument,
+ installFrontend,
removeSettings,
updateInstanceDocument,
updateSettings } from '@/api/settings'
@@ -13,6 +15,7 @@ const settings = {
state: {
activeTab: 'instance',
configDisabled: true,
+ frontends: [],
db: {},
description: [],
instancePanel: '',
@@ -41,6 +44,9 @@ const settings = {
SET_DESCRIPTION: (state, data) => {
state.description = data
},
+ SET_FRONTENDS: (state, data) => {
+ state.frontends = data
+ },
SET_LOADING: (state, status) => {
state.loading = status
},
@@ -86,6 +92,10 @@ const settings = {
}
},
actions: {
+ async FetchFrontends({ commit, getters }) {
+ const { data } = await fetchFrontends(getters.authHost, getters.token)
+ commit('SET_FRONTENDS', data)
+ },
async FetchInstanceDocument({ commit, getters }, name) {
const { data } = await getInstanceDocument(name, getters.authHost, getters.token)
if (name === 'instance-panel') {
@@ -112,6 +122,10 @@ const settings = {
commit('TOGGLE_TABS', false)
commit('SET_LOADING', false)
},
+ async InstallFrontend({ commit, getters }, { name, ref, file, buildUrl, buildDir }) {
+ const { data } = await installFrontend({ name, ref, file, build_url: buildUrl, build_dir: buildDir }, getters.authHost, getters.token)
+ commit('SET_FRONTENDS', data)
+ },
async RemoveInstanceDocument({ dispatch, getters }, name) {
await deleteInstanceDocument(name, getters.authHost, getters.token)
await dispatch('FetchInstanceDocument', name)
diff --git a/src/views/settings/components/ActivityPub.vue b/src/views/settings/components/ActivityPub.vue
index e18a2267..38c1a739 100644
--- a/src/views/settings/components/ActivityPub.vue
+++ b/src/views/settings/components/ActivityPub.vue
@@ -8,7 +8,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Authentication.vue b/src/views/settings/components/Authentication.vue
index 03c3e0c5..006fdf0c 100644
--- a/src/views/settings/components/Authentication.vue
+++ b/src/views/settings/components/Authentication.vue
@@ -16,7 +16,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Captcha.vue b/src/views/settings/components/Captcha.vue
index 819e2b40..f39c076f 100644
--- a/src/views/settings/components/Captcha.vue
+++ b/src/views/settings/components/Captcha.vue
@@ -8,7 +8,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Esshd.vue b/src/views/settings/components/Esshd.vue
index a46f012d..a3141563 100644
--- a/src/views/settings/components/Esshd.vue
+++ b/src/views/settings/components/Esshd.vue
@@ -4,7 +4,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Frontend.vue b/src/views/settings/components/Frontend.vue
index 894f8f51..574051be 100644
--- a/src/views/settings/components/Frontend.vue
+++ b/src/views/settings/components/Frontend.vue
@@ -1,5 +1,7 @@
@@ -41,11 +43,12 @@
import { mapGetters } from 'vuex'
import i18n from '@/lang'
import Setting from './Setting'
+import FrontendsTable from './inputComponents/FrontendsTable'
import _ from 'lodash'
export default {
name: 'Frontend',
- components: { Setting },
+ components: { FrontendsTable, Setting },
computed: {
...mapGetters([
'settings'
@@ -80,6 +83,9 @@ export default {
frontendsData() {
return _.get(this.settings.settings, [':pleroma', ':frontends']) || {}
},
+ isDesktop() {
+ return this.$store.state.app.device === 'desktop'
+ },
isMobile() {
return this.$store.state.app.device === 'mobile'
},
diff --git a/src/views/settings/components/Gopher.vue b/src/views/settings/components/Gopher.vue
index ffc2fa19..2382b987 100644
--- a/src/views/settings/components/Gopher.vue
+++ b/src/views/settings/components/Gopher.vue
@@ -4,7 +4,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Http.vue b/src/views/settings/components/Http.vue
index 8aa8a23b..87a6d94b 100644
--- a/src/views/settings/components/Http.vue
+++ b/src/views/settings/components/Http.vue
@@ -16,7 +16,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Instance.vue b/src/views/settings/components/Instance.vue
index e3dacea2..f751e8dc 100644
--- a/src/views/settings/components/Instance.vue
+++ b/src/views/settings/components/Instance.vue
@@ -45,7 +45,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/JobQueue.vue b/src/views/settings/components/JobQueue.vue
index d2691af8..1a07356d 100644
--- a/src/views/settings/components/JobQueue.vue
+++ b/src/views/settings/components/JobQueue.vue
@@ -24,7 +24,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/LinkFormatter.vue b/src/views/settings/components/LinkFormatter.vue
index cb44a457..c92f1a4f 100644
--- a/src/views/settings/components/LinkFormatter.vue
+++ b/src/views/settings/components/LinkFormatter.vue
@@ -4,7 +4,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Logger.vue b/src/views/settings/components/Logger.vue
index 3a3abdba..b350c07d 100644
--- a/src/views/settings/components/Logger.vue
+++ b/src/views/settings/components/Logger.vue
@@ -16,7 +16,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/MRF.vue b/src/views/settings/components/MRF.vue
index dd92b3cb..36e548c2 100644
--- a/src/views/settings/components/MRF.vue
+++ b/src/views/settings/components/MRF.vue
@@ -7,7 +7,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Mailer.vue b/src/views/settings/components/Mailer.vue
index 65ec18e0..ee0e8475 100644
--- a/src/views/settings/components/Mailer.vue
+++ b/src/views/settings/components/Mailer.vue
@@ -20,7 +20,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/MediaProxy.vue b/src/views/settings/components/MediaProxy.vue
index 701a28ff..3c9ebc47 100644
--- a/src/views/settings/components/MediaProxy.vue
+++ b/src/views/settings/components/MediaProxy.vue
@@ -16,7 +16,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Metadata.vue b/src/views/settings/components/Metadata.vue
index d22be109..3326bb6f 100644
--- a/src/views/settings/components/Metadata.vue
+++ b/src/views/settings/components/Metadata.vue
@@ -8,7 +8,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Other.vue b/src/views/settings/components/Other.vue
index 91a9fe2a..86a5507e 100644
--- a/src/views/settings/components/Other.vue
+++ b/src/views/settings/components/Other.vue
@@ -26,7 +26,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/RateLimiters.vue b/src/views/settings/components/RateLimiters.vue
index f7f0c976..42b84782 100644
--- a/src/views/settings/components/RateLimiters.vue
+++ b/src/views/settings/components/RateLimiters.vue
@@ -4,7 +4,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/Upload.vue b/src/views/settings/components/Upload.vue
index 124de255..2251df24 100644
--- a/src/views/settings/components/Upload.vue
+++ b/src/views/settings/components/Upload.vue
@@ -24,7 +24,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/WebPush.vue b/src/views/settings/components/WebPush.vue
index 0a09c17d..c84cae18 100644
--- a/src/views/settings/components/WebPush.vue
+++ b/src/views/settings/components/WebPush.vue
@@ -4,7 +4,7 @@
- Submit
+ {{ $t('settings.submit') }}
diff --git a/src/views/settings/components/inputComponents/FrontendStatusButton.vue b/src/views/settings/components/inputComponents/FrontendStatusButton.vue
new file mode 100644
index 00000000..939f4f4b
--- /dev/null
+++ b/src/views/settings/components/inputComponents/FrontendStatusButton.vue
@@ -0,0 +1,64 @@
+
+
+
+ {{ $t('settings.inProcess') }}
+
+
+ {{ $t('settings.installed') }}
+
+
+ {{ $t('settings.install') }}
+
+
+
+
+
diff --git a/src/views/settings/components/inputComponents/FrontendsTable.vue b/src/views/settings/components/inputComponents/FrontendsTable.vue
new file mode 100644
index 00000000..fa51c903
--- /dev/null
+++ b/src/views/settings/components/inputComponents/FrontendsTable.vue
@@ -0,0 +1,148 @@
+
+
+
+ {{ $t('settings.availableFrontends') }}
+ {{ $t('settings.installFrontends') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.installAnotherFrontend') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.install') }}
+
+
+
+
+
+
+
diff --git a/src/views/settings/components/inputComponents/IconsInput.vue b/src/views/settings/components/inputComponents/IconsInput.vue
index e2f09165..1b4f1e9d 100644
--- a/src/views/settings/components/inputComponents/IconsInput.vue
+++ b/src/views/settings/components/inputComponents/IconsInput.vue
@@ -12,13 +12,13 @@
- Add another `key - value` pair to this icon
+ {{ $t('settings.addKeyValuePair') }}
- Add another icon configuration
+ {{ $t('settings.addIconConfig') }}
diff --git a/src/views/settings/components/inputComponents/RateLimitInput.vue b/src/views/settings/components/inputComponents/RateLimitInput.vue
index 60668369..18deaf0d 100644
--- a/src/views/settings/components/inputComponents/RateLimitInput.vue
+++ b/src/views/settings/components/inputComponents/RateLimitInput.vue
@@ -16,14 +16,14 @@
@input="parseRateLimiter($event, setting.key, 'limit', 'oneLimit', rateLimitAllUsers)"/>
- Unauthenticated users:
+ {{ $t('settings.unauthenticatedUsers') }}:
@@ -49,7 +49,7 @@
- Authenticated users:
+ {{ $t('settings.authenticatedUsers') }}:
diff --git a/src/views/settings/styles/main.scss b/src/views/settings/styles/main.scss
index c55208ad..5858267b 100644
--- a/src/views/settings/styles/main.scss
+++ b/src/views/settings/styles/main.scss
@@ -75,6 +75,20 @@
.form-container {
margin-bottom: 80px;
}
+ .frontend-container {
+ margin-right: 30px;
+ }
+ .frontend-form-input {
+ margin-top: 20px;
+ }
+ .frontends-button-container {
+ width: 100%;
+ margin-top: 15px;
+ }
+ .frontends-table {
+ width: 100%;
+ margin-right: 30px;
+ }
.grouped-settings-header {
margin: 0 0 14px 0;
}
@@ -126,6 +140,10 @@
width: 100%;
}
}
+ .install-frontend-button {
+ margin-top: 15px;
+ float: right;
+ }
.keyword-container {
width: 100%
}
@@ -451,6 +469,15 @@
justify-content: space-between;
margin: 0 5px;
}
+ .frontend-container {
+ margin: 0 15px 10px 15px;
+ .description-container {
+ margin: 0;
+ }
+ }
+ .frontend-form-input {
+ margin-top: 0;
+ }
h1 {
font-size: 24px;
}