fix: certificate selector can not select #375

This commit is contained in:
Jacky 2024-05-06 17:35:10 +08:00
parent bd0bbe95ef
commit 8623e1e89b
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
5 changed files with 140 additions and 69 deletions

View file

@ -1,85 +1,132 @@
<script setup lang="ts"> <script setup lang="ts">
import _ from 'lodash'
import type { Ref } from 'vue'
import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue' import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
import type Curd from '@/api/curd' import type Curd from '@/api/curd'
import type { Column } from '@/components/StdDesign/types' import type { Column } from '@/components/StdDesign/types'
const props = defineProps<{ const props = defineProps<{
selectedKey: string | number label?: string
value?: string | number selectedKey: number | number[] | undefined | null
recordValueIndex: string
selectionType: 'radio' | 'checkbox' selectionType: 'radio' | 'checkbox'
recordValueIndex: string // to index the value of the record
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
api: Curd<any> api: Curd<any>
columns: Column[] columns: Column[]
disableSearch?: boolean disableSearch?: boolean
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
getParams: any getParams?: any
description?: string description?: string
errorMessages?: string
itemKey?: string // default: id
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value?: any | any[]
disabled?: boolean
// eslint-disable-next-line @typescript-eslint/no-explicit-any
valueApi?: Curd<any>
}>() }>()
const emit = defineEmits(['update:selectedKey', 'changeSelect']) const emit = defineEmits(['update:selectedKey'])
const getParams = computed(() => {
return props.getParams
})
const visible = ref(false) const visible = ref(false)
const M_value = ref('') // eslint-disable-next-line @typescript-eslint/no-explicit-any
const M_values = ref([]) as any
const init = _.debounce(_init, 500, {
leading: true,
trailing: false,
})
onMounted(() => { onMounted(() => {
init() init()
}) })
const selected = ref([])
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const record: any = reactive({}) const records = ref([]) as Ref<any[]>
function init() { async function _init() {
if (props.selectedKey && !props.value && props.selectionType === 'radio') { // valueApi is used to fetch items that are using itemKey as index value
// eslint-disable-next-line @typescript-eslint/no-explicit-any const api = props.valueApi || props.api
props.api.get(props.selectedKey).then((r: any) => {
Object.assign(record, r) M_values.value = []
M_value.value = r[props.recordValueIndex]
if (props.selectionType === 'radio') {
// M_values.value = [props.value] // not init value, we need to fetch them from api
if (!props.value && props.selectedKey) {
api.get(props.selectedKey, props.getParams).then(r => {
M_values.value = [r]
records.value = [r]
}) })
} }
}
else if (typeof props.selectedKey === 'object') {
M_values.value = props.value || []
// not init value, we need to fetch them from api
if (!props.value && (props.selectedKey?.length || 0) > 0) {
api.get_list({
...props.getParams,
id: props.selectedKey,
}).then(r => {
M_values.value = r.data
records.value = r.data
})
}
}
} }
function show() { function show() {
if (!props.disabled)
visible.value = true visible.value = true
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function onSelect(_selected: any) {
selected.value = _selected
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function onSelectedRecord(r: any) {
Object.assign(record, r)
}
function ok() { const selectedKeyBuffer = ref()
visible.value = false
if (props.selectionType === 'radio')
selectedKeyBuffer.value = [props.selectedKey]
else
selectedKeyBuffer.value = props.selectedKey
const computedSelectedKeys = computed({
get() {
if (props.selectionType === 'radio') if (props.selectionType === 'radio')
emit('update:selectedKey', selected.value[0]) return [selectedKeyBuffer.value]
else else
emit('update:selectedKey', selected.value) return selectedKeyBuffer.value
},
set(v) {
selectedKeyBuffer.value = v
},
})
M_value.value = record[props.recordValueIndex] onMounted(() => {
emit('changeSelect', record) if (props.selectedKey === undefined || props.selectedKey === null) {
if (props.selectionType === 'radio')
emit('update:selectedKey', '')
else
emit('update:selectedKey', [])
}
})
async function ok() {
visible.value = false
emit('update:selectedKey', selectedKeyBuffer.value)
M_values.value = _.clone(records.value)
} }
watch(props, () => { watchEffect(() => {
if (!props?.selectedKey)
M_value.value = ''
else if (props.value)
M_value.value = props.value as string
else
init() init()
}) })
const _selectedKey = computed({ // function clear() {
get() { // M_values.value = []
return props.selectedKey // emit('update:selectedKey', '')
}, // }
set(v) {
emit('update:selectedKey', v)
},
})
</script> </script>
<template> <template>
@ -88,19 +135,23 @@ const _selectedKey = computed({
class="std-selector" class="std-selector"
@click="show" @click="show"
> >
<AInput <div class="chips-container">
v-model="_selectedKey" <ATag
disabled v-for="(chipText, index) in M_values"
hidden :key="index"
/> class="mr-1"
<div class="value"> color="orange"
{{ M_value }} :bordered="false"
@click="show"
>
{{ chipText?.[recordValueIndex] }}
</ATag>
</div> </div>
<AModal <AModal
:mask="false" :mask="false"
:open="visible" :open="visible"
:cancel-text="$gettext('Cancel')" :cancel-text="$gettext('Cancel')"
:ok-text="$gettext('OK')" :ok-text="$gettext('Ok')"
:title="$gettext('Selector')" :title="$gettext('Selector')"
:width="800" :width="800"
destroy-on-close destroy-on-close
@ -109,15 +160,16 @@ const _selectedKey = computed({
> >
{{ description }} {{ description }}
<StdTable <StdTable
v-model:selected-row-keys="computedSelectedKeys"
v-model:selected-rows="records"
:api="api" :api="api"
:columns="columns" :columns="columns"
:disable-search="disableSearch" :disable-search="disableSearch"
pithy pithy
:row-key="itemKey"
:get-params="getParams" :get-params="getParams"
:selection-type="selectionType" :selection-type="selectionType"
disable-query-params disable-query-params
@on-selected="onSelect"
@on-selected-record="onSelectedRecord"
/> />
</AModal> </AModal>
</div> </div>
@ -126,16 +178,18 @@ const _selectedKey = computed({
<style lang="less" scoped> <style lang="less" scoped>
.std-selector-container { .std-selector-container {
height: 39.9px; min-height: 39.9px;
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
.std-selector { .std-selector {
overflow-y: auto;
box-sizing: border-box; box-sizing: border-box;
font-variant: tabular-nums; font-variant: tabular-nums;
list-style: none; list-style: none;
font-feature-settings: 'tnum'; font-feature-settings: 'tnum';
height: 32px; min-height: 32px;
max-height: 100px;
padding: 4px 11px; padding: 4px 11px;
font-size: 14px; font-size: 14px;
line-height: 1.5; line-height: 1.5;
@ -143,9 +197,15 @@ const _selectedKey = computed({
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
border-radius: 4px; border-radius: 4px;
transition: all 0.3s; transition: all 0.3s;
margin: 0 10px 0 0; //margin: 0 10px 0 0;
cursor: pointer; cursor: pointer;
min-width: 180px; min-width: 180px;
} }
} }
.chips-container {
span {
margin: 2px;
}
}
</style> </style>

View file

@ -1 +1 @@
{"version":"2.0.0-beta.22","build_id":130,"total_build":334} {"version":"2.0.0-beta.22","build_id":131,"total_build":335}

View file

@ -214,6 +214,7 @@ function wsOnMessage(m: MessageEvent) {
:md="8" :md="8"
> >
<RadialBarChart <RadialBarChart
:key="$gettext('Memory')"
:name="$gettext('Memory')" :name="$gettext('Memory')"
:series="[memory.pressure]" :series="[memory.pressure]"
:center-text="memory.used" :center-text="memory.used"
@ -227,6 +228,7 @@ function wsOnMessage(m: MessageEvent) {
:md="8" :md="8"
> >
<RadialBarChart <RadialBarChart
:key="$gettext('Swap')"
:name="$gettext('Swap')" :name="$gettext('Swap')"
:series="[memory.swap_percent]" :series="[memory.swap_percent]"
:center-text="memory.swap_used" :center-text="memory.swap_used"
@ -240,6 +242,7 @@ function wsOnMessage(m: MessageEvent) {
:md="8" :md="8"
> >
<RadialBarChart <RadialBarChart
:key="$gettext('Storage')"
:name="$gettext('Storage')" :name="$gettext('Storage')"
:series="[disk.percentage]" :series="[disk.percentage]"
:center-text="disk.used" :center-text="disk.used"

View file

@ -12,7 +12,6 @@ import type { Column, JSXElements } from '@/components/StdDesign/types'
const current_server_directives = inject('current_server_directives') as ComputedRef<NgxDirective[]> const current_server_directives = inject('current_server_directives') as ComputedRef<NgxDirective[]>
const directivesMap = inject('directivesMap') as Ref<Record<string, NgxDirective[]>> const directivesMap = inject('directivesMap') as Ref<Record<string, NgxDirective[]>>
const visible = ref(false) const visible = ref(false)
const record = ref({}) as Ref<Cert>
const columns: Column[] = [{ const columns: Column[] = [{
title: () => $gettext('Name'), title: () => $gettext('Name'),
@ -55,31 +54,39 @@ function open() {
visible.value = true visible.value = true
} }
function onSelectedRecord(r: Cert) { const records = ref([]) as Ref<Cert[]>
record.value = r
}
function ok() { function ok() {
if (directivesMap.value.ssl_certificate?.[0]) { if (directivesMap.value.ssl_certificate?.[0]) {
directivesMap.value.ssl_certificate[0].params = record.value.ssl_certificate_path directivesMap.value.ssl_certificate[0].params = records.value[0].ssl_certificate_path
} }
else { else {
current_server_directives?.value.push({ current_server_directives?.value.push({
directive: 'ssl_certificate', directive: 'ssl_certificate',
params: record.value.ssl_certificate_path, params: records.value[0].ssl_certificate_path,
}) })
} }
if (directivesMap.value.ssl_certificate_key?.[0]) { if (directivesMap.value.ssl_certificate_key?.[0]) {
directivesMap.value.ssl_certificate_key[0].params = record.value.ssl_certificate_key_path directivesMap.value.ssl_certificate_key[0].params = records.value[0].ssl_certificate_key_path
} }
else { else {
current_server_directives?.value.push({ current_server_directives?.value.push({
directive: 'ssl_certificate_key', directive: 'ssl_certificate_key',
params: record.value.ssl_certificate_key_path, params: records.value[0].ssl_certificate_key_path,
}) })
} }
visible.value = false visible.value = false
} }
const selectedKeyBuffer = ref({})
const computedSelectedKeys = computed({
get() {
return [selectedKeyBuffer.value]
},
set(v) {
selectedKeyBuffer.value = v
},
})
</script> </script>
<template> <template>
@ -94,11 +101,12 @@ function ok() {
@ok="ok" @ok="ok"
> >
<StdTable <StdTable
v-model:selected-row-keys="computedSelectedKeys"
v-model:selected-rows="records"
:api="cert" :api="cert"
pithy pithy
:columns="columns" :columns="columns"
selection-type="radio" selection-type="radio"
@on-selected-record="onSelectedRecord"
/> />
</AModal> </AModal>
</div> </div>

View file

@ -1 +1 @@
{"version":"2.0.0-beta.22","build_id":130,"total_build":334} {"version":"2.0.0-beta.22","build_id":131,"total_build":335}