mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-16 16:20:59 +00:00
feat(api-tokens): manage multiple named tokens; add tab/section anchor URLs
Replace the single regenerable API token with a named-token list: - New ApiToken model + service with constant-time auth matching - Seeder migrates the legacy `apiToken` setting into a "default" row - Security tab gets create/enable/delete UI; api-docs page links to it - Dedicated "API Tokens" section in the in-panel docs URL anchors now reflect the active tab/section on Settings, Xray, and API Docs pages, so deep links like `/panel/settings#security` work. Translations for the 8 new SecurityTab strings added across all locales.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { Modal, message } from 'ant-design-vue';
|
||||
import {
|
||||
@@ -208,6 +208,40 @@ function confirmRestart() {
|
||||
onOk: () => restartXray(),
|
||||
});
|
||||
}
|
||||
|
||||
const tabKeys = ['tpl-basic', 'tpl-routing', 'tpl-outbound', 'tpl-balancer', 'tpl-dns', 'tpl-advanced'];
|
||||
const slugByKey = {
|
||||
'tpl-basic': 'basic',
|
||||
'tpl-routing': 'routing',
|
||||
'tpl-outbound': 'outbound',
|
||||
'tpl-balancer': 'balancer',
|
||||
'tpl-dns': 'dns',
|
||||
'tpl-advanced': 'advanced',
|
||||
};
|
||||
const keyBySlug = Object.fromEntries(Object.entries(slugByKey).map(([k, v]) => [v, k]));
|
||||
|
||||
const activeTabKey = ref(keyBySlug[window.location.hash.slice(1)] || tabKeys[0]);
|
||||
|
||||
function onTabChange(key) {
|
||||
activeTabKey.value = key;
|
||||
const slug = slugByKey[key];
|
||||
if (slug && window.location.hash !== `#${slug}`) {
|
||||
history.replaceState(null, '', `#${slug}`);
|
||||
}
|
||||
}
|
||||
|
||||
function syncTabFromHash() {
|
||||
const key = keyBySlug[window.location.hash.slice(1)];
|
||||
if (key) activeTabKey.value = key;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('hashchange', syncTabFromHash);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('hashchange', syncTabFromHash);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -259,7 +293,7 @@ function confirmRestart() {
|
||||
|
||||
<!-- Tabs -->
|
||||
<a-col :span="24">
|
||||
<a-tabs default-active-key="tpl-basic">
|
||||
<a-tabs :active-key="activeTabKey" @change="onTabChange">
|
||||
<a-tab-pane key="tpl-basic" class="tab-pane">
|
||||
<template #tab>
|
||||
<SettingOutlined /> <span>{{ t('pages.xray.basicTemplate') }}</span>
|
||||
|
||||
Reference in New Issue
Block a user