fix(plugins): show tenant domain and move store prices into a tab
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { ArrowRightOutlined, AppstoreAddOutlined, SearchOutlined } from '@ant-design/icons-vue'
|
||||
import api from '@/api/http'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import PluginCatalogPage from '@/pages/PluginCatalogPage.vue'
|
||||
|
||||
type ExpiryLevel = 'healthy' | 'warning' | 'critical' | 'unknown' | 'none'
|
||||
|
||||
@@ -33,7 +34,10 @@ type RequestRow = {
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
type MainTab = 'khanegi' | 'hamkar' | 'requests' | 'catalog'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const auth = useAuthStore()
|
||||
const canWrite = computed(() => auth.can('plugins:write'))
|
||||
const storeBusyId = ref<string | null>(null)
|
||||
@@ -41,7 +45,7 @@ const loadingList = ref(false)
|
||||
const tenants = ref<TenantRow[]>([])
|
||||
const q = ref('')
|
||||
const toneFilter = ref<'healthy' | 'warning' | 'critical' | 'unknown' | null>(null)
|
||||
const mainTab = ref<'khanegi' | 'hamkar' | 'requests'>('khanegi')
|
||||
const mainTab = ref<MainTab>('khanegi')
|
||||
const requests = ref<RequestRow[]>([])
|
||||
const loadingRequests = ref(false)
|
||||
const actingId = ref<string | null>(null)
|
||||
@@ -160,11 +164,29 @@ async function reject(row: RequestRow) {
|
||||
}
|
||||
}
|
||||
|
||||
function setTab(tab: 'khanegi' | 'hamkar' | 'requests') {
|
||||
function setTab(tab: MainTab) {
|
||||
mainTab.value = tab
|
||||
const query = tab === 'khanegi' ? {} : { tab }
|
||||
void router.replace({ query })
|
||||
if (tab === 'requests') void loadRequests()
|
||||
}
|
||||
|
||||
function tabFromQuery(raw: unknown): MainTab {
|
||||
if (raw === 'hamkar' || raw === 'requests' || raw === 'catalog') return raw
|
||||
return 'khanegi'
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.query.tab,
|
||||
(tab) => {
|
||||
const next = tabFromQuery(tab)
|
||||
if (mainTab.value === next) return
|
||||
mainTab.value = next
|
||||
if (next === 'requests') void loadRequests()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
loadTenants()
|
||||
})
|
||||
@@ -189,9 +211,10 @@ onMounted(() => {
|
||||
<button type="button" :class="{ active: mainTab === 'khanegi' }" @click="setTab('khanegi')">خانگی</button>
|
||||
<button type="button" :class="{ active: mainTab === 'hamkar' }" @click="setTab('hamkar')">همکار</button>
|
||||
<button type="button" :class="{ active: mainTab === 'requests' }" @click="setTab('requests')">درخواستها</button>
|
||||
<button type="button" :class="{ active: mainTab === 'catalog' }" @click="setTab('catalog')">قیمت فروشگاه</button>
|
||||
</div>
|
||||
|
||||
<div v-if="mainTab !== 'requests'" class="toolbar">
|
||||
<div v-if="mainTab === 'khanegi' || mainTab === 'hamkar'" class="toolbar">
|
||||
<a-input
|
||||
v-model:value="q"
|
||||
allow-clear
|
||||
@@ -200,12 +223,9 @@ onMounted(() => {
|
||||
>
|
||||
<template #prefix><SearchOutlined /></template>
|
||||
</a-input>
|
||||
<a-button v-if="mainTab === 'khanegi'" type="primary" @click="router.push({ name: 'plugin-catalog' })">
|
||||
قیمت فروشگاه
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<div v-if="mainTab !== 'requests'" class="legend" role="group" aria-label="فیلتر وضعیت افزونه">
|
||||
<div v-if="mainTab === 'khanegi' || mainTab === 'hamkar'" class="legend" role="group" aria-label="فیلتر وضعیت افزونه">
|
||||
<button
|
||||
type="button"
|
||||
class="chip all"
|
||||
@@ -292,6 +312,11 @@ onMounted(() => {
|
||||
</a-spin>
|
||||
</section>
|
||||
|
||||
<section v-else-if="mainTab === 'catalog'" class="sms-selector">
|
||||
<div class="sms-side-head">قیمت فروشگاه خانگی</div>
|
||||
<PluginCatalogPage embedded />
|
||||
</section>
|
||||
|
||||
<section v-else class="sms-selector">
|
||||
<div class="sms-side-head"><AppstoreAddOutlined /> نسخهها</div>
|
||||
<a-spin :spinning="loadingList">
|
||||
@@ -332,14 +357,13 @@ onMounted(() => {
|
||||
:class="toneClass(t.summary?.expiryLevel)"
|
||||
@click="openTenant(t.id)"
|
||||
>
|
||||
<div
|
||||
v-if="canWrite"
|
||||
class="sms-toggle"
|
||||
:class="{ off: !t.pluginStoreEnabled }"
|
||||
@click.stop
|
||||
>
|
||||
<span class="sms-toggle-label">فروشگاه افزونه</span>
|
||||
<div class="sms-toggle" :class="{ off: !t.pluginStoreEnabled }" @click.stop>
|
||||
<div class="sms-toggle-text">
|
||||
<span class="sms-toggle-label">فروشگاه افزونه</span>
|
||||
<small class="sms-toggle-domain" dir="ltr">{{ t.domain }}</small>
|
||||
</div>
|
||||
<a-switch
|
||||
v-if="canWrite"
|
||||
:checked="t.pluginStoreEnabled === true"
|
||||
:loading="storeBusyId === t.id"
|
||||
checked-children="روشن"
|
||||
@@ -488,6 +512,20 @@ onMounted(() => {
|
||||
color: #334155;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.sms-toggle-text {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
.sms-toggle-domain {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
color: #64748b;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tenant-card strong { font-size: 0.95rem; }
|
||||
.tenant-card span,
|
||||
|
||||
Reference in New Issue
Block a user