forked from AkkomaGang/admin-fe
Merge branch 'feature/install-switch-frontends' into 'develop'
Ability to install frontends Closes #164 See merge request pleroma/admin-fe!197
This commit is contained in:
commit
1e5f128a56
28 changed files with 330 additions and 28 deletions
|
@ -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
|
- 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
|
- 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 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
|
### Changed
|
||||||
|
|
||||||
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import { baseName } from './utils'
|
import { baseName } from './utils'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
export async function deleteInstanceDocument(name, authHost, token) {
|
export async function deleteInstanceDocument(name, authHost, token) {
|
||||||
return await request({
|
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()}` } : {}
|
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
||||||
|
|
|
@ -416,6 +416,7 @@ export default {
|
||||||
moderationLog: 'Moderation Log'
|
moderationLog: 'Moderation Log'
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
|
submit: 'Submit',
|
||||||
settings: 'Settings',
|
settings: 'Settings',
|
||||||
instance: 'Instance',
|
instance: 'Instance',
|
||||||
upload: 'Upload',
|
upload: 'Upload',
|
||||||
|
@ -460,7 +461,27 @@ export default {
|
||||||
uploadImage: 'Upload image',
|
uploadImage: 'Upload image',
|
||||||
remove: 'Remove',
|
remove: 'Remove',
|
||||||
instancePanel: 'Instance Panel Document',
|
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: {
|
invites: {
|
||||||
inviteTokens: 'Invite tokens',
|
inviteTokens: 'Invite tokens',
|
||||||
|
@ -546,6 +567,5 @@ export default {
|
||||||
emptyPack: 'This emoji pack is empty',
|
emptyPack: 'This emoji pack is empty',
|
||||||
emojiWarning: 'Pack names cannot include any of the following characters: # / < > & +',
|
emojiWarning: 'Pack names cannot include any of the following characters: # / < > & +',
|
||||||
image: 'Image'
|
image: 'Image'
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import {
|
import {
|
||||||
deleteInstanceDocument,
|
deleteInstanceDocument,
|
||||||
fetchDescription,
|
fetchDescription,
|
||||||
|
fetchFrontends,
|
||||||
fetchSettings,
|
fetchSettings,
|
||||||
getInstanceDocument,
|
getInstanceDocument,
|
||||||
|
installFrontend,
|
||||||
removeSettings,
|
removeSettings,
|
||||||
updateInstanceDocument,
|
updateInstanceDocument,
|
||||||
updateSettings } from '@/api/settings'
|
updateSettings } from '@/api/settings'
|
||||||
|
@ -13,6 +15,7 @@ const settings = {
|
||||||
state: {
|
state: {
|
||||||
activeTab: 'instance',
|
activeTab: 'instance',
|
||||||
configDisabled: true,
|
configDisabled: true,
|
||||||
|
frontends: [],
|
||||||
db: {},
|
db: {},
|
||||||
description: [],
|
description: [],
|
||||||
instancePanel: '',
|
instancePanel: '',
|
||||||
|
@ -41,6 +44,9 @@ const settings = {
|
||||||
SET_DESCRIPTION: (state, data) => {
|
SET_DESCRIPTION: (state, data) => {
|
||||||
state.description = data
|
state.description = data
|
||||||
},
|
},
|
||||||
|
SET_FRONTENDS: (state, data) => {
|
||||||
|
state.frontends = data
|
||||||
|
},
|
||||||
SET_LOADING: (state, status) => {
|
SET_LOADING: (state, status) => {
|
||||||
state.loading = status
|
state.loading = status
|
||||||
},
|
},
|
||||||
|
@ -86,6 +92,10 @@ const settings = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
async FetchFrontends({ commit, getters }) {
|
||||||
|
const { data } = await fetchFrontends(getters.authHost, getters.token)
|
||||||
|
commit('SET_FRONTENDS', data)
|
||||||
|
},
|
||||||
async FetchInstanceDocument({ commit, getters }, name) {
|
async FetchInstanceDocument({ commit, getters }, name) {
|
||||||
const { data } = await getInstanceDocument(name, getters.authHost, getters.token)
|
const { data } = await getInstanceDocument(name, getters.authHost, getters.token)
|
||||||
if (name === 'instance-panel') {
|
if (name === 'instance-panel') {
|
||||||
|
@ -112,6 +122,10 @@ const settings = {
|
||||||
commit('TOGGLE_TABS', false)
|
commit('TOGGLE_TABS', false)
|
||||||
commit('SET_LOADING', 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) {
|
async RemoveInstanceDocument({ dispatch, getters }, name) {
|
||||||
await deleteInstanceDocument(name, getters.authHost, getters.token)
|
await deleteInstanceDocument(name, getters.authHost, getters.token)
|
||||||
await dispatch('FetchInstanceDocument', name)
|
await dispatch('FetchInstanceDocument', name)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<setting :setting-group="user" :data="userData"/>
|
<setting :setting-group="user" :data="userData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<setting :setting-group="oauth2" :data="oauth2Data"/>
|
<setting :setting-group="oauth2" :data="oauth2Data"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<setting :setting-group="kocaptcha" :data="kocaptchaData"/>
|
<setting :setting-group="kocaptcha" :data="kocaptchaData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<setting :setting-group="esshd" :data="esshdData"/>
|
<setting :setting-group="esshd" :data="esshdData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||||
|
<frontends-table />
|
||||||
|
<el-divider v-if="frontend" class="divider thick-line"/>
|
||||||
<el-form :model="frontendData" :label-position="labelPosition" :label-width="labelWidth">
|
<el-form :model="frontendData" :label-position="labelPosition" :label-width="labelWidth">
|
||||||
<setting :setting-group="frontend" :data="frontendData"/>
|
<setting :setting-group="frontend" :data="frontendData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
@ -32,7 +34,7 @@
|
||||||
<setting :setting-group="preload" :data="preloadData"/>
|
<setting :setting-group="preload" :data="preloadData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -41,11 +43,12 @@
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import i18n from '@/lang'
|
import i18n from '@/lang'
|
||||||
import Setting from './Setting'
|
import Setting from './Setting'
|
||||||
|
import FrontendsTable from './inputComponents/FrontendsTable'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Frontend',
|
name: 'Frontend',
|
||||||
components: { Setting },
|
components: { FrontendsTable, Setting },
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'settings'
|
'settings'
|
||||||
|
@ -80,6 +83,9 @@ export default {
|
||||||
frontendsData() {
|
frontendsData() {
|
||||||
return _.get(this.settings.settings, [':pleroma', ':frontends']) || {}
|
return _.get(this.settings.settings, [':pleroma', ':frontends']) || {}
|
||||||
},
|
},
|
||||||
|
isDesktop() {
|
||||||
|
return this.$store.state.app.device === 'desktop'
|
||||||
|
},
|
||||||
isMobile() {
|
isMobile() {
|
||||||
return this.$store.state.app.device === 'mobile'
|
return this.$store.state.app.device === 'mobile'
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<setting :setting-group="gopher" :data="gopherData"/>
|
<setting :setting-group="gopher" :data="gopherData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<setting :setting-group="webCacheTtl" :data="webCacheTtlData"/>
|
<setting :setting-group="webCacheTtl" :data="webCacheTtlData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
<setting :setting-group="streamer" :data="streamerData"/>
|
<setting :setting-group="streamer" :data="streamerData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<setting :setting-group="hackneyPools" :data="hackneyPoolsData"/>
|
<setting :setting-group="hackneyPools" :data="hackneyPoolsData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<setting :setting-group="linkFormatter" :data="linkFormatterData"/>
|
<setting :setting-group="linkFormatter" :data="linkFormatterData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<setting :setting-group="quack" :data="quackData"/>
|
<setting :setting-group="quack" :data="quackData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<setting :setting-group="newUsersDigestEmail" :data="newUsersDigestEmailData"/>
|
<setting :setting-group="newUsersDigestEmail" :data="newUsersDigestEmailData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<setting :setting-group="scriptInvalidation" :data="scriptInvalidationData"/>
|
<setting :setting-group="scriptInvalidation" :data="scriptInvalidationData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<setting :setting-group="richMedia" :data="richMediaData"/>
|
<setting :setting-group="richMedia" :data="richMediaData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<setting :setting-group="castAndValidate" :data="castAndValidateData"/>
|
<setting :setting-group="castAndValidate" :data="castAndValidateData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<setting :setting-group="rateLimiters" :data="rateLimitersData"/>
|
<setting :setting-group="rateLimiters" :data="rateLimitersData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<setting :setting-group="uploadAnonymizeFilename" :data="uploadAnonymizeFilenameData"/>
|
<setting :setting-group="uploadAnonymizeFilename" :data="uploadAnonymizeFilenameData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<setting :setting-group="vapidDetails" :data="vapidDetailsData"/>
|
<setting :setting-group="vapidDetails" :data="vapidDetailsData"/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="submit-button-container">
|
<div class="submit-button-container">
|
||||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
<template>
|
||||||
|
<span>
|
||||||
|
<el-button
|
||||||
|
v-if="buttonLoading"
|
||||||
|
:loading="true"
|
||||||
|
disabled
|
||||||
|
type="text"
|
||||||
|
size="small">
|
||||||
|
{{ $t('settings.inProcess') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-else-if="frontend.installed"
|
||||||
|
disabled
|
||||||
|
type="text"
|
||||||
|
size="small">
|
||||||
|
{{ $t('settings.installed') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
@click="installFrontend(frontend)">
|
||||||
|
{{ $t('settings.install') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import i18n from '@/lang'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FrontendStatusButton',
|
||||||
|
props: {
|
||||||
|
frontend: {
|
||||||
|
type: Object,
|
||||||
|
default: function() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
buttonLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async installFrontend({ name }) {
|
||||||
|
this.buttonLoading = true
|
||||||
|
try {
|
||||||
|
await this.$store.dispatch('InstallFrontend', { name })
|
||||||
|
} catch (e) {
|
||||||
|
this.buttonLoading = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.buttonLoading = false
|
||||||
|
this.$message({
|
||||||
|
message: i18n.t('settings.frontendSuccess'),
|
||||||
|
type: 'success',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
148
src/views/settings/components/inputComponents/FrontendsTable.vue
Normal file
148
src/views/settings/components/inputComponents/FrontendsTable.vue
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
<template>
|
||||||
|
<el-form :label-position="labelPosition" :label-width="labelWidth" class="frontend-container">
|
||||||
|
<el-form-item class="description-container">
|
||||||
|
<span class="setting-label">{{ $t('settings.availableFrontends') }}</span>
|
||||||
|
<span class="expl no-top-margin"><p>{{ $t('settings.installFrontends') }}</p></span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-table
|
||||||
|
:data="availableFrontends"
|
||||||
|
class="frontends-table">
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('settings.name')"
|
||||||
|
prop="name"
|
||||||
|
width="120"/>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('settings.git')"
|
||||||
|
prop="git"/>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('settings.installed')"
|
||||||
|
prop="installed">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<frontend-status-button :frontend="scope.row"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="frontends-button-container">
|
||||||
|
<el-button
|
||||||
|
:size="isDesktop ? 'medium' : 'mini'"
|
||||||
|
:icon="frontendInputOpen ? 'el-icon-minus' : 'el-icon-plus'"
|
||||||
|
circle
|
||||||
|
@click="toggleFrontendInput"/>
|
||||||
|
<span class="icons-button-desc">{{ $t('settings.installAnotherFrontend') }}</span>
|
||||||
|
</div>
|
||||||
|
<el-form v-if="frontendInputOpen" ref="frontendFormData" :rules="rules" :model="frontendFormData" label-width="130px">
|
||||||
|
<el-form-item :label="$t('settings.name')" class="frontend-form-input" prop="name">
|
||||||
|
<el-input v-model="frontendFormData.name"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('settings.ref')" class="frontend-form-input">
|
||||||
|
<el-input v-model="frontendFormData.ref"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('settings.file')" class="frontend-form-input">
|
||||||
|
<el-input v-model="frontendFormData.file"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('settings.buildUrl')" class="frontend-form-input">
|
||||||
|
<el-input v-model="frontendFormData.buildUrl"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('settings.buildDir')" class="frontend-form-input">
|
||||||
|
<el-input v-model="frontendFormData.buildDir"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item class="install-frontend-button">
|
||||||
|
<el-button :loading="buttonLoading" type="primary" @click="installNewFrontend">{{ $t('settings.install') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import i18n from '@/lang'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import FrontendStatusButton from './FrontendStatusButton'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FrontendsTable',
|
||||||
|
components: { FrontendStatusButton },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
buttonLoading: false,
|
||||||
|
frontendInputOpen: false,
|
||||||
|
frontendFormData: {
|
||||||
|
name: '',
|
||||||
|
ref: '',
|
||||||
|
file: '',
|
||||||
|
buildUrl: '',
|
||||||
|
buildDir: ''
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
name: { required: true, message: 'Please input Name', trigger: 'blur' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
'settings'
|
||||||
|
]),
|
||||||
|
availableFrontends() {
|
||||||
|
return this.settings.frontends
|
||||||
|
},
|
||||||
|
labelPosition() {
|
||||||
|
return this.isMobile ? 'top' : 'right'
|
||||||
|
},
|
||||||
|
labelWidth() {
|
||||||
|
if (this.isMobile) {
|
||||||
|
return '120px'
|
||||||
|
} else if (this.isTablet) {
|
||||||
|
return '200px'
|
||||||
|
} else {
|
||||||
|
return '280px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isDesktop() {
|
||||||
|
return this.$store.state.app.device === 'desktop'
|
||||||
|
},
|
||||||
|
isMobile() {
|
||||||
|
return this.$store.state.app.device === 'mobile'
|
||||||
|
},
|
||||||
|
isTablet() {
|
||||||
|
return this.$store.state.app.device === 'tablet'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
await this.$store.dispatch('FetchFrontends')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
installNewFrontend() {
|
||||||
|
this.$refs['frontendFormData'].validate(async(valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.buttonLoading = true
|
||||||
|
try {
|
||||||
|
await this.$store.dispatch('InstallFrontend', this.frontendFormData)
|
||||||
|
} catch (e) {
|
||||||
|
this.buttonLoading = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.buttonLoading = false
|
||||||
|
this.$message({
|
||||||
|
message: i18n.t('settings.frontendSuccess'),
|
||||||
|
type: 'success',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
this.frontendFormData = {
|
||||||
|
name: '',
|
||||||
|
ref: '',
|
||||||
|
file: '',
|
||||||
|
buildUrl: '',
|
||||||
|
buildDir: ''
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toggleFrontendInput() {
|
||||||
|
this.frontendInputOpen = !this.frontendInputOpen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -12,13 +12,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="icons-button-container">
|
<div class="icons-button-container">
|
||||||
<el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="addValueToIcons(index)"/>
|
<el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="addValueToIcons(index)"/>
|
||||||
<span class="icons-button-desc">Add another `key - value` pair to this icon</span>
|
<span class="icons-button-desc">{{ $t('settings.addKeyValuePair') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-divider class="divider"/>
|
<el-divider class="divider"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="icons-button-container">
|
<div class="icons-button-container">
|
||||||
<el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="addIconToIcons"/>
|
<el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="addIconToIcons"/>
|
||||||
<span class="icons-button-desc">Add another icon configuration</span>
|
<span class="icons-button-desc">{{ $t('settings.addIconConfig') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
@input="parseRateLimiter($event, setting.key, 'limit', 'oneLimit', rateLimitAllUsers)"/>
|
@input="parseRateLimiter($event, setting.key, 'limit', 'oneLimit', rateLimitAllUsers)"/>
|
||||||
<div class="limit-button-container">
|
<div class="limit-button-container">
|
||||||
<el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="toggleLimits([['', ''], ['', '']], setting.key)"/>
|
<el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="toggleLimits([['', ''], ['', '']], setting.key)"/>
|
||||||
<p class="expl limit-expl">Set different limits for unauthenticated and authenticated users</p>
|
<p class="expl limit-expl">{{ $t('settings.setLimits') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="rateLimitAuthUsers">
|
<div v-if="rateLimitAuthUsers">
|
||||||
<el-form-item class="rate-limit">
|
<el-form-item class="rate-limit">
|
||||||
<div class="rate-limit-label-container">
|
<div class="rate-limit-label-container">
|
||||||
<span class="rate-limit-label">
|
<span class="rate-limit-label">
|
||||||
Unauthenticated users:
|
{{ $t('settings.unauthenticatedUsers') }}:
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="rate-limit-content">
|
<div class="rate-limit-content">
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
<el-form-item class="rate-limit">
|
<el-form-item class="rate-limit">
|
||||||
<div class="rate-limit-label-container">
|
<div class="rate-limit-label-container">
|
||||||
<span class="rate-limit-label">
|
<span class="rate-limit-label">
|
||||||
Authenticated users:
|
{{ $t('settings.authenticatedUsers') }}:
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="rate-limit-content">
|
<div class="rate-limit-content">
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div class="limit-button-container">
|
<div class="limit-button-container">
|
||||||
<el-button :size="isDesktop ? 'medium' : 'mini'" class="icon-minus-button" icon="el-icon-minus" circle @click="toggleLimits(['', ''], setting.key)"/>
|
<el-button :size="isDesktop ? 'medium' : 'mini'" class="icon-minus-button" icon="el-icon-minus" circle @click="toggleLimits(['', ''], setting.key)"/>
|
||||||
<p class="expl limit-expl">Set limit for all users</p>
|
<p class="expl limit-expl">{{ $t('settings.setLimitsForAll') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -75,6 +75,20 @@
|
||||||
.form-container {
|
.form-container {
|
||||||
margin-bottom: 80px;
|
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 {
|
.grouped-settings-header {
|
||||||
margin: 0 0 14px 0;
|
margin: 0 0 14px 0;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +140,10 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.install-frontend-button {
|
||||||
|
margin-top: 15px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
.keyword-container {
|
.keyword-container {
|
||||||
width: 100%
|
width: 100%
|
||||||
}
|
}
|
||||||
|
@ -451,6 +469,15 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
}
|
}
|
||||||
|
.frontend-container {
|
||||||
|
margin: 0 15px 10px 15px;
|
||||||
|
.description-container {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frontend-form-input {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue