logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 7bb28bb23c61e2d648eecf5d59969d32631f78e8
parent 3ac67ab7274c199766d026fcf168bd2a3d4e2692
Author: Henry Jameson <me@hjkos.com>
Date:   Wed, 29 Mar 2023 00:58:07 +0300

frontends tab initial implementation, now you can (re)install frontends! yay!

Diffstat:

Msrc/App.scss22+++++++++++++++++++---
Asrc/components/settings_modal/admin_tabs/frontends_tab.js58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/settings_modal/admin_tabs/frontends_tab.scss13+++++++++++++
Asrc/components/settings_modal/admin_tabs/frontends_tab.vue72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/settings_modal/settings_modal.scss1-
Msrc/components/settings_modal/settings_modal_admin_content.js8+++-----
Msrc/i18n/en.json8++++++++
Msrc/modules/adminSettings.js15+++++++++++++++
Msrc/services/api/api.service.js42+++++++++++++++++++++++++++++++++++++++++-
9 files changed, 229 insertions(+), 10 deletions(-)

diff --git a/src/App.scss b/src/App.scss @@ -645,6 +645,19 @@ option { } } +.cards-list { + display: grid; + grid-auto-flow: row dense; + grid-template-columns: 1fr 1fr; + + li { + border: 1px solid var(--border); + border-radius: var(--inputRadius); + padding: 0.5em; + margin: 0.25em; + } +} + .btn-block { display: block; width: 100%; @@ -655,16 +668,19 @@ option { display: inline-flex; vertical-align: middle; - button { + button, + .button-dropdown { position: relative; flex: 1 1 auto; - &:not(:last-child) { + &:not(:last-child), + &:not(:last-child) .button-default { border-top-right-radius: 0; border-bottom-right-radius: 0; } - &:not(:first-child) { + &:not(:first-child), + &:not(:first-child) .button-default { border-top-left-radius: 0; border-bottom-left-radius: 0; } diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.js b/src/components/settings_modal/admin_tabs/frontends_tab.js @@ -0,0 +1,58 @@ +import BooleanSetting from '../helpers/boolean_setting.vue' +import ChoiceSetting from '../helpers/choice_setting.vue' +import IntegerSetting from '../helpers/integer_setting.vue' +import StringSetting from '../helpers/string_setting.vue' +import GroupSetting from '../helpers/group_setting.vue' +import Popover from 'src/components/popover/popover.vue' + +import SharedComputedObject from '../helpers/shared_computed_object.js' +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faGlobe +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faGlobe +) + +const FrontendsTab = { + provide () { + return { + defaultDraftMode: true, + defaultSource: 'admin' + } + }, + components: { + BooleanSetting, + ChoiceSetting, + IntegerSetting, + StringSetting, + GroupSetting, + Popover + }, + created () { + if (this.user.rights.admin) { + this.$store.dispatch('loadFrontendsStuff') + } + }, + computed: { + frontends () { + return this.$store.state.adminSettings.frontends + }, + ...SharedComputedObject() + }, + methods: { + update (frontend, suggestRef) { + const ref = suggestRef || frontend.refs[0] + const { name } = frontend + const payload = { name, ref } + + this.$store.state.api.backendInteractor.installFrontend({ payload }) + .then((externalUser) => { + this.$store.dispatch('loadFrontendsStuff') + }) + } + } +} + +export default FrontendsTab diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.scss b/src/components/settings_modal/admin_tabs/frontends_tab.scss @@ -0,0 +1,13 @@ +.frontends-tab { + .cards-list { + padding: 0; + } + + dd { + text-overflow: ellipsis; + word-wrap: nowrap; + white-space: nowrap; + overflow-x: hidden; + max-width: 80%; + } +} diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.vue b/src/components/settings_modal/admin_tabs/frontends_tab.vue @@ -0,0 +1,72 @@ +<template> + <div class="frontends-tab" :label="$t('admin_dash.tabs.frontends')"> + <div class="setting-item"> + <h2>{{ $t('admin_dash.tabs.frontends') }}</h2> + <ul class="setting-list cards-list"> + <li v-for="frontend in frontends" :key="frontend.name"> + <strong>{{ frontend.name }}</strong> + <dl> + <dt>{{ $t('admin_dash.frontend.repository') }}</dt> + <dd><a :href="frontend.git">{{ frontend.git }}</a></dd> + <dt v-if="expertLevel">{{ $t('admin_dash.frontend.versions') }}</dt> + <dd v-if="expertLevel">{{ frontend.refs }}</dd> + <dt v-if="expertLevel">{{ $t('admin_dash.frontend.build_url') }}</dt> + <dd v-if="expertLevel">{{ frontend.build_url }}</dd> + </dl> + <div> + <span class="btn-group"> + <button + class="button button-default btn" + type="button" + :title="$t('admin_dash.frontend.update')" + @click="update(frontend)" + > + {{ + frontend.installed + ? $t('admin_dash.frontend.reinstall') + : $t('admin_dash.frontend.install') + }} + </button> + <Popover + v-if="frontend.refs.length > 1" + trigger="click" + class="button-dropdown" + placement="bottom" + > + <template #content> + <div class="dropdown-menu"> + <button + v-for="ref in frontend.refs" + :key="ref" + class="button-default dropdown-item" + @click="update(frontend, ref)" + > + <i18n-t keypath="admin_dash.frontend.install_version"> + <template #version> + <code>{{ ref }}</code> + </template> + </i18n-t> + </button> + </div> + </template> + <template #trigger> + <button + class="button button-default btn" + type="button" + :title="$t('admin_dash.frontend.update')" + > + <FAIcon icon="chevron-down" /> + </button> + </template> + </Popover> + </span> + </div> + </li> + </ul> + </div> + </div> +</template> + +<script src="./frontends_tab.js"></script> + +<style lang="scss" src="./frontends_tab.scss"></style> diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss @@ -43,7 +43,6 @@ .btn { min-height: 2em; - min-width: 10em; padding: 0 2em; } } diff --git a/src/components/settings_modal/settings_modal_admin_content.js b/src/components/settings_modal/settings_modal_admin_content.js @@ -1,9 +1,8 @@ import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' -import DataImportExportTab from './tabs/data_import_export_tab.vue' -import MutesAndBlocksTab from './tabs/mutes_and_blocks_tab.vue' import InstanceTab from './admin_tabs/instance_tab.vue' import LimitsTab from './admin_tabs/limits_tab.vue' +import FrontendsTab from './admin_tabs/frontends_tab.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -32,10 +31,9 @@ const SettingsModalAdminContent = { components: { TabSwitcher, - DataImportExportTab, - MutesAndBlocksTab, InstanceTab, - LimitsTab + LimitsTab, + FrontendsTab }, computed: { user () { diff --git a/src/i18n/en.json b/src/i18n/en.json @@ -873,6 +873,14 @@ "users": "User profile limits", "profile_fields": "Profile fields limits", "user_uploads": "Profile media limits" + }, + "frontend": { + "repository": "Repository link", + "versions": "Available versions", + "build_url": "Build URL", + "reinstall": "Reinstall", + "install": "Install", + "install_version": "Install version {version}" } }, "time": { diff --git a/src/modules/adminSettings.js b/src/modules/adminSettings.js @@ -1,6 +1,7 @@ import { set, get, cloneDeep, differenceWith, isEqual, flatten } from 'lodash' export const defaultState = { + frontends: [], loaded: false, needsReboot: null, config: null, @@ -23,6 +24,16 @@ const adminSettingsStorage = { state.loaded = false state.dbConfigEnabled = false }, + setAvailableFrontends (state, { frontends }) { + state.frontends = frontends.map(f => { + if (f.name === 'pleroma-fe') { + f.refs = ['master', 'develop'] + } else { + f.refs = [f.ref] + } + return f + }) + }, updateAdminSettings (state, { config, modifiedPaths }) { state.loaded = true state.dbConfigEnabled = true @@ -48,6 +59,10 @@ const adminSettingsStorage = { } }, actions: { + loadFrontendsStuff ({ state, rootState, dispatch, commit }) { + rootState.api.backendInteractor.fetchAvailableFrontends() + .then(frontends => commit('setAvailableFrontends', { frontends })) + }, loadAdminStuff ({ state, rootState, dispatch, commit }) { rootState.api.backendInteractor.fetchInstanceDBConfig() .then(backendDbConfig => { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js @@ -110,6 +110,8 @@ const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcemen const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config' const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions' +const PLEROMA_ADMIN_FRONTENDS_URL = '/api/pleroma/admin/frontends' +const PLEROMA_ADMIN_FRONTENDS_INSTALL_URL = '/api/pleroma/admin/frontends/install' const oldfetch = window.fetch @@ -1693,6 +1695,21 @@ const fetchInstanceConfigDescriptions = ({ credentials }) => { }) } +const fetchAvailableFrontends = ({ credentials }) => { + return fetch(PLEROMA_ADMIN_FRONTENDS_URL, { + headers: authHeaders(credentials) + }) + .then((response) => { + if (response.ok) { + return response.json() + } else { + return { + error: response + } + } + }) +} + const pushInstanceDBConfig = ({ credentials, payload }) => { return fetch(PLEROMA_ADMIN_CONFIG_URL, { headers: { @@ -1714,6 +1731,27 @@ const pushInstanceDBConfig = ({ credentials, payload }) => { }) } +const installFrontend = ({ credentials, payload }) => { + return fetch(PLEROMA_ADMIN_FRONTENDS_INSTALL_URL, { + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...authHeaders(credentials) + }, + method: 'POST', + body: JSON.stringify(payload) + }) + .then((response) => { + if (response.ok) { + return response.json() + } else { + return { + error: response + } + } + }) +} + const apiService = { verifyCredentials, fetchTimeline, @@ -1830,7 +1868,9 @@ const apiService = { adminFetchAnnouncements, fetchInstanceDBConfig, fetchInstanceConfigDescriptions, - pushInstanceDBConfig + fetchAvailableFrontends, + pushInstanceDBConfig, + installFrontend } export default apiService