mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
fix: certificate selector can not select #375
This commit is contained in:
parent
9413978697
commit
2071891841
5 changed files with 140 additions and 69 deletions
|
@ -1,85 +1,132 @@
|
|||
<script setup lang="ts">
|
||||
import _ from 'lodash'
|
||||
import type { Ref } from 'vue'
|
||||
import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
|
||||
import type Curd from '@/api/curd'
|
||||
import type { Column } from '@/components/StdDesign/types'
|
||||
|
||||
const props = defineProps<{
|
||||
selectedKey: string | number
|
||||
value?: string | number
|
||||
recordValueIndex: string
|
||||
label?: string
|
||||
selectedKey: number | number[] | undefined | null
|
||||
selectionType: 'radio' | 'checkbox'
|
||||
recordValueIndex: string // to index the value of the record
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
api: Curd<any>
|
||||
columns: Column[]
|
||||
disableSearch?: boolean
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
getParams: any
|
||||
getParams?: any
|
||||
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 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(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
const selected = ref([])
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const record: any = reactive({})
|
||||
const records = ref([]) as Ref<any[]>
|
||||
|
||||
function init() {
|
||||
if (props.selectedKey && !props.value && props.selectionType === 'radio') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
props.api.get(props.selectedKey).then((r: any) => {
|
||||
Object.assign(record, r)
|
||||
M_value.value = r[props.recordValueIndex]
|
||||
})
|
||||
async function _init() {
|
||||
// valueApi is used to fetch items that are using itemKey as index value
|
||||
const api = props.valueApi || props.api
|
||||
|
||||
M_values.value = []
|
||||
|
||||
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() {
|
||||
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)
|
||||
if (!props.disabled)
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
function ok() {
|
||||
visible.value = false
|
||||
if (props.selectionType === 'radio')
|
||||
emit('update:selectedKey', selected.value[0])
|
||||
else
|
||||
emit('update:selectedKey', selected.value)
|
||||
const selectedKeyBuffer = ref()
|
||||
|
||||
M_value.value = record[props.recordValueIndex]
|
||||
emit('changeSelect', record)
|
||||
}
|
||||
if (props.selectionType === 'radio')
|
||||
selectedKeyBuffer.value = [props.selectedKey]
|
||||
else
|
||||
selectedKeyBuffer.value = props.selectedKey
|
||||
|
||||
watch(props, () => {
|
||||
if (!props?.selectedKey)
|
||||
M_value.value = ''
|
||||
else if (props.value)
|
||||
M_value.value = props.value as string
|
||||
else
|
||||
init()
|
||||
})
|
||||
|
||||
const _selectedKey = computed({
|
||||
const computedSelectedKeys = computed({
|
||||
get() {
|
||||
return props.selectedKey
|
||||
if (props.selectionType === 'radio')
|
||||
return [selectedKeyBuffer.value]
|
||||
else
|
||||
return selectedKeyBuffer.value
|
||||
},
|
||||
set(v) {
|
||||
emit('update:selectedKey', v)
|
||||
selectedKeyBuffer.value = v
|
||||
},
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
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)
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
// function clear() {
|
||||
// M_values.value = []
|
||||
// emit('update:selectedKey', '')
|
||||
// }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -88,19 +135,23 @@ const _selectedKey = computed({
|
|||
class="std-selector"
|
||||
@click="show"
|
||||
>
|
||||
<AInput
|
||||
v-model="_selectedKey"
|
||||
disabled
|
||||
hidden
|
||||
/>
|
||||
<div class="value">
|
||||
{{ M_value }}
|
||||
<div class="chips-container">
|
||||
<ATag
|
||||
v-for="(chipText, index) in M_values"
|
||||
:key="index"
|
||||
class="mr-1"
|
||||
color="orange"
|
||||
:bordered="false"
|
||||
@click="show"
|
||||
>
|
||||
{{ chipText?.[recordValueIndex] }}
|
||||
</ATag>
|
||||
</div>
|
||||
<AModal
|
||||
:mask="false"
|
||||
:open="visible"
|
||||
:cancel-text="$gettext('Cancel')"
|
||||
:ok-text="$gettext('OK')"
|
||||
:ok-text="$gettext('Ok')"
|
||||
:title="$gettext('Selector')"
|
||||
:width="800"
|
||||
destroy-on-close
|
||||
|
@ -109,15 +160,16 @@ const _selectedKey = computed({
|
|||
>
|
||||
{{ description }}
|
||||
<StdTable
|
||||
v-model:selected-row-keys="computedSelectedKeys"
|
||||
v-model:selected-rows="records"
|
||||
:api="api"
|
||||
:columns="columns"
|
||||
:disable-search="disableSearch"
|
||||
pithy
|
||||
:row-key="itemKey"
|
||||
:get-params="getParams"
|
||||
:selection-type="selectionType"
|
||||
disable-query-params
|
||||
@on-selected="onSelect"
|
||||
@on-selected-record="onSelectedRecord"
|
||||
/>
|
||||
</AModal>
|
||||
</div>
|
||||
|
@ -126,16 +178,18 @@ const _selectedKey = computed({
|
|||
|
||||
<style lang="less" scoped>
|
||||
.std-selector-container {
|
||||
height: 39.9px;
|
||||
min-height: 39.9px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
.std-selector {
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
font-variant: tabular-nums;
|
||||
list-style: none;
|
||||
font-feature-settings: 'tnum';
|
||||
height: 32px;
|
||||
min-height: 32px;
|
||||
max-height: 100px;
|
||||
padding: 4px 11px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
|
@ -143,9 +197,15 @@ const _selectedKey = computed({
|
|||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
margin: 0 10px 0 0;
|
||||
//margin: 0 10px 0 0;
|
||||
cursor: pointer;
|
||||
min-width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
.chips-container {
|
||||
span {
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -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}
|
|
@ -214,6 +214,7 @@ function wsOnMessage(m: MessageEvent) {
|
|||
:md="8"
|
||||
>
|
||||
<RadialBarChart
|
||||
:key="$gettext('Memory')"
|
||||
:name="$gettext('Memory')"
|
||||
:series="[memory.pressure]"
|
||||
:center-text="memory.used"
|
||||
|
@ -227,6 +228,7 @@ function wsOnMessage(m: MessageEvent) {
|
|||
:md="8"
|
||||
>
|
||||
<RadialBarChart
|
||||
:key="$gettext('Swap')"
|
||||
:name="$gettext('Swap')"
|
||||
:series="[memory.swap_percent]"
|
||||
:center-text="memory.swap_used"
|
||||
|
@ -240,6 +242,7 @@ function wsOnMessage(m: MessageEvent) {
|
|||
:md="8"
|
||||
>
|
||||
<RadialBarChart
|
||||
:key="$gettext('Storage')"
|
||||
:name="$gettext('Storage')"
|
||||
:series="[disk.percentage]"
|
||||
:center-text="disk.used"
|
||||
|
|
|
@ -12,7 +12,6 @@ import type { Column, JSXElements } from '@/components/StdDesign/types'
|
|||
const current_server_directives = inject('current_server_directives') as ComputedRef<NgxDirective[]>
|
||||
const directivesMap = inject('directivesMap') as Ref<Record<string, NgxDirective[]>>
|
||||
const visible = ref(false)
|
||||
const record = ref({}) as Ref<Cert>
|
||||
|
||||
const columns: Column[] = [{
|
||||
title: () => $gettext('Name'),
|
||||
|
@ -55,31 +54,39 @@ function open() {
|
|||
visible.value = true
|
||||
}
|
||||
|
||||
function onSelectedRecord(r: Cert) {
|
||||
record.value = r
|
||||
}
|
||||
const records = ref([]) as Ref<Cert[]>
|
||||
|
||||
function ok() {
|
||||
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 {
|
||||
current_server_directives?.value.push({
|
||||
directive: 'ssl_certificate',
|
||||
params: record.value.ssl_certificate_path,
|
||||
params: records.value[0].ssl_certificate_path,
|
||||
})
|
||||
}
|
||||
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 {
|
||||
current_server_directives?.value.push({
|
||||
directive: 'ssl_certificate_key',
|
||||
params: record.value.ssl_certificate_key_path,
|
||||
params: records.value[0].ssl_certificate_key_path,
|
||||
})
|
||||
}
|
||||
visible.value = false
|
||||
}
|
||||
const selectedKeyBuffer = ref({})
|
||||
|
||||
const computedSelectedKeys = computed({
|
||||
get() {
|
||||
return [selectedKeyBuffer.value]
|
||||
},
|
||||
set(v) {
|
||||
selectedKeyBuffer.value = v
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -94,11 +101,12 @@ function ok() {
|
|||
@ok="ok"
|
||||
>
|
||||
<StdTable
|
||||
v-model:selected-row-keys="computedSelectedKeys"
|
||||
v-model:selected-rows="records"
|
||||
:api="cert"
|
||||
pithy
|
||||
:columns="columns"
|
||||
selection-type="radio"
|
||||
@on-selected-record="onSelectedRecord"
|
||||
/>
|
||||
</AModal>
|
||||
</div>
|
||||
|
|
|
@ -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}
|
Loading…
Add table
Add a link
Reference in a new issue