rate limits page

This commit is contained in:
Henry Jameson 2025-12-09 13:21:46 +02:00
commit 57dfbd8a53
8 changed files with 285 additions and 8 deletions

View 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]]
}
}
}
}
}

View 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>&nbsp;</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>