fix(frontend): quota notify UI improvements
- QuotaNotifyToggle: add $ or % suffix to threshold input based on type - QuotaLimitCard: combine reset mode and notify toggle on same row to reduce vertical height for daily/weekly sections - Remove redundant ml-4 indentation from QuotaNotifyToggle
This commit is contained in:
@@ -1 +1 @@
|
|||||||
0.1.110.27
|
0.1.110.28
|
||||||
|
|||||||
@@ -203,28 +203,28 @@ const onWeeklyModeChange = (e: Event) => {
|
|||||||
:placeholder="t('admin.accounts.quotaLimitPlaceholder')"
|
:placeholder="t('admin.accounts.quotaLimitPlaceholder')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 日配额重置模式 -->
|
<!-- 日配额:重置方式 + 告警阈值同行 -->
|
||||||
<div class="mt-2 flex items-center gap-2">
|
<div class="mt-2 flex items-center gap-2 flex-wrap">
|
||||||
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetMode') }}</label>
|
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetMode') }}</label>
|
||||||
<select
|
<select
|
||||||
:value="dailyResetMode || 'rolling'"
|
:value="dailyResetMode || 'rolling'"
|
||||||
@change="onDailyModeChange"
|
@change="onDailyModeChange"
|
||||||
class="input py-1 text-xs"
|
class="input py-1 text-xs w-auto"
|
||||||
>
|
>
|
||||||
<option value="rolling">{{ t('admin.accounts.quotaResetModeRolling') }}</option>
|
<option value="rolling">{{ t('admin.accounts.quotaResetModeRolling') }}</option>
|
||||||
<option value="fixed">{{ t('admin.accounts.quotaResetModeFixed') }}</option>
|
<option value="fixed">{{ t('admin.accounts.quotaResetModeFixed') }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
<!-- 固定模式:小时选择 -->
|
||||||
<!-- 固定模式:小时选择 -->
|
<template v-if="dailyResetMode === 'fixed'">
|
||||||
<div v-if="dailyResetMode === 'fixed'" class="mt-2 flex items-center gap-2">
|
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetHour') }}</label>
|
||||||
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetHour') }}</label>
|
<select
|
||||||
<select
|
:value="dailyResetHour ?? 0"
|
||||||
:value="dailyResetHour ?? 0"
|
@change="emit('update:dailyResetHour', Number(($event.target as HTMLSelectElement).value))"
|
||||||
@change="emit('update:dailyResetHour', Number(($event.target as HTMLSelectElement).value))"
|
class="input py-1 text-xs w-24"
|
||||||
class="input py-1 text-xs w-24"
|
>
|
||||||
>
|
<option v-for="h in hourOptions" :key="h" :value="h">{{ String(h).padStart(2, '0') }}:00</option>
|
||||||
<option v-for="h in hourOptions" :key="h" :value="h">{{ String(h).padStart(2, '0') }}:00</option>
|
</select>
|
||||||
</select>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<p class="input-hint">
|
<p class="input-hint">
|
||||||
<template v-if="dailyResetMode === 'fixed'">
|
<template v-if="dailyResetMode === 'fixed'">
|
||||||
@@ -234,7 +234,6 @@ const onWeeklyModeChange = (e: Event) => {
|
|||||||
{{ t('admin.accounts.quotaDailyLimitHint') }}
|
{{ t('admin.accounts.quotaDailyLimitHint') }}
|
||||||
</template>
|
</template>
|
||||||
</p>
|
</p>
|
||||||
<!-- 日配额告警 -->
|
|
||||||
<QuotaNotifyToggle
|
<QuotaNotifyToggle
|
||||||
v-if="quotaNotifyGlobalEnabled && dailyLimit && dailyLimit > 0"
|
v-if="quotaNotifyGlobalEnabled && dailyLimit && dailyLimit > 0"
|
||||||
:enabled="props.quotaNotifyDailyEnabled"
|
:enabled="props.quotaNotifyDailyEnabled"
|
||||||
@@ -261,36 +260,36 @@ const onWeeklyModeChange = (e: Event) => {
|
|||||||
:placeholder="t('admin.accounts.quotaLimitPlaceholder')"
|
:placeholder="t('admin.accounts.quotaLimitPlaceholder')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 周配额重置模式 -->
|
<!-- 周配额:重置方式 + 告警阈值同行 -->
|
||||||
<div class="mt-2 flex items-center gap-2">
|
<div class="mt-2 flex items-center gap-2 flex-wrap">
|
||||||
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetMode') }}</label>
|
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetMode') }}</label>
|
||||||
<select
|
<select
|
||||||
:value="weeklyResetMode || 'rolling'"
|
:value="weeklyResetMode || 'rolling'"
|
||||||
@change="onWeeklyModeChange"
|
@change="onWeeklyModeChange"
|
||||||
class="input py-1 text-xs"
|
class="input py-1 text-xs w-auto"
|
||||||
>
|
>
|
||||||
<option value="rolling">{{ t('admin.accounts.quotaResetModeRolling') }}</option>
|
<option value="rolling">{{ t('admin.accounts.quotaResetModeRolling') }}</option>
|
||||||
<option value="fixed">{{ t('admin.accounts.quotaResetModeFixed') }}</option>
|
<option value="fixed">{{ t('admin.accounts.quotaResetModeFixed') }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
<!-- 固定模式:星期几 + 小时 -->
|
||||||
<!-- 固定模式:星期几 + 小时 -->
|
<template v-if="weeklyResetMode === 'fixed'">
|
||||||
<div v-if="weeklyResetMode === 'fixed'" class="mt-2 flex items-center gap-2 flex-wrap">
|
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaWeeklyResetDay') }}</label>
|
||||||
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaWeeklyResetDay') }}</label>
|
<select
|
||||||
<select
|
:value="weeklyResetDay ?? 1"
|
||||||
:value="weeklyResetDay ?? 1"
|
@change="emit('update:weeklyResetDay', Number(($event.target as HTMLSelectElement).value))"
|
||||||
@change="emit('update:weeklyResetDay', Number(($event.target as HTMLSelectElement).value))"
|
class="input py-1 text-xs w-28"
|
||||||
class="input py-1 text-xs w-28"
|
>
|
||||||
>
|
<option v-for="d in dayOptions" :key="d.value" :value="d.value">{{ t('admin.accounts.dayOfWeek.' + d.key) }}</option>
|
||||||
<option v-for="d in dayOptions" :key="d.value" :value="d.value">{{ t('admin.accounts.dayOfWeek.' + d.key) }}</option>
|
</select>
|
||||||
</select>
|
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetHour') }}</label>
|
||||||
<label class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">{{ t('admin.accounts.quotaResetHour') }}</label>
|
<select
|
||||||
<select
|
:value="weeklyResetHour ?? 0"
|
||||||
:value="weeklyResetHour ?? 0"
|
@change="emit('update:weeklyResetHour', Number(($event.target as HTMLSelectElement).value))"
|
||||||
@change="emit('update:weeklyResetHour', Number(($event.target as HTMLSelectElement).value))"
|
class="input py-1 text-xs w-24"
|
||||||
class="input py-1 text-xs w-24"
|
>
|
||||||
>
|
<option v-for="h in hourOptions" :key="h" :value="h">{{ String(h).padStart(2, '0') }}:00</option>
|
||||||
<option v-for="h in hourOptions" :key="h" :value="h">{{ String(h).padStart(2, '0') }}:00</option>
|
</select>
|
||||||
</select>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<p class="input-hint">
|
<p class="input-hint">
|
||||||
<template v-if="weeklyResetMode === 'fixed'">
|
<template v-if="weeklyResetMode === 'fixed'">
|
||||||
@@ -300,7 +299,6 @@ const onWeeklyModeChange = (e: Event) => {
|
|||||||
{{ t('admin.accounts.quotaWeeklyLimitHint') }}
|
{{ t('admin.accounts.quotaWeeklyLimitHint') }}
|
||||||
</template>
|
</template>
|
||||||
</p>
|
</p>
|
||||||
<!-- 周配额告警 -->
|
|
||||||
<QuotaNotifyToggle
|
<QuotaNotifyToggle
|
||||||
v-if="quotaNotifyGlobalEnabled && weeklyLimit && weeklyLimit > 0"
|
v-if="quotaNotifyGlobalEnabled && weeklyLimit && weeklyLimit > 0"
|
||||||
:enabled="props.quotaNotifyWeeklyEnabled"
|
:enabled="props.quotaNotifyWeeklyEnabled"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ function toggleType(current: string | null) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="ml-4 mt-2 flex items-center gap-3">
|
<div class="flex items-center gap-2">
|
||||||
<label class="text-sm text-gray-500 whitespace-nowrap">{{ t('admin.accounts.quotaNotify.alert') }}</label>
|
<label class="text-sm text-gray-500 whitespace-nowrap">{{ t('admin.accounts.quotaNotify.alert') }}</label>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -38,7 +38,7 @@ function toggleType(current: string | null) {
|
|||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<div v-if="enabled" class="flex items-center gap-1 flex-1">
|
<template v-if="enabled">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="px-1.5 py-0.5 text-xs font-medium rounded border transition-colors"
|
class="px-1.5 py-0.5 text-xs font-medium rounded border transition-colors"
|
||||||
@@ -55,16 +55,22 @@ function toggleType(current: string | null) {
|
|||||||
>
|
>
|
||||||
%
|
%
|
||||||
</button>
|
</button>
|
||||||
<input
|
<div class="relative flex-1">
|
||||||
:value="threshold"
|
<input
|
||||||
@input="emit('update:threshold', parseFloat(($event.target as HTMLInputElement).value) || null)"
|
:value="threshold"
|
||||||
type="number"
|
@input="emit('update:threshold', parseFloat(($event.target as HTMLInputElement).value) || null)"
|
||||||
min="0"
|
type="number"
|
||||||
:max="thresholdType === 'percentage' ? 100 : undefined"
|
min="0"
|
||||||
:step="thresholdType === 'percentage' ? 1 : 0.01"
|
:max="thresholdType === 'percentage' ? 100 : undefined"
|
||||||
class="input py-1 text-sm flex-1"
|
:step="thresholdType === 'percentage' ? 1 : 0.01"
|
||||||
:placeholder="thresholdType === 'percentage' ? t('admin.accounts.quotaNotify.thresholdPlaceholder') : t('admin.accounts.quotaNotify.threshold')"
|
class="input py-1 text-sm w-full"
|
||||||
/>
|
:class="thresholdType === 'percentage' ? 'pr-7' : 'pr-7'"
|
||||||
</div>
|
:placeholder="thresholdType === 'percentage' ? t('admin.accounts.quotaNotify.thresholdPlaceholder') : t('admin.accounts.quotaNotify.threshold')"
|
||||||
|
/>
|
||||||
|
<span class="absolute right-2.5 top-1/2 -translate-y-1/2 text-xs text-gray-400 pointer-events-none">
|
||||||
|
{{ thresholdType === 'percentage' ? '%' : '$' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user