feat(admin): add edit flows for all catalogs and member authentik sync
This commit is contained in:
@@ -16,6 +16,12 @@
|
||||
<template #empty><el-empty description="目前無群組" /></template>
|
||||
<el-table-column prop="group_key" label="Group Key" width="180" />
|
||||
<el-table-column prop="name" label="群組名稱" min-width="200" />
|
||||
<el-table-column prop="status" label="狀態" width="120" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" @click="openEditGroup(row)">編輯</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
@@ -60,16 +66,34 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="Scope ID">
|
||||
<el-input v-model="groupPermForm.scope_id" placeholder="company_key or site_key" />
|
||||
<el-select v-model="groupPermForm.scope_id" placeholder="選擇 Scope ID" filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="s in scopeOptions"
|
||||
:key="s.value"
|
||||
:label="s.label"
|
||||
:value="s.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="系統">
|
||||
<el-input v-model="groupPermForm.system" placeholder="mkt" />
|
||||
<el-select v-model="groupPermForm.system" placeholder="選擇系統" filterable style="width: 100%">
|
||||
<el-option v-for="s in systems" :key="s.system_key" :label="`${s.name} (${s.system_key})`" :value="s.system_key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="模組(選填)">
|
||||
<el-input v-model="groupPermForm.module" placeholder="campaign" clearable />
|
||||
<el-select v-model="groupPermForm.module" placeholder="系統層(留空) 或選模組" clearable filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="m in filteredModuleOptions"
|
||||
:key="m.value"
|
||||
:label="m.label"
|
||||
:value="m.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作">
|
||||
<el-input v-model="groupPermForm.action" placeholder="view" />
|
||||
<el-select v-model="groupPermForm.action" filterable allow-create default-first-option style="width: 100%">
|
||||
<el-option v-for="a in actionOptions" :key="a" :label="a" :value="a" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
@@ -113,22 +137,73 @@
|
||||
<el-button type="primary" :loading="creatingGroup" @click="handleCreateGroup">確認</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="showEditGroup" title="編輯群組" @close="resetEditGroupForm">
|
||||
<el-form :model="editGroupForm" label-width="120px">
|
||||
<el-form-item label="Group Key">
|
||||
<el-input :model-value="editGroupForm.group_key" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="群組名稱">
|
||||
<el-input v-model="editGroupForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="狀態">
|
||||
<el-select v-model="editGroupForm.status" style="width: 100%">
|
||||
<el-option label="active" value="active" />
|
||||
<el-option label="inactive" value="inactive" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showEditGroup = false">取消</el-button>
|
||||
<el-button type="primary" :loading="savingGroup" @click="handleEditGroup">儲存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ref, reactive, onMounted, computed, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import {
|
||||
getPermissionGroups,
|
||||
createPermissionGroup,
|
||||
updatePermissionGroup,
|
||||
addMemberToGroup,
|
||||
groupGrant,
|
||||
groupRevoke
|
||||
} from '@/api/permission-groups'
|
||||
import { getSystems } from '@/api/systems'
|
||||
import { getModules } from '@/api/modules'
|
||||
import { getCompanies } from '@/api/companies'
|
||||
import { getSites } from '@/api/sites'
|
||||
|
||||
const activeTab = ref('groups')
|
||||
const systems = ref([])
|
||||
const modules = ref([])
|
||||
const companies = ref([])
|
||||
const sites = ref([])
|
||||
const actionOptions = ['view', 'edit', 'manage', 'admin']
|
||||
|
||||
const filteredModuleOptions = computed(() => {
|
||||
if (!groupPermForm.system) return []
|
||||
return modules.value
|
||||
.filter(m => m.system_key === groupPermForm.system && !m.module_key.endsWith('.__system__'))
|
||||
.map(m => ({
|
||||
value: m.module_key.split('.', 2)[1] || m.module_key,
|
||||
label: `${m.name} (${m.module_key})`
|
||||
}))
|
||||
})
|
||||
|
||||
const scopeOptions = computed(() => {
|
||||
if (groupPermForm.scope_type === 'company') {
|
||||
return companies.value.map(c => ({ value: c.company_key, label: `${c.name} (${c.company_key})` }))
|
||||
}
|
||||
if (groupPermForm.scope_type === 'site') {
|
||||
return sites.value.map(s => ({ value: s.site_key, label: `${s.name} (${s.site_key})` }))
|
||||
}
|
||||
return []
|
||||
})
|
||||
|
||||
// Groups
|
||||
const groups = ref([])
|
||||
@@ -150,10 +225,26 @@ async function loadGroups() {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCatalogs() {
|
||||
const [systemsRes, modulesRes, companiesRes, sitesRes] = await Promise.all([
|
||||
getSystems(),
|
||||
getModules(),
|
||||
getCompanies(),
|
||||
getSites()
|
||||
])
|
||||
systems.value = systemsRes.data?.items || []
|
||||
modules.value = modulesRes.data?.items || []
|
||||
companies.value = companiesRes.data?.items || []
|
||||
sites.value = sitesRes.data?.items || []
|
||||
}
|
||||
|
||||
// Create Group
|
||||
const showCreateGroup = ref(false)
|
||||
const creatingGroup = ref(false)
|
||||
const createForm = reactive({ group_key: '', name: '' })
|
||||
const showEditGroup = ref(false)
|
||||
const savingGroup = ref(false)
|
||||
const editGroupForm = reactive({ group_key: '', name: '', status: 'active' })
|
||||
|
||||
function resetCreateForm() {
|
||||
createForm.group_key = ''
|
||||
@@ -179,6 +270,36 @@ async function handleCreateGroup() {
|
||||
}
|
||||
}
|
||||
|
||||
function openEditGroup(row) {
|
||||
editGroupForm.group_key = row.group_key
|
||||
editGroupForm.name = row.name
|
||||
editGroupForm.status = row.status || 'active'
|
||||
showEditGroup.value = true
|
||||
}
|
||||
|
||||
function resetEditGroupForm() {
|
||||
editGroupForm.group_key = ''
|
||||
editGroupForm.name = ''
|
||||
editGroupForm.status = 'active'
|
||||
}
|
||||
|
||||
async function handleEditGroup() {
|
||||
savingGroup.value = true
|
||||
try {
|
||||
await updatePermissionGroup(editGroupForm.group_key, {
|
||||
name: editGroupForm.name,
|
||||
status: editGroupForm.status
|
||||
})
|
||||
ElMessage.success('群組更新成功')
|
||||
showEditGroup.value = false
|
||||
await loadGroups()
|
||||
} catch (err) {
|
||||
ElMessage.error('群組更新失敗')
|
||||
} finally {
|
||||
savingGroup.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Add Member
|
||||
const memberForm = reactive({ groupKey: '', authentikSub: '' })
|
||||
const addingMember = ref(false)
|
||||
@@ -245,5 +366,15 @@ async function handleGroupRevoke() {
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(loadGroups)
|
||||
watch(() => groupPermForm.scope_type, () => {
|
||||
groupPermForm.scope_id = ''
|
||||
})
|
||||
|
||||
watch(() => groupPermForm.system, () => {
|
||||
groupPermForm.module = ''
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([loadGroups(), loadCatalogs()])
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user