jcloud/dashboard/src2/components/ConfigEditorDialog.vue
2025-04-12 17:39:38 +08:00

196 lines
4.4 KiB
Vue

<template>
<Dialog
:options="{
title: config ? '编辑配置' : '添加配置',
actions: [
{
label: config ? '编辑键' : '添加键',
variant: 'solid',
loading: docResource?.updateConfig?.loading,
onClick: addConfig
}
]
}"
v-model="showDialog"
>
<template v-slot:body-content>
<div class="space-y-4">
<div :class="{ 'pointer-events-none': config }">
<FormControl
type="autocomplete"
label="配置名称"
:options="keyOptions"
v-model="selectedConfig"
/>
</div>
<FormControl
type="text"
label="键"
:modelValue="
selectedConfig?.value === '__custom_key'
? key
: selectedConfig?.value
"
@update:modelValue="
selectedConfig?.value === '__custom_key' ? (key = $event) : null
"
:disabled="selectedConfig?.value !== '__custom_key'"
autocomplete="off"
/>
<FormControl
type="select"
label="类型"
:modelValue="selectedConfig?.type || type"
@update:modelValue="type = $event"
:options="[
'String',
'Number',
'JSON',
'Boolean',
selectedConfig?.value !== '__custom_key' ? 'Password' : null
]"
:disabled="selectedConfig?.value !== '__custom_key'"
autocomplete="off"
/>
<FormControl
v-bind="valueInputProps"
label="值"
v-model="value"
autocomplete="off"
/>
<ErrorMessage class="mt-2" :message="error" />
</div>
</template>
</Dialog>
</template>
<script>
import {
Autocomplete,
ErrorMessage,
FormControl,
getCachedDocumentResource
} from 'jingrow-ui';
export default {
name: 'ConfigEditorDialog',
props: ['site', 'group', 'config'],
components: {
Autocomplete,
FormControl,
ErrorMessage
},
data() {
return {
docResource: null,
showDialog: true,
selectedConfig: null,
key: null,
type: null,
value: null,
error: null
};
},
async mounted() {
if (this.config) {
await this.$resources.standardKeys.promise;
this.selectedConfig = this.keyOptions.find(
option => this.config.key === option.value
);
if (this.selectedConfig) {
this.key = this.selectedConfig?.value;
this.type = this.selectedConfig?.type;
} else {
this.selectedConfig = this.keyOptions.find(
option => '__custom_key' === option.value
);
this.key = this.config.key;
this.type = this.config.type;
}
this.value = this.config.type === 'Password' ? '' : this.config.value;
}
},
resources: {
standardKeys() {
return {
url: 'jcloud.api.site.get_site_config_standard_keys',
cache: 'Site Config Standard Keys',
initialData: [],
auto: true
};
}
},
methods: {
addConfig() {
if (this.site) {
this.docResource = getCachedDocumentResource('Site', this.site);
} else if (this.group) {
this.docResource = getCachedDocumentResource(
'Release Group',
this.group
);
}
if (!this.docResource) return;
let key =
this.selectedConfig?.value == '__custom_key'
? this.key
: this.selectedConfig?.value;
let type = this.selectedConfig?.type || this.type;
let value = this.value;
if (type === 'JSON') {
try {
value = JSON.parse(value);
} catch (e) {
this.error = '无效的JSON';
return;
}
} else if (type === 'Boolean') {
value = value === '1' ? true : false;
} else if (type === 'Number') {
value = Number(value);
}
let config = { [key]: value };
this.docResource.updateConfig.submit(
{ config },
{
onSuccess: () => {
this.$emit('success');
this.showDialog = false;
},
onError: error => {
this.error = error;
}
}
);
}
},
computed: {
keyOptions() {
let customKeyOption = {
label: '自定义键',
value: '__custom_key'
};
let standardKeyOptions = this.$resources.standardKeys.data.map(key => ({
label: key.title,
value: key.key,
type: key.type
}));
return [customKeyOption, ...standardKeyOptions];
},
valueInputProps() {
let type = {
String: 'text',
Number: 'number',
JSON: 'textarea',
Boolean: 'select'
}[this.selectedConfig?.type || this.type];
return {
type,
options: type === 'select' ? ['1', '0'] : null
};
}
}
};
</script>