// core libs // types import { computed, watch, type ComputedRef, type Ref } from "vue"; import { ref } from "vue"; import { apiClient } from "@/utils/api-client"; // libs import { cloneDeep, merge } from "lodash-es"; import type { ConfigMap, Setting, SettingForm } from "@halo-dev/api-client"; import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core"; import { Toast } from "@halo-dev/components"; import { useI18n } from "vue-i18n"; const initialConfigMap: ConfigMap = { apiVersion: "v1alpha1", kind: "ConfigMap", metadata: { name: "", }, data: {}, }; interface useSettingFormReturn { setting: Ref; configMap: Ref; configMapFormData: Ref> | undefined>; saving: Ref; handleFetchSettings: () => void; handleFetchConfigMap: () => void; handleSaveConfigMap: () => void; handleReset: () => void; } export function useSettingForm( settingName: Ref, configMapName: Ref ): useSettingFormReturn { const { t } = useI18n(); const setting = ref(); const configMap = ref(cloneDeep(initialConfigMap)); const configMapFormData = ref< Record> | undefined >(); const saving = ref(false); const handleFetchSettings = async () => { if (!settingName.value) { setting.value = undefined; return; } try { const { data } = await apiClient.extension.setting.getv1alpha1Setting({ name: settingName.value, }); setting.value = data; // init configMapFormData if (!configMapFormData.value) { const { forms } = setting.value.spec; const initialConfigMapFormData: Record< string, Record > = {}; forms.forEach((form) => { initialConfigMapFormData[form.group] = {}; const formSchema = form.formSchema as ( | FormKitSchemaCondition | FormKitSchemaNode )[]; formSchema.forEach((schema) => { // @ts-ignore if ("name" in schema && "$formkit" in schema) { initialConfigMapFormData[form.group][schema.name] = schema.value || undefined; } }); }); configMapFormData.value = cloneDeep(initialConfigMapFormData); } } catch (e) { console.error("Failed to fetch setting", e); } }; const handleFetchConfigMap = async () => { if (!configMapName.value) { configMap.value = cloneDeep(initialConfigMap); configMapFormData.value = undefined; return; } try { const response = await apiClient.extension.configMap.getv1alpha1ConfigMap( { name: configMapName.value, }, { mute: true, } ); configMap.value = response.data; const { data } = configMap.value; if (data) { // merge objects value const { forms } = setting.value?.spec || {}; forms?.forEach((form) => { if (!configMapFormData.value) { return; } configMapFormData.value[form.group] = merge( configMapFormData.value[form.group] || {}, JSON.parse(data[form.group] || "{}") ); }); } } catch (e) { console.error("Failed to fetch configMap", e); } }; const handleSaveConfigMap = async () => { try { saving.value = true; if (!configMap.value.metadata.name && configMapName.value) { configMap.value.metadata.name = configMapName.value; } setting.value?.spec.forms.forEach((item: SettingForm) => { // @ts-ignore configMap.value.data[item.group] = JSON.stringify( configMapFormData?.value?.[item.group] ); }); if (!configMap.value.metadata.creationTimestamp) { const { data } = await apiClient.extension.configMap.createv1alpha1ConfigMap({ configMap: configMap.value, }); configMapName.value = data.metadata.name; } else { const { data } = await apiClient.extension.configMap.updatev1alpha1ConfigMap({ configMap: configMap.value, name: configMap.value.metadata.name, }); configMapName.value = data.metadata.name; } Toast.success(t("core.common.toast.save_success")); } catch (e) { console.error("Failed to save configMap", e); } finally { await handleFetchSettings(); await handleFetchConfigMap(); saving.value = false; } }; const handleReset = () => { setting.value = undefined; configMap.value = cloneDeep(initialConfigMap); configMapFormData.value = undefined; }; return { setting, configMap, configMapFormData, saving, handleFetchSettings, handleFetchConfigMap, handleSaveConfigMap, handleReset, }; } interface useSettingFormConvertReturn { formSchema: ComputedRef< (FormKitSchemaCondition | FormKitSchemaNode)[] | undefined >; configMapFormData: Ref>>; convertToSave: () => ConfigMap | undefined; } export function useSettingFormConvert( setting: Ref, configMap: Ref, group: Ref ): useSettingFormConvertReturn { const configMapFormData = ref>>({}); const formSchema = computed(() => { if (!setting.value) { return; } const { forms } = setting.value.spec; return forms.find((item) => item.group === group?.value)?.formSchema as ( | FormKitSchemaCondition | FormKitSchemaNode )[]; }); watch( () => configMap.value, () => { const { forms } = setting.value?.spec || {}; forms?.forEach((form) => { configMapFormData.value[form.group] = JSON.parse( configMap.value?.data?.[form.group] || "{}" ); }); Object.keys(configMap.value?.data || {}).forEach((key) => { if (!forms?.find((item) => item.group === key)) { configMapFormData.value[key] = JSON.parse( configMap.value?.data?.[key] || "{}" ); } }); }, { immediate: true, } ); function convertToSave() { const configMapToUpdate = cloneDeep(configMap.value); if (!configMapToUpdate) { return; } const data: { [key: string]: string; } = {}; const { forms } = setting.value?.spec || {}; forms?.forEach((item: SettingForm) => { data[item.group] = JSON.stringify(configMapFormData?.value?.[item.group]); }); Object.keys(configMap.value?.data || {}).forEach((key) => { if (!forms?.find((item) => item.group === key)) { data[key] = configMap.value?.data?.[key] || "{}"; } }); configMapToUpdate.data = data; return configMapToUpdate; } return { formSchema, configMapFormData, convertToSave, }; }