Compare commits

...
Author SHA1 Message Date
Yuki Guo fd462e39e8 Merge branch 'dev-v2' into pr@dev-v2@fix_page_cache 2026-11-06 18:04:44 +08:00
guoyuqi e8ac89dcd2 fix : page caching settings 2026-11-06 17:39:49 +08:00
62 changed files with 603 additions and 147 deletions
@@ -0,0 +1,57 @@
<template>
<div>
<el-card class="cached-tabs">
<el-radio-group :model-value="activeTab" @change="select">
<el-radio-button v-for="item in items" :key="item.value" :value="item.value" size="large">
{{ item.label }}
</el-radio-button>
</el-radio-group>
</el-card>
<slot :active="activeTab" />
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router';
import { useCachedTab } from '@/composables/useCachedTab';
const props = withDefaults(
defineProps<{
items: { value: string; label: string }[];
defaultValue: string;
cacheKey?: string;
requestedValue?: string;
}>(),
{ cacheKey: 'default' },
);
const emit = defineEmits<{ activate: [value: string] }>();
const pagePath = useRoute().path;
const { activeTab, select } = useCachedTab({
key: () => JSON.stringify([pagePath, props.cacheKey]),
values: () => props.items.map((item) => item.value),
defaultValue: () => props.defaultValue,
requestedValue: () => props.requestedValue,
onActivate: (value) => emit('activate', value),
});
</script>
<style scoped lang="scss">
.cached-tabs {
--el-card-padding: 0;
:deep(.el-radio-button__inner) {
min-width: 100px;
height: 100%;
background-color: var(--panel-button-active) !important;
box-shadow: none !important;
outline: none !important;
border: 2px solid transparent !important;
}
:deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
color: $primary-color;
border-color: $primary-color !important;
border-radius: 4px;
}
}
</style>
@@ -50,7 +50,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { routerToNameWithQuery, routerToPathWithQuery } from '@/utils/router'; import { openPage } from '@/utils/router';
import { computed, onMounted, ref, watch } from 'vue'; import { computed, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { hasPermissionMetaAccess, hasRouteAccess } from '@/utils/rbac'; import { hasPermissionMetaAccess, hasRouteAccess } from '@/utils/rbac';
@@ -96,8 +96,8 @@ const handleChange = async (label: string) => {
const btn = buttonArray.value.find((btn) => btn.label === label); const btn = buttonArray.value.find((btn) => btn.label === label);
if (!btn) return; if (!btn) return;
try { try {
if (btn.path) await routerToPathWithQuery(btn.path, { uncached: 'true' }); if (btn.path) await openPage({ path: btn.path });
else if (btn.name) await routerToNameWithQuery(btn.name, { uncached: 'true' }); else if (btn.name) await openPage({ name: btn.name });
} finally { } finally {
syncActiveName(); syncActiveName();
} }
+40 -3
View File
@@ -5,21 +5,36 @@
clearable clearable
v-model="searchInfo" v-model="searchInfo"
@clear="search()" @clear="search()"
suffix-icon="Search" @keydown.enter.stop.prevent="search()"
@change="search()" @blur="searchIfChanged()"
:disabled="props.disabled" :disabled="props.disabled"
:placeholder="props.placeholder || $t('commons.button.search')" :placeholder="props.placeholder || $t('commons.button.search')"
></el-input> >
<template #suffix>
<button
type="button"
class="search-submit"
:disabled="props.disabled"
:aria-label="$t('commons.button.search')"
@mousedown.prevent
@click="search()"
>
<el-icon><Search /></el-icon>
</button>
</template>
</el-input>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onActivated, ref, watch } from 'vue'; import { onActivated, ref, watch } from 'vue';
import { Search } from '@element-plus/icons-vue';
defineOptions({ name: 'TableSearch' }); defineOptions({ name: 'TableSearch' });
const emit = defineEmits(['search', 'update:searchName']); const emit = defineEmits(['search', 'update:searchName']);
const searchInfo = ref(); const searchInfo = ref();
let lastSearch: string | number | undefined;
const props = defineProps({ const props = defineProps({
placeholder: String, placeholder: String,
disabled: { disabled: {
@@ -37,6 +52,7 @@ watch(
(newVal) => { (newVal) => {
if (searchInfo.value !== newVal) { if (searchInfo.value !== newVal) {
searchInfo.value = newVal; searchInfo.value = newVal;
lastSearch = newVal;
} }
}, },
{ immediate: true }, { immediate: true },
@@ -47,7 +63,28 @@ onActivated(() => {
}); });
const search = () => { const search = () => {
if (props.disabled) return;
lastSearch = searchInfo.value;
emit('update:searchName', searchInfo.value); emit('update:searchName', searchInfo.value);
emit('search'); emit('search');
}; };
const searchIfChanged = () => {
if (searchInfo.value !== lastSearch) search();
};
</script> </script>
<style scoped>
.search-submit {
display: inline-flex;
align-items: center;
padding: 0;
border: 0;
background: transparent;
color: inherit;
cursor: pointer;
}
.search-submit:disabled {
cursor: not-allowed;
}
</style>
@@ -175,6 +175,8 @@ import { useCardColumns } from './useCardColumns';
import { useContextMenu } from './useContextMenu'; import { useContextMenu } from './useContextMenu';
import { useResponsivePagination } from './useResponsivePagination'; import { useResponsivePagination } from './useResponsivePagination';
import { useTableSelection } from './useTableSelection'; import { useTableSelection } from './useTableSelection';
import { useRoute } from 'vue-router';
import { usePaginationCache } from './usePaginationCache';
const slots = useSlots(); const slots = useSlots();
const attrs = useAttrs(); const attrs = useAttrs();
const { isMobile, openMenuTabs, currentNode } = useGlobalStore(); const { isMobile, openMenuTabs, currentNode } = useGlobalStore();
@@ -187,11 +189,16 @@ type ViewMode = 'table' | 'card';
const props = defineProps({ const props = defineProps({
header: String, header: String,
data: { type: Array as PropType<any[]>, default: () => [] }, data: { type: Array as PropType<any[]>, default: () => [] },
loading: { type: Boolean, default: false },
selectionContext: { type: [String, Number, Array, Object, Function], default: undefined }, selectionContext: { type: [String, Number, Array, Object, Function], default: undefined },
paginationConfig: { paginationConfig: {
type: Object, type: Object,
required: false, required: false,
}, },
cachePagination: { type: Boolean, default: undefined },
refreshOnRestore: { type: Boolean, default: true },
cacheId: String,
cacheScope: [String, Number],
pageSizes: { pageSizes: {
type: Array as PropType<number[]>, type: Array as PropType<number[]>,
default: () => [5, 10, 20, 50, 100, 200, 500], default: () => [5, 10, 20, 50, 100, 200, 500],
@@ -217,6 +224,15 @@ const props = defineProps({
}, },
}); });
const emit = defineEmits(['search', 'update:selects', 'update:paginationConfig', 'update:viewMode']); const emit = defineEmits(['search', 'update:selects', 'update:paginationConfig', 'update:viewMode']);
usePaginationCache({
pagePath: useRoute().path,
pagination: () => props.paginationConfig as { currentPage: number; pageSize: number; cacheSizeKey?: string },
enabled: () => props.cachePagination,
id: () => props.cacheId,
scope: () => props.cacheScope,
search: () => emit('search'),
refreshOnRestore: () => props.refreshOnRestore,
});
const tableRef = ref(); const tableRef = ref();
const complexTableRef = ref<HTMLElement>(); const complexTableRef = ref<HTMLElement>();
const tableHeight = ref<number | string>(''); const tableHeight = ref<number | string>('');
@@ -343,10 +359,10 @@ const handleRightClick = (row, column, event) => {
}; };
watch( watch(
() => props.data, () => [props.data, props.loading],
() => { () => {
const pagination = props.paginationConfig; const pagination = props.paginationConfig;
if (!pagination || !pagination.pageSize) return; if (props.loading || !pagination || !pagination.pageSize) return;
const lastPage = Math.max(1, Math.ceil(pagination.total / pagination.pageSize)); const lastPage = Math.max(1, Math.ceil(pagination.total / pagination.pageSize));
if (pagination.currentPage > lastPage) { if (pagination.currentPage > lastPage) {
pagination.currentPage = lastPage; pagination.currentPage = lastPage;
@@ -361,7 +377,7 @@ function currentChange() {
} }
function sizeChange() { function sizeChange() {
if (props.paginationConfig.cacheSizeKey) { if (props.cachePagination === false && props.paginationConfig.cacheSizeKey) {
writePanelCache( writePanelCache(
'pagination', 'pagination',
panelCacheKey(`size:${props.paginationConfig.cacheSizeKey}`), panelCacheKey(`size:${props.paginationConfig.cacheSizeKey}`),
@@ -0,0 +1,124 @@
import { nextTick, onActivated, onDeactivated, onScopeDispose, watch } from 'vue';
import GlobalStore from '@/store/modules/global';
import { panelCacheKey, readPanelCache, writePanelCache } from '@/utils/panel-cache';
interface Pagination {
currentPage: number;
pageSize: number;
cacheSizeKey?: string;
}
interface Options {
pagePath: string;
pagination: () => Pagination | undefined;
enabled: () => boolean | undefined;
id: () => string | undefined;
scope: () => string | number | undefined;
search: () => void;
refreshOnRestore?: () => boolean;
}
/** Restore during child setup, before the owning page's onMounted query. */
export const usePaginationCache = (options: Options) => {
const store = GlobalStore();
const defaults = new WeakMap<Pagination, { currentPage: number; pageSize: number }>();
let active = true;
let restoring = false;
let activeKey: string | undefined;
let queued = false;
let disposed = false;
let pending: { key: string; currentPage: number; pageSize: number } | undefined;
let writeQueued = false;
const flush = () => {
if (!pending) return;
const { key: target, currentPage, pageSize } = pending;
pending = undefined;
writePanelCache('pagination', target, { currentPage, pageSize });
};
const requestSearch = () => {
if (queued || !key()) return;
queued = true;
void nextTick(() => {
queued = false;
if (active && !disposed && key() && options.refreshOnRestore?.() !== false) options.search();
});
};
const key = () => {
const pagination = options.pagination();
if (options.enabled() === false || !pagination || !store.cacheUserID) return undefined;
return panelCacheKey(
JSON.stringify([
'table-pagination',
options.pagePath,
options.id() ?? pagination.cacheSizeKey ?? 'default',
options.scope() ?? '',
]),
);
};
const positiveInteger = (value: unknown): value is number => Number.isInteger(value) && Number(value) > 0;
const restore = () => {
flush();
activeKey = key();
const pagination = options.pagination();
if (!activeKey || !pagination) return false;
if (!defaults.has(pagination)) {
defaults.set(pagination, { currentPage: pagination.currentPage, pageSize: pagination.pageSize });
}
const initial = defaults.get(pagination)!;
const saved = readPanelCache<Partial<Pagination>>('pagination', activeKey);
const page = positiveInteger(saved?.currentPage) ? saved.currentPage : initial.currentPage;
const size = positiveInteger(saved?.pageSize) ? saved.pageSize : initial.pageSize;
const changed = pagination.currentPage !== page || pagination.pageSize !== size;
restoring = true;
try {
pagination.pageSize = size;
pagination.currentPage = page;
} finally {
restoring = false;
}
return changed;
};
// The initial restore deliberately does not emit: the parent owns its first query.
restore();
watch(
() => [key(), options.pagination(), store.panelCache.pagination, store.panelCache.duration],
() => {
if (!active) return;
const previousKey = activeKey;
const changed = restore();
if (activeKey && (changed || previousKey !== activeKey)) requestSearch();
},
{ flush: 'sync' },
);
watch(
() => [options.pagination()?.currentPage, options.pagination()?.pageSize],
([currentPage, pageSize]) => {
// Never write old-page state under a newly selected node/account.
if (!active || restoring || !activeKey || activeKey !== key()) return;
if (!positiveInteger(currentPage) || !positiveInteger(pageSize)) return;
pending = { key: activeKey, currentPage, pageSize };
if (!writeQueued) {
writeQueued = true;
queueMicrotask(() => {
writeQueued = false;
flush();
});
}
},
{ flush: 'sync' },
);
onDeactivated(() => {
flush();
active = false;
});
onActivated(() => {
if (active) return;
active = true;
restore();
requestSearch();
});
onScopeDispose(() => {
flush();
disposed = true;
active = false;
});
};
+89
View File
@@ -0,0 +1,89 @@
import { nextTick, onActivated, onDeactivated, onMounted, onScopeDispose, readonly, ref, watch } from 'vue';
import GlobalStore from '@/store/modules/global';
import { panelCacheKey, readPanelCache, writePanelCache } from '@/utils/panel-cache';
interface CachedTabOptions {
key: () => string;
values: () => string[];
defaultValue: () => string;
requestedValue?: () => string | undefined;
onActivate: (value: string) => unknown;
}
export const useCachedTab = (options: CachedTabOptions) => {
const store = GlobalStore();
const activeTab = ref('');
let active = true;
let mounted = false;
let version = 0;
let restoredKey: string | undefined;
const key = () => panelCacheKey(`inline-tabs:${options.key()}`);
const valid = (value: unknown): value is string => typeof value === 'string' && options.values().includes(value);
const restore = (useRequested = true) => {
const requested = useRequested ? options.requestedValue?.() : undefined;
const saved = readPanelCache<string>('tabs', key());
restoredKey = key();
activeTab.value = valid(requested)
? requested
: valid(saved)
? saved
: valid(options.defaultValue())
? options.defaultValue()
: options.values()[0] || '';
};
const activate = async () => {
const current = ++version;
await nextTick();
if (current !== version || !active || !mounted || !valid(activeTab.value)) return;
options.onActivate(activeTab.value);
};
const select = (value: string) => {
if (!active || !valid(value) || value === activeTab.value) return;
activeTab.value = value;
writePanelCache('tabs', key(), value);
void activate();
};
watch(
[
key,
() => store.panelCache.tabs,
() => store.panelCache.duration,
() => JSON.stringify(options.values()),
options.defaultValue,
() => options.requestedValue?.(),
],
(values, previous) => {
if (!active) return;
// Reflecting the selected tab into the URL is not another selection.
if (
previous.length &&
values.slice(0, 5).every((value, index) => value === previous[index]) &&
values[5] === activeTab.value
)
return;
// A URL left over from the previous node/account must not override its cache.
restore(!previous.length || values[0] === previous[0]);
if (mounted) void activate();
},
{ immediate: true, flush: 'sync' },
);
onMounted(() => {
mounted = true;
void activate();
});
onDeactivated(() => {
active = false;
version++;
});
onActivated(() => {
if (active) return;
active = true;
restore(restoredKey === key());
void activate();
});
onScopeDispose(() => {
active = false;
version++;
});
return { activeTab: readonly(activeTab), select };
};
@@ -15,7 +15,7 @@
<el-menu <el-menu
v-else v-else
:default-active="activeMenu" :default-active="activeMenu"
:router="true" :router="false"
:collapse="isCollapse" :collapse="isCollapse"
:collapse-transition="false" :collapse-transition="false"
:unique-opened="!menuAccordion" :unique-opened="!menuAccordion"
+2 -6
View File
@@ -62,7 +62,7 @@ import TerminalDock from '@/components/terminal/dock/index.vue';
import useResize from './hooks/useResize'; import useResize from './hooks/useResize';
import { MenuStore, TabsStore } from '@/store'; import { MenuStore, TabsStore } from '@/store';
import { getSystemAvailable } from '@/api/modules/setting'; import { getSystemAvailable } from '@/api/modules/setting';
import { useRoute, useRouter } from 'vue-router'; import { openMenu } from '@/utils/router';
import { loadMasterProductProFromDB, loadProductProFromDB } from '@/utils/xpack'; import { loadMasterProductProFromDB, loadProductProFromDB } from '@/utils/xpack';
import { useTheme } from '@/global/use-theme'; import { useTheme } from '@/global/use-theme';
import TaskList from '@/components/task-list/index.vue'; import TaskList from '@/components/task-list/index.vue';
@@ -95,8 +95,6 @@ const openTask = () => {
menuStore.setCollapse(); menuStore.setCollapse();
} }
}; };
const router = useRouter();
const route = useRoute();
const menuStore = MenuStore(); const menuStore = MenuStore();
const tabsStore = TabsStore(); const tabsStore = TabsStore();
@@ -151,9 +149,7 @@ watch(
}, },
); );
const handleMenuClick = async (path) => { const handleMenuClick = async (path) => {
await router.push({ path: path }); await openMenu(path);
tabsStore.addTab(route);
tabsStore.activeTabPath = route.path;
}; };
const toLogin = () => { const toLogin = () => {
+5 -31
View File
@@ -1,4 +1,4 @@
import { panelCacheKey, readPanelCache, writePanelCache, removePanelCache, prunePanelCache } from '@/utils/panel-cache'; import { panelCacheKey, writePanelCache, prunePanelCache } from '@/utils/panel-cache';
import router from '@/routers/router'; import router from '@/routers/router';
import NProgress from '@/config/nprogress'; import NProgress from '@/config/nprogress';
import { useGlobalStore } from '@/composables/useGlobalStore'; import { useGlobalStore } from '@/composables/useGlobalStore';
@@ -11,7 +11,6 @@ import { TerminalDockSessionStore, TerminalSessionStore } from '@/store';
const axiosCanceler = new AxiosCanceler(); const axiosCanceler = new AxiosCanceler();
let isRedirecting = false;
const enterpriseLicenseCheckWhiteList = ['EnterpriseLicenseRequired', 'entrance', 'login', 'Expired']; const enterpriseLicenseCheckWhiteList = ['EnterpriseLicenseRequired', 'entrance', 'login', 'Expired'];
const noLoginWhiteList = ['entrance', 'login', 'file-share', '404', 'Expired']; const noLoginWhiteList = ['entrance', 'login', 'file-share', '404', 'Expired'];
@@ -30,7 +29,7 @@ const clearLoginStatus = () => {
TerminalDockSessionStore().closeAll(); TerminalDockSessionStore().closeAll();
}; };
router.beforeEach(async (to, from) => { router.beforeEach(async (to) => {
const { entrance, isEnterprise, isEnterpriseLicenseLoaded, isEnterpriseLicensed, isLogin, isOnRestart } = const { entrance, isEnterprise, isEnterpriseLicenseLoaded, isEnterpriseLicensed, isLogin, isOnRestart } =
useGlobalStore(); useGlobalStore();
NProgress.start(); NProgress.start();
@@ -103,34 +102,11 @@ router.beforeEach(async (to, from) => {
if (to.name === 'Expired') { if (to.name === 'Expired') {
return true; return true;
} }
const activeMenuKey = panelCacheKey(String(to.meta.activeMenu || '')); // Compatibility for old links: explicit navigation no longer needs to clear a cache.
if (to.query.uncached != undefined) { if (to.query.uncached != undefined) {
const query = { ...to.query }; const query = { ...to.query };
delete query.uncached; delete query.uncached;
removePanelCache('tabs', activeMenuKey); return { path: to.path, query, hash: to.hash };
return { path: to.path, query };
}
const cachedRoute = readPanelCache<string>('tabs', activeMenuKey);
if (
to.meta.activeMenu &&
to.meta.activeMenu != from.meta.activeMenu &&
typeof cachedRoute === 'string' &&
cachedRoute &&
cachedRoute !== to.path &&
!isRedirecting
) {
const cachedRouteInfo = router.resolve(cachedRoute);
if (
cachedRouteInfo.matched.length > 0 &&
cachedRouteInfo.meta.activeMenu === to.meta.activeMenu &&
hasRouteAccess(cachedRouteInfo)
) {
isRedirecting = true;
NProgress.done();
return cachedRoute;
}
removePanelCache('tabs', activeMenuKey);
} }
if (!hasRouteAccess(to)) { if (!hasRouteAccess(to)) {
@@ -144,11 +120,10 @@ router.beforeEach(async (to, from) => {
router.afterEach((to, _from, failure) => { router.afterEach((to, _from, failure) => {
prunePanelCache(); prunePanelCache();
if (failure) { if (failure) {
isRedirecting = false;
NProgress.done(); NProgress.done();
return; return;
} }
if (to.meta.activeMenu && !to.meta.ignoreTab && !isRedirecting) { if (to.meta.activeMenu && !to.meta.ignoreTab) {
let notMathParam = true; let notMathParam = true;
if (to.matched.some((record) => record.path.includes(':'))) { if (to.matched.some((record) => record.path.includes(':'))) {
notMathParam = false; notMathParam = false;
@@ -166,7 +141,6 @@ router.afterEach((to, _from, failure) => {
} }
} }
isRedirecting = false;
NProgress.done(); NProgress.done();
}); });
+36 -6
View File
@@ -4,6 +4,7 @@ import { hasRouteAccess } from '@/utils/rbac';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgError } from '@/utils/message'; import { MsgError } from '@/utils/message';
import type { RouteLocationRaw } from 'vue-router'; import type { RouteLocationRaw } from 'vue-router';
import { panelCacheKey, readPanelCache, removePanelCache } from '@/utils/panel-cache';
const pushWithAccessCheck = async (to: RouteLocationRaw) => { const pushWithAccessCheck = async (to: RouteLocationRaw) => {
const resolvedRoute = router.resolve(to); const resolvedRoute = router.resolve(to);
@@ -15,24 +16,53 @@ const pushWithAccessCheck = async (to: RouteLocationRaw) => {
tabStoreMiddleWare(); tabStoreMiddleWare();
}; };
/** Explicit navigation always opens the requested page, independent of tab caching. */
export const openPage = pushWithAccessCheck;
/** Only module-menu entry points restore the last visited route within that module. */
export const openMenu = async (to: RouteLocationRaw) => {
let entry = router.resolve(to);
const visited = new Set<string>();
// Menu roots often redirect and only their destination declares activeMenu.
while (!visited.has(entry.fullPath)) {
visited.add(entry.fullPath);
const redirect = entry.matched[entry.matched.length - 1]?.redirect;
if (!redirect) break;
entry = router.resolve(typeof redirect === 'function' ? redirect(entry, router.currentRoute.value) : redirect);
}
const menu = entry.meta.activeMenu;
if (menu) {
const key = panelCacheKey(String(menu));
const cached = readPanelCache<unknown>('tabs', key);
if (typeof cached === 'string') {
const destination = router.resolve(cached);
if (destination.matched.length && destination.meta.activeMenu === menu && hasRouteAccess(destination)) {
return openPage(cached);
}
}
if (cached !== undefined) removePanelCache('tabs', key);
}
return openPage(to);
};
export const routerToName = async (name: string) => { export const routerToName = async (name: string) => {
await pushWithAccessCheck({ name: name }); await openPage({ name: name });
}; };
export const routerToPath = async (path: string) => { export const routerToPath = async (path: string) => {
await pushWithAccessCheck({ path: path }); await openPage({ path: path });
}; };
export const routerToFileWithPath = async (pathItem: string) => { export const routerToFileWithPath = async (pathItem: string) => {
await pushWithAccessCheck({ name: 'File', query: { path: pathItem, uncached: 'true' } }); await openPage({ name: 'File', query: { path: pathItem, uncached: 'true' } });
}; };
export const routerToNameWithQuery = async (name: string, query: any) => { export const routerToNameWithQuery = async (name: string, query: any) => {
await pushWithAccessCheck({ name: name, query: query }); await openPage({ name: name, query: query });
}; };
export const routerToPathWithQuery = async (path: string, query: any) => { export const routerToPathWithQuery = async (path: string, query: any) => {
await pushWithAccessCheck({ path: path, query: query }); await openPage({ path: path, query: query });
}; };
export const jumpToPath = (router: any, path: string) => { export const jumpToPath = (router: any, path: string) => {
@@ -40,7 +70,7 @@ export const jumpToPath = (router: any, path: string) => {
}; };
export const routerToNameWithParams = async (name: string, params: any) => { export const routerToNameWithParams = async (name: string, params: any) => {
await pushWithAccessCheck({ name: name, params: params }); await openPage({ name: name, params: params });
}; };
const tabStoreMiddleWare = () => { const tabStoreMiddleWare = () => {
+3 -3
View File
@@ -139,11 +139,11 @@ export const bindSearchState = (key: () => string | undefined, fields: SearchFie
interface SearchStateOptions { interface SearchStateOptions {
scope?: () => string | number | undefined; scope?: () => string | number | undefined;
onRevisit: () => unknown; onRevisit?: () => unknown;
} }
/** Keep queries across page visits and reload data when a cached page becomes active. */ /** Keep queries across page visits and reload data when a cached page becomes active. */
export const useSearchState = (page: string, fields: SearchFields, options: SearchStateOptions) => { export const useSearchState = (page: string, fields: SearchFields, options: SearchStateOptions = {}) => {
const { cacheUserID } = storeToRefs(GlobalStore()); const { cacheUserID } = storeToRefs(GlobalStore());
const binding = bindSearchState(() => { const binding = bindSearchState(() => {
const scope = options.scope?.(); const scope = options.scope?.();
@@ -160,6 +160,6 @@ export const useSearchState = (page: string, fields: SearchFields, options: Sear
onActivated(async () => { onActivated(async () => {
if (!deactivated) return; if (!deactivated) return;
deactivated = false; deactivated = false;
if (await binding.resume()) return options.onRevisit(); if (await binding.resume()) return options.onRevisit?.();
}); });
}; };
@@ -20,6 +20,7 @@
v-if="!noApp" v-if="!noApp"
v-model:view-mode="viewMode" v-model:view-mode="viewMode"
:data="items" :data="items"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@search="search" @search="search"
> >
+6 -1
View File
@@ -16,7 +16,12 @@
<TableRefresh @search="search()" /> <TableRefresh @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="items"
@search="search()"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
+1
View File
@@ -53,6 +53,7 @@
<ComplexTable <ComplexTable
:data="connections" :data="connections"
row-key="id" row-key="id"
:cache-pagination="false"
:pagination-config="pagination" :pagination-config="pagination"
:columns="accountColumns" :columns="accountColumns"
local-key="modelServiceColumn" local-key="modelServiceColumn"
@@ -50,6 +50,7 @@
v-else-if="modelInstalled" v-else-if="modelInstalled"
:selection-context="() => [searchName]" :selection-context="() => [searchName]"
row-key="id" row-key="id"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
@sort-change="search" @sort-change="search"
@@ -85,6 +85,7 @@
<template #main> <template #main>
<ComplexTable <ComplexTable
:selection-context="() => [searchName, activeTag, includeAppStore, props.filters]" :selection-context="() => [searchName, activeTag, includeAppStore, props.filters]"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:view-mode="viewMode" v-model:view-mode="viewMode"
v-model:selects="selects" v-model:selects="selects"
@@ -36,6 +36,7 @@
</template> </template>
<template #main> <template #main>
<ComplexTable <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:data="data" :data="data"
@sort-change="search" @sort-change="search"
@@ -28,6 +28,7 @@
<ComplexTable <ComplexTable
:selection-context="() => [searchName]" :selection-context="() => [searchName]"
row-key="id" row-key="id"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
@@ -20,6 +20,7 @@
</template> </template>
<template #main> <template #main>
<ComplexTable <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
@@ -40,6 +40,7 @@
<ComplexTable <ComplexTable
:selection-context="() => [searchName]" :selection-context="() => [searchName]"
row-key="id" row-key="id"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
@@ -28,6 +28,7 @@
<ComplexTable <ComplexTable
:selection-context="() => [searchName]" :selection-context="() => [searchName]"
row-key="name" row-key="name"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
@@ -55,6 +55,7 @@
<ComplexTable <ComplexTable
:selection-context="() => [searchName, searchGroupID]" :selection-context="() => [searchName, searchGroupID]"
row-key="id" row-key="id"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:default-sort=" :default-sort="
paginationConfig.order !== 'null' paginationConfig.order !== 'null'
@@ -70,6 +70,7 @@
:selection-context="() => [searchInfo, group]" :selection-context="() => [searchInfo, group]"
row-key="id" row-key="id"
v-model:selects="selects" v-model:selects="selects"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:data="data" :data="data"
@search="search" @search="search"
@@ -106,6 +106,7 @@
<ComplexTable <ComplexTable
v-if="currentDB" v-if="currentDB"
:class="{ mask: maskShow }" :class="{ mask: maskShow }"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sort-change="search" @sort-change="search"
@search="search" @search="search"
@@ -10,7 +10,13 @@
<TableSearch @search="search()" v-model:searchName="searchName" /> <TableSearch @search="search()" v-model:searchName="searchName" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
@sort-change="search"
@search="search"
:data="data"
>
<el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable /> <el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable />
<el-table-column :label="$t('database.version')" prop="version" /> <el-table-column :label="$t('database.version')" prop="version" />
<el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" /> <el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" />
@@ -118,6 +118,7 @@
<template #main> <template #main>
<ComplexTable <ComplexTable
v-if="currentDB" v-if="currentDB"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:class="{ mask: maskShow }" :class="{ mask: maskShow }"
@sort-change="search" @sort-change="search"
@@ -10,7 +10,13 @@
<TableSearch @search="search()" v-model:searchName="searchName" /> <TableSearch @search="search()" v-model:searchName="searchName" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
@sort-change="search"
@search="search"
:data="data"
>
<el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable /> <el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable />
<el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" /> <el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" />
<el-table-column :label="$t('commons.login.username')" prop="username" /> <el-table-column :label="$t('commons.login.username')" prop="username" />
@@ -93,6 +93,7 @@
<ComplexTable <ComplexTable
v-if="currentDB" v-if="currentDB"
:class="{ mask: maskShow }" :class="{ mask: maskShow }"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sort-change="search" @sort-change="search"
@search="search" @search="search"
@@ -10,7 +10,13 @@
<TableSearch @search="search()" v-model:searchName="searchName" /> <TableSearch @search="search()" v-model:searchName="searchName" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
@sort-change="search"
@search="search"
:data="data"
>
<el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable /> <el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable />
<el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" /> <el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" />
<el-table-column :label="$t('commons.login.username')" prop="username" /> <el-table-column :label="$t('commons.login.username')" prop="username" />
@@ -10,7 +10,13 @@
<TableSearch @search="search()" v-model:searchName="searchName" /> <TableSearch @search="search()" v-model:searchName="searchName" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
@sort-change="search"
@search="search"
:data="data"
>
<el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable /> <el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable />
<el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" /> <el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" />
<el-table-column :label="$t('commons.login.password')" prop="password"> <el-table-column :label="$t('commons.login.password')" prop="password">
@@ -506,6 +506,7 @@
<template #main> <template #main>
<ComplexTable <ComplexTable
class="file-table" class="file-table"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:ref="(el) => setTableRef(item.id, el)" :ref="(el) => setTableRef(item.id, el)"
@@ -48,6 +48,7 @@
<ComplexTable <ComplexTable
v-model:selects="selects" v-model:selects="selects"
:data="containerPageRows" :data="containerPageRows"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:heightDiff="320" :heightDiff="320"
row-key="key" row-key="key"
@@ -169,6 +170,7 @@
v-model:selects="orphanSelects" v-model:selects="orphanSelects"
v-loading="loading" v-loading="loading"
:data="orphanPageRows" :data="orphanPageRows"
:cache-pagination="false"
:pagination-config="orphanPaginationConfig" :pagination-config="orphanPaginationConfig"
row-key="policyUUID" row-key="policyUUID"
max-height="calc(100vh - 220px)" max-height="calc(100vh - 220px)"
@@ -66,6 +66,7 @@
row.interface, row.interface,
]) ])
" "
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
@search="search" @search="search"
@@ -109,6 +109,7 @@
<ComplexTable <ComplexTable
:selection-context="() => [searchName, selectedRuleFilters]" :selection-context="() => [searchName, selectedRuleFilters]"
v-model:selects="selects" v-model:selects="selects"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:data="allRows" :data="allRows"
:heightDiff="320 + noticeHeight" :heightDiff="320 + noticeHeight"
+7 -1
View File
@@ -26,7 +26,13 @@
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search" :heightDiff="400"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="data"
@search="search"
:heightDiff="400"
>
<el-table-column min-width="80" :label="$t('logs.loginIP')" prop="address" /> <el-table-column min-width="80" :label="$t('logs.loginIP')" prop="address" />
<el-table-column min-width="60" :label="$t('ssh.belong')" prop="area" /> <el-table-column min-width="60" :label="$t('ssh.belong')" prop="area" />
<el-table-column min-width="60" :label="$t('commons.table.port')" prop="port" /> <el-table-column min-width="60" :label="$t('commons.table.port')" prop="port" />
+7 -1
View File
@@ -57,7 +57,13 @@
<TableRefresh @search="resetAndLoadLogs" /> <TableRefresh @search="resetAndLoadLogs" />
</template> </template>
<template #main> <template #main>
<ComplexTable :data="logs" :pagination-config="paginationConfig" @row-click="openDetail" :heightDiff="320"> <ComplexTable
:data="logs"
:cache-pagination="false"
:pagination-config="paginationConfig"
@row-click="openDetail"
:heightDiff="320"
>
<el-table-column prop="time" :label="$t('commons.table.date')" width="220" show-overflow-tooltip /> <el-table-column prop="time" :label="$t('commons.table.date')" width="220" show-overflow-tooltip />
<el-table-column :label="$t('logs.priority')" width="120"> <el-table-column :label="$t('logs.priority')" width="120">
<template #default="{ row }"> <template #default="{ row }">
+7 -1
View File
@@ -21,7 +21,13 @@
<TableSetting title="login-log-refresh" @search="search()" /> <TableSetting title="login-log-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search" :heightDiff="330"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="data"
@search="search"
:heightDiff="330"
>
<el-table-column :label="$t('logs.loginIP')" prop="ip" /> <el-table-column :label="$t('logs.loginIP')" prop="ip" />
<el-table-column v-if="isEnterprise" :label="$t('commons.login.username')" prop="user" /> <el-table-column v-if="isEnterprise" :label="$t('commons.login.username')" prop="user" />
<el-table-column :label="$t('logs.loginAddress')" prop="address" /> <el-table-column :label="$t('logs.loginAddress')" prop="address" />
+7 -1
View File
@@ -78,7 +78,13 @@
<TableSetting title="operation-log-refresh" @search="search()" /> <TableSetting title="operation-log-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search" :heightDiff="330"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="data"
@search="search"
:heightDiff="330"
>
<el-table-column :label="$t('logs.resource')" prop="group" fix> <el-table-column :label="$t('logs.resource')" prop="group" fix>
<template #default="{ row }"> <template #default="{ row }">
<span v-if="row.source && row.source.indexOf('-') === -1"> <span v-if="row.source && row.source.indexOf('-') === -1">
+7 -1
View File
@@ -16,7 +16,13 @@
<TableSetting title="task-log-refresh" @search="search()" /> <TableSetting title="task-log-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search" :heightDiff="330"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="data"
@search="search"
:heightDiff="330"
>
<el-table-column :label="$t('logs.taskName')" prop="name" min-width="180px"> <el-table-column :label="$t('logs.taskName')" prop="name" min-width="180px">
<template #default="{ row }"> <template #default="{ row }">
{{ translateTaskText(row.name) }} {{ translateTaskText(row.name) }}
@@ -75,6 +75,7 @@
</template> </template>
<template #main> <template #main>
<ComplexTable <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:data="data" :data="data"
:height-diff="380" :height-diff="380"
@@ -14,7 +14,12 @@
</div> </div>
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search()"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="data"
@search="search()"
>
<el-table-column :label="$t('xpack.alert.alertMsg')" prop="message" show-overflow-tooltip> <el-table-column :label="$t('xpack.alert.alertMsg')" prop="message" show-overflow-tooltip>
<template #default="{ row }"> <template #default="{ row }">
{{ formatMessage(row.alertDetail) }} {{ formatMessage(row.alertDetail) }}
@@ -65,6 +65,7 @@
</el-alert> </el-alert>
<ComplexTable <ComplexTable
class="mt-3" class="mt-3"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:data="allConfigs" :data="allConfigs"
:empty-text="$t('commons.msg.noneData')" :empty-text="$t('commons.msg.noneData')"
@@ -28,6 +28,7 @@
</template> </template>
</el-alert> </el-alert>
<ComplexTable <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sort-change="search" @sort-change="search"
@search="search" @search="search"
+7 -1
View File
@@ -14,7 +14,13 @@
<TableSetting title="backup-account-refresh" @search="search()" /> <TableSetting title="backup-account-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
@sort-change="search"
@search="search"
:data="data"
>
<el-table-column <el-table-column
:label="$t('license.authorizationId')" :label="$t('license.authorizationId')"
:min-width="80" :min-width="80"
@@ -21,6 +21,7 @@
<ComplexTable <ComplexTable
:selection-context="() => [searchName]" :selection-context="() => [searchName]"
row-key="id" row-key="id"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
@@ -34,6 +34,7 @@
</template> </template>
<template #main> <template #main>
<ComplexTable <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
@@ -114,11 +115,11 @@ const paginationConfig = reactive({
order: 'ascending', order: 'ascending',
}); });
const info = ref(); const info = ref();
useSearchState( useSearchState('terminal/command/index', {
'terminal/command/index', search: info,
{ search: info, page: toRef(paginationConfig, 'currentPage'), pageSize: toRef(paginationConfig, 'pageSize') }, page: toRef(paginationConfig, 'currentPage'),
{ onRevisit: () => search() }, pageSize: toRef(paginationConfig, 'pageSize'),
); });
const group = ref<string>(''); const group = ref<string>('');
const dialogRef = ref(); const dialogRef = ref();
const opRef = ref(); const opRef = ref();
+6 -5
View File
@@ -23,6 +23,7 @@
</template> </template>
<template #main> <template #main>
<ComplexTable <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
@@ -90,11 +91,11 @@ const paginationConfig = reactive({
total: 0, total: 0,
}); });
const info = ref(); const info = ref();
useSearchState( useSearchState('terminal/host/index', {
'terminal/host/index', search: info,
{ search: info, page: toRef(paginationConfig, 'currentPage'), pageSize: toRef(paginationConfig, 'pageSize') }, page: toRef(paginationConfig, 'currentPage'),
{ onRevisit: () => search() }, pageSize: toRef(paginationConfig, 'pageSize'),
); });
const group = ref<string>(''); const group = ref<string>('');
const opRef = ref(); const opRef = ref();
+28 -58
View File
@@ -1,35 +1,20 @@
<template> <template>
<div> <CachedTabs
<el-card class="router_card"> :items="tabs"
<el-radio-group v-model="activeNames" @change="handleChange"> default-value="terminal"
<el-radio-button class="router_card_button" size="large" value="terminal"> cache-key="terminal/main"
{{ $t('menu.terminal', 2) }} :requested-value="route.path === '/terminal' && route.query.path ? 'terminal' : undefined"
</el-radio-button> @activate="handleChange"
<el-radio-button v-if="isAdmin" class="router_card_button" size="large" value="host"> >
{{ $t('terminal.host', 2) }} <template #default="{ active }">
</el-radio-button> <div v-show="active === 'terminal'">
<el-radio-button class="router_card_button" size="large" value="command"> <TerminalTab ref="terminalTabRef" />
{{ $t('terminal.quickCommand', 2) }} </div>
</el-radio-button> <HostTab v-if="isAdmin && active === 'host'" ref="hostTabRef" />
<el-radio-button v-if="isAdmin" class="router_card_button" size="large" value="setting"> <CommandTab v-if="active === 'command'" ref="commandTabRef" />
{{ $t('container.setting') }} <SettingTab v-if="isAdmin && active === 'setting'" ref="settingTabRef" />
</el-radio-button> </template>
</el-radio-group> </CachedTabs>
</el-card>
<div v-show="activeNames === 'terminal'">
<TerminalTab ref="terminalTabRef" />
</div>
<div v-if="isAdmin && activeNames === 'host'">
<HostTab ref="hostTabRef" />
</div>
<div v-if="activeNames === 'command'">
<CommandTab ref="commandTabRef" />
</div>
<div v-if="isAdmin && activeNames === 'setting'">
<SettingTab ref="settingTabRef" />
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -37,20 +22,29 @@ import HostTab from '@/views/terminal/host/index.vue';
import CommandTab from '@/views/terminal/command/index.vue'; import CommandTab from '@/views/terminal/command/index.vue';
import TerminalTab from '@/views/terminal/terminal/index.vue'; import TerminalTab from '@/views/terminal/terminal/index.vue';
import SettingTab from '@/views/terminal/setting/index.vue'; import SettingTab from '@/views/terminal/setting/index.vue';
import { onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import CachedTabs from '@/components/cached-tabs/index.vue';
import i18n from '@/lang';
import { getTerminalInfo } from '@/api/modules/setting'; import { getTerminalInfo } from '@/api/modules/setting';
import { TerminalStore } from '@/store'; import { TerminalStore } from '@/store';
import { useGlobalStore } from '@/composables/useGlobalStore'; import { useGlobalStore } from '@/composables/useGlobalStore';
const terminalStore = TerminalStore(); const terminalStore = TerminalStore();
const { isAdmin } = useGlobalStore(); const { isAdmin } = useGlobalStore();
const activeNames = ref<string>('terminal'); const route = useRoute();
const tabs = computed(() => [
{ value: 'terminal', label: i18n.global.t('menu.terminal', 2) },
...(isAdmin.value ? [{ value: 'host', label: i18n.global.t('terminal.host', 2) }] : []),
{ value: 'command', label: i18n.global.t('terminal.quickCommand', 2) },
...(isAdmin.value ? [{ value: 'setting', label: i18n.global.t('container.setting') }] : []),
]);
const hostTabRef = ref(); const hostTabRef = ref();
const commandTabRef = ref(); const commandTabRef = ref();
const terminalTabRef = ref(); const terminalTabRef = ref();
const settingTabRef = ref(); const settingTabRef = ref();
const handleChange = (tab: any) => { const handleChange = (tab: string) => {
if (tab === 'host' && isAdmin.value) { if (tab === 'host' && isAdmin.value) {
hostTabRef.value?.acceptParams(); hostTabRef.value?.acceptParams();
} }
@@ -85,29 +79,5 @@ const loadTerminalSetting = async () => {
onMounted(() => { onMounted(() => {
loadTerminalSetting(); loadTerminalSetting();
handleChange('terminal');
}); });
</script> </script>
<style lang="scss" scoped>
.router_card {
--el-card-padding: 0;
}
.router_card_button {
:deep(.el-radio-button__inner) {
min-width: 100px;
height: 100%;
background-color: var(--panel-button-active) !important;
box-shadow: none !important;
outline: none !important;
border: 2px solid transparent !important;
}
:deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
color: $primary-color;
border-color: $primary-color !important;
border-radius: 4px;
}
}
</style>
@@ -53,6 +53,7 @@
row-key="id" row-key="id"
:class="{ mask: !clamStatus.isRunning }" :class="{ mask: !clamStatus.isRunning }"
v-if="!isSettingShow" v-if="!isSettingShow"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:scrollbar-always-on="isMobile" :scrollbar-always-on="isMobile"
v-model:selects="selects" v-model:selects="selects"
+1
View File
@@ -68,6 +68,7 @@
</template> </template>
<template #main> <template #main>
<ComplexTable <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
v-model:selects="selects" v-model:selects="selects"
@sort-change="search" @sort-change="search"
@@ -13,7 +13,13 @@
<TableSetting title="dotnet-runtime-refresh" @search="search()" /> <TableSetting title="dotnet-runtime-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()" :heightDiff="260"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="items"
@search="search()"
:heightDiff="260"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
@@ -13,7 +13,13 @@
<TableSetting title="go-runtime-refresh" @search="search()" /> <TableSetting title="go-runtime-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()" :heightDiff="260"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="items"
@search="search()"
:heightDiff="260"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
@@ -13,7 +13,13 @@
<TableSetting title="java-runtime-refresh" @search="search()" /> <TableSetting title="java-runtime-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()" :heightDiff="260"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="items"
@search="search()"
:heightDiff="260"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
@@ -13,7 +13,13 @@
<TableSetting title="node-runtime-refresh" @search="search()" /> <TableSetting title="node-runtime-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()" :heightDiff="260"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="items"
@search="search()"
:heightDiff="260"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
@@ -21,7 +21,13 @@
<TableSetting title="php-runtime-refresh" @search="search()" /> <TableSetting title="php-runtime-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()" :heightDiff="260"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="items"
@search="search()"
:heightDiff="260"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
@@ -13,7 +13,13 @@
<TableSetting title="python-runtime-refresh" @search="search()" /> <TableSetting title="python-runtime-refresh" @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()" :heightDiff="260"> <ComplexTable
:cache-pagination="false"
:pagination-config="paginationConfig"
:data="items"
@search="search()"
:heightDiff="260"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
@@ -11,7 +11,13 @@
<el-alert :title="$t('ssl.acmeHelper')" type="info" :closable="false" /> <el-alert :title="$t('ssl.acmeHelper')" type="info" :closable="false" />
</template> </template>
<template #main> <template #main>
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()" v-loading="loading"> <ComplexTable
:data="data"
:cache-pagination="false"
:pagination-config="paginationConfig"
@search="search()"
v-loading="loading"
>
<el-table-column <el-table-column
:label="$t('website.email')" :label="$t('website.email')"
fix fix
+7 -1
View File
@@ -11,7 +11,13 @@
</el-button> </el-button>
</template> </template>
<template #main> <template #main>
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()" v-loading="loading"> <ComplexTable
:data="data"
:cache-pagination="false"
:pagination-config="paginationConfig"
@search="search()"
v-loading="loading"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
show-overflow-tooltip show-overflow-tooltip
@@ -8,7 +8,12 @@
</el-button> </el-button>
</template> </template>
<template #main> <template #main>
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()"> <ComplexTable
:data="data"
:cache-pagination="false"
:pagination-config="paginationConfig"
@search="search()"
>
<el-table-column <el-table-column
:label="$t('commons.table.name')" :label="$t('commons.table.name')"
fix fix
+7 -1
View File
@@ -23,7 +23,7 @@
</el-button> </el-button>
</template> </template>
<template #rightToolBar> <template #rightToolBar>
<TableSearch @search="search()" v-model:searchName="req.domain" /> <TableSearch @search="searchByDomain" v-model:searchName="req.domain" />
<TableRefresh @search="search()" /> <TableRefresh @search="search()" />
<fu-table-column-select <fu-table-column-select
:columns="columns" :columns="columns"
@@ -36,6 +36,7 @@
<template #main> <template #main>
<ComplexTable <ComplexTable
:data="data" :data="data"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@search="search()" @search="search()"
v-model:selects="selects" v-model:selects="selects"
@@ -434,6 +435,11 @@ const search = () => {
}); });
}; };
const searchByDomain = () => {
paginationConfig.currentPage = 1;
search();
};
const updateDesc = (row: Website.SSLDTO, bulr: Function) => { const updateDesc = (row: Website.SSLDTO, bulr: Function) => {
bulr(); bulr();
if (row.description && row.description.length > 128) { if (row.description && row.description.length > 128) {
@@ -15,7 +15,13 @@
<TableRefresh @search="search()" /> <TableRefresh @search="search()" />
</template> </template>
<template #main> <template #main>
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()" v-loading="loading"> <ComplexTable
:data="data"
:cache-pagination="false"
:pagination-config="paginationConfig"
@search="search()"
v-loading="loading"
>
<el-table-column :label="$t('template.name')" prop="name" min-width="120px" show-overflow-tooltip /> <el-table-column :label="$t('template.name')" prop="name" min-width="120px" show-overflow-tooltip />
<el-table-column :label="$t('template.type')" prop="type" width="150px"> <el-table-column :label="$t('template.type')" prop="type" width="150px">
<template #default="{ row }"> <template #default="{ row }">
@@ -61,6 +61,7 @@
<ComplexTable <ComplexTable
:selection-context="() => [req.name, req.type, req.websiteGroupId]" :selection-context="() => [req.name, req.type, req.websiteGroupId]"
row-key="id" row-key="id"
:cache-pagination="false"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:default-sort="tableSort.order ? tableSort : undefined" :default-sort="tableSort.order ? tableSort : undefined"
v-model:view-mode="viewMode" v-model:view-mode="viewMode"