Merge branch 'admin-tabs-2' into shigusegubu-themes3
This commit is contained in:
commit
03e9e5082f
8 changed files with 285 additions and 8 deletions
20
src/components/settings_modal/admin_tabs/rates_tab.js
Normal file
20
src/components/settings_modal/admin_tabs/rates_tab.js
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import RateSetting from '../helpers/rate_setting.vue'
|
||||||
|
|
||||||
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
|
|
||||||
|
const RatesTab = {
|
||||||
|
provide () {
|
||||||
|
return {
|
||||||
|
defaultDraftMode: true,
|
||||||
|
defaultSource: 'admin'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
RateSetting,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...SharedComputedObject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RatesTab
|
||||||
41
src/components/settings_modal/admin_tabs/rates_tab.vue
Normal file
41
src/components/settings_modal/admin_tabs/rates_tab.vue
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<div :label="$t('admin_dash.tabs.instance')">
|
||||||
|
<div class="setting-item">
|
||||||
|
<h3>{{ $t('admin_dash.rate_limit.account_confirmation_resend') }}</h3>
|
||||||
|
<ul class="setting-list">
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:account_confirmation_resend" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:ap_routes" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:app_account_creation" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:authentication" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:oauth_app_creation" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:relation_id_action" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:search" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:status_id_action" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:statuses_actions" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<RateSetting path=":pleroma.:rate_limit.:timeline" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./rates_tab.js"></script>
|
||||||
53
src/components/settings_modal/helpers/rate_setting.js
Normal file
53
src/components/settings_modal/helpers/rate_setting.js
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
|
import Setting from './setting.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
...Setting,
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
newValue: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
...Setting.components,
|
||||||
|
Checkbox
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
...Setting.props
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...Setting.computed,
|
||||||
|
isSeparate () {
|
||||||
|
// [[a1, b1], [a2, b2]] vs [a, b]
|
||||||
|
return Array.isArray(this.visibleState[0])
|
||||||
|
},
|
||||||
|
normalizedState () {
|
||||||
|
if (this.isSeparate) {
|
||||||
|
return this.visibleState.map(y => y.map(x => Number(x) || 0))
|
||||||
|
} else {
|
||||||
|
return [this.visibleState.map(x => Number(x) || 0)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...Setting.methods,
|
||||||
|
getValue ({ event, side, index, eventType }) {
|
||||||
|
if (eventType === 'edit') {
|
||||||
|
const value = Number(event.target.value)
|
||||||
|
if (Number.isNaN(value)) return this.visibleState
|
||||||
|
|
||||||
|
const newVal = [...this.normalizedState.map(x => [...x])]
|
||||||
|
newVal[side][index] = value
|
||||||
|
return newVal
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventType === 'toggleMode') {
|
||||||
|
if (event === 'split') {
|
||||||
|
return [this.normalizedState[0], this.normalizedState[0]]
|
||||||
|
} else if (event === 'join') {
|
||||||
|
return [this.normalizedState[0]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/components/settings_modal/helpers/rate_setting.vue
Normal file
117
src/components/settings_modal/helpers/rate_setting.vue
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="matchesExpertLevel"
|
||||||
|
class="RateSetting"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="setting-label"
|
||||||
|
:class="{ 'faint': shouldBeDisabled }"
|
||||||
|
>
|
||||||
|
<template v-if="backendDescriptionLabel">
|
||||||
|
{{ backendDescriptionLabel + ' ' }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="source === 'admin'">
|
||||||
|
MISSING LABEL FOR {{ path }}
|
||||||
|
</template>
|
||||||
|
<slot v-else />
|
||||||
|
</label>
|
||||||
|
<p
|
||||||
|
v-if="backendDescriptionDescription"
|
||||||
|
class="setting-description"
|
||||||
|
:class="{ 'faint': shouldBeDisabled }"
|
||||||
|
>
|
||||||
|
{{ backendDescriptionDescription + ' ' }}
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th> </th>
|
||||||
|
<th>
|
||||||
|
{{ $t('admin_dash.rate_limit.period') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ $t('admin_dash.rate_limit.amount') }}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td v-if="isSeparate">
|
||||||
|
{{ $t('admin_dash.rate_limit.unauthenticated') }}
|
||||||
|
</td>
|
||||||
|
<td v-else>
|
||||||
|
{{ $t('admin_dash.rate_limit.rate_limit') }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
class="input string-input"
|
||||||
|
type="number"
|
||||||
|
:value="normalizedState[0][0]"
|
||||||
|
@change="e => update({ event: e, index: 0, side: 0, eventType: 'edit' })"
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
class="input string-input"
|
||||||
|
type="number"
|
||||||
|
:value="normalizedState[0][1]"
|
||||||
|
@change="e => update({ event: e, index: 1, side: 0, eventType: 'edit' })"
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="isSeparate">
|
||||||
|
<td>
|
||||||
|
{{ $t('admin_dash.rate_limit.authenticated') }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
class="input string-input"
|
||||||
|
type="number"
|
||||||
|
:value="normalizedState[1][0]"
|
||||||
|
@change="e => update({ event: e, index: 0, side: 1, eventType: 'edit' })"
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
class="input string-input"
|
||||||
|
type="number"
|
||||||
|
:value="normalizedState[1][1]"
|
||||||
|
@change="e => update({ event: e, index: 1, side: 1, eventType: 'edit' })"
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<Checkbox
|
||||||
|
:model-value="isSeparate"
|
||||||
|
@update:model-value="event => update({ event: event ? 'join' : 'split', eventType: 'toggleMode' })"
|
||||||
|
>
|
||||||
|
{{ $t('admin_dash.rate_limit.separate') }}
|
||||||
|
</Checkbox>
|
||||||
|
<div>
|
||||||
|
<ModifiedIndicator
|
||||||
|
:changed="isChanged"
|
||||||
|
:onclick="reset"
|
||||||
|
/>
|
||||||
|
<ProfileSettingIndicator :is-profile="isProfileSetting" />
|
||||||
|
<DraftButtons />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./rate_setting.js"></script>
|
||||||
|
<style lang="scss">
|
||||||
|
.RateSetting {
|
||||||
|
table {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
input {
|
||||||
|
width: 15ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -13,6 +13,7 @@ import RegistrationsTab from './admin_tabs/registrations_tab.vue'
|
||||||
import AuthTab from './admin_tabs/auth_tab.vue'
|
import AuthTab from './admin_tabs/auth_tab.vue'
|
||||||
import HTTPTab from './admin_tabs/http_tab.vue'
|
import HTTPTab from './admin_tabs/http_tab.vue'
|
||||||
import OtherTab from './admin_tabs/other_tab.vue'
|
import OtherTab from './admin_tabs/other_tab.vue'
|
||||||
|
import RatesTab from './admin_tabs/rates_tab.vue'
|
||||||
import PostsTab from './admin_tabs/posts_tab.vue'
|
import PostsTab from './admin_tabs/posts_tab.vue'
|
||||||
import FederationTab from './admin_tabs/federation_tab.vue'
|
import FederationTab from './admin_tabs/federation_tab.vue'
|
||||||
import JobQueuesTab from './admin_tabs/job_queues_tab.vue'
|
import JobQueuesTab from './admin_tabs/job_queues_tab.vue'
|
||||||
|
|
@ -34,7 +35,8 @@ import {
|
||||||
faCircleNodes,
|
faCircleNodes,
|
||||||
faUpload,
|
faUpload,
|
||||||
faMessage,
|
faMessage,
|
||||||
faEllipsis
|
faEllipsis,
|
||||||
|
faGauge
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
|
|
@ -52,7 +54,8 @@ library.add(
|
||||||
faCircleNodes,
|
faCircleNodes,
|
||||||
faUpload,
|
faUpload,
|
||||||
faMessage,
|
faMessage,
|
||||||
faEllipsis
|
faEllipsis,
|
||||||
|
faGauge
|
||||||
)
|
)
|
||||||
|
|
||||||
const SettingsModalAdminContent = {
|
const SettingsModalAdminContent = {
|
||||||
|
|
@ -73,6 +76,7 @@ const SettingsModalAdminContent = {
|
||||||
AuthTab,
|
AuthTab,
|
||||||
HTTPTab,
|
HTTPTab,
|
||||||
MonitoringTab,
|
MonitoringTab,
|
||||||
|
RatesTab,
|
||||||
OtherTab,
|
OtherTab,
|
||||||
PostsTab
|
PostsTab
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,15 @@
|
||||||
<LimitsTab />
|
<LimitsTab />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="adminDbLoaded"
|
||||||
|
:label="$t('admin_dash.tabs.rate_limit')"
|
||||||
|
icon="gauge"
|
||||||
|
data-tab-name="rate_limits"
|
||||||
|
>
|
||||||
|
<RatesTab />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
:label="$t('admin_dash.tabs.uploads')"
|
:label="$t('admin_dash.tabs.uploads')"
|
||||||
icon="upload"
|
icon="upload"
|
||||||
|
|
|
||||||
|
|
@ -1162,6 +1162,7 @@
|
||||||
"job_queues": "Job Queues",
|
"job_queues": "Job Queues",
|
||||||
"auth": "Auth",
|
"auth": "Auth",
|
||||||
"posts": "Posts",
|
"posts": "Posts",
|
||||||
|
"rate_limit": "Rate Limits",
|
||||||
"http": "HTTP",
|
"http": "HTTP",
|
||||||
"federation": "Federation",
|
"federation": "Federation",
|
||||||
"other": "Other"
|
"other": "Other"
|
||||||
|
|
@ -1227,6 +1228,14 @@
|
||||||
},
|
},
|
||||||
"queues": "Queues"
|
"queues": "Queues"
|
||||||
},
|
},
|
||||||
|
"rate_limit": {
|
||||||
|
"rate_limit": "Rate Limit",
|
||||||
|
"amount": "Amount",
|
||||||
|
"unauthenticated": "Unauthenticated",
|
||||||
|
"authenticated": "Authenticated",
|
||||||
|
"period": "Time period",
|
||||||
|
"separate": "Separate rate limits for authenticated/unauthenticated users"
|
||||||
|
},
|
||||||
"nodb": {
|
"nodb": {
|
||||||
"heading": "Database config is disabled",
|
"heading": "Database config is disabled",
|
||||||
"text": "You need to change backend config files so that {property} is set to {value}, see more in {documentation}.",
|
"text": "You need to change backend config files so that {property} is set to {value}, see more in {documentation}.",
|
||||||
|
|
@ -1421,6 +1430,12 @@
|
||||||
"description": "idk"
|
"description": "idk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
":rate_limit": {
|
||||||
|
":oauth_app_creation": {
|
||||||
|
"label": "OAuth app creation",
|
||||||
|
"description": "For registering new OAuth App ID"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Pleroma_DOT_Formatter": {
|
"Pleroma_DOT_Formatter": {
|
||||||
":attribute_toggle": {
|
":attribute_toggle": {
|
||||||
"label": "Set {attr} attribute"
|
"label": "Set {attr} attribute"
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ const adminSettingsStorage = {
|
||||||
setInstanceAdminSettings ({ state, commit }, { backendDbConfig }) {
|
setInstanceAdminSettings ({ state, commit }, { backendDbConfig }) {
|
||||||
const config = state.config || {}
|
const config = state.config || {}
|
||||||
const modifiedPaths = new Set()
|
const modifiedPaths = new Set()
|
||||||
|
|
||||||
backendDbConfig.configs.forEach(c => {
|
backendDbConfig.configs.forEach(c => {
|
||||||
const path = [c.group, c.key]
|
const path = [c.group, c.key]
|
||||||
if (c.db) {
|
if (c.db) {
|
||||||
|
|
@ -94,16 +95,33 @@ const adminSettingsStorage = {
|
||||||
// Using strings for modified paths for easier searching
|
// Using strings for modified paths for easier searching
|
||||||
c.db.forEach(x => modifiedPaths.add([...path, x].join(' -> ')))
|
c.db.forEach(x => modifiedPaths.add([...path, x].join(' -> ')))
|
||||||
}
|
}
|
||||||
const convert = (value) => {
|
|
||||||
|
// we need to preserve tuples on second level only, possibly third
|
||||||
|
// but it's not a case right now.
|
||||||
|
const convert = (value, preserveTuples, preserveTuplesLv2) => {
|
||||||
if (Array.isArray(value) && value.length > 0 && value[0].tuple) {
|
if (Array.isArray(value) && value.length > 0 && value[0].tuple) {
|
||||||
return value.reduce((acc, c) => {
|
if (!preserveTuples) {
|
||||||
return { ...acc, [c.tuple[0]]: convert(c.tuple[1]) }
|
return value.reduce((acc, c) => {
|
||||||
}, {})
|
return { ...acc, [c.tuple[0]]: convert(c.tuple[1], preserveTuplesLv2) }
|
||||||
|
}, {})
|
||||||
|
} else {
|
||||||
|
return value.map(x => x.tuple)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return value
|
if (!preserveTuples) {
|
||||||
|
return value
|
||||||
|
} else {
|
||||||
|
return value.tuple
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set(config, path, convert(c.value))
|
// for most stuff we want maps since those are more convenient
|
||||||
|
// however this doesn't allow for multiple values per same key
|
||||||
|
// so for those cases we want to preserve tuples as-is
|
||||||
|
// right now it's made exclusively for :pleroma.:rate_limit
|
||||||
|
// so it might not work properly elsewhere
|
||||||
|
const preserveTuples = path.find(x => x === ':rate_limit')
|
||||||
|
set(config, path, convert(c.value, false, preserveTuples))
|
||||||
})
|
})
|
||||||
console.log('CONFIG', JSON.parse(JSON.stringify(config)))
|
console.log('CONFIG', JSON.parse(JSON.stringify(config)))
|
||||||
// patching http adapter config to be easier to handle
|
// patching http adapter config to be easier to handle
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue