|
|
|
@ -15,45 +15,45 @@ const emits = defineEmits(['saved'])
|
|
|
|
|
|
|
|
|
|
const toast = useToast() |
|
|
|
|
const { $api } = useNuxtApp() |
|
|
|
|
const plugin = ref<any>(null) |
|
|
|
|
const pluginFormData = ref<any>({}) |
|
|
|
|
const formRef = ref() |
|
|
|
|
const isLoading = ref(true) |
|
|
|
|
const loadingAction = ref<null | string>(null) |
|
|
|
|
let plugin = $ref<any>(null) |
|
|
|
|
let pluginFormData = $ref<any>({}) |
|
|
|
|
let isLoading = $ref(true) |
|
|
|
|
let loadingAction = $ref<null | string>(null) |
|
|
|
|
|
|
|
|
|
const saveSettings = async () => { |
|
|
|
|
loadingAction.value = 'save' |
|
|
|
|
loadingAction = 'save' |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
await formRef.value?.validateFields() |
|
|
|
|
|
|
|
|
|
await $api.plugin.update(id, { |
|
|
|
|
input: JSON.stringify(pluginFormData.value), |
|
|
|
|
input: JSON.stringify(pluginFormData), |
|
|
|
|
active: true, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
emits('saved') |
|
|
|
|
toast.success(plugin.value.formDetails.msgOnInstall || 'Plugin settings saved successfully') |
|
|
|
|
toast.success(plugin.formDetails.msgOnInstall || 'Plugin settings saved successfully') |
|
|
|
|
} catch (_e: any) { |
|
|
|
|
const e = await extractSdkResponseErrorMsg(_e) |
|
|
|
|
toast.error(e.message) |
|
|
|
|
} finally { |
|
|
|
|
loadingAction.value = null |
|
|
|
|
loadingAction = null |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const addSetting = () => { |
|
|
|
|
pluginFormData.value.push({}) |
|
|
|
|
pluginFormData.push({}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const testSettings = async () => { |
|
|
|
|
loadingAction.value = 'test' |
|
|
|
|
loadingAction = 'test' |
|
|
|
|
try { |
|
|
|
|
const res = await $api.plugin.test({ |
|
|
|
|
input: pluginFormData.value, |
|
|
|
|
id: plugin.value?.id, |
|
|
|
|
category: plugin.value?.category, |
|
|
|
|
title: plugin.value?.title, |
|
|
|
|
input: pluginFormData, |
|
|
|
|
id: plugin?.id, |
|
|
|
|
category: plugin?.category, |
|
|
|
|
title: plugin?.title, |
|
|
|
|
}) |
|
|
|
|
if (res) { |
|
|
|
|
toast.success('Successfully tested plugin settings') |
|
|
|
@ -64,7 +64,7 @@ const testSettings = async () => {
|
|
|
|
|
const e = await extractSdkResponseErrorMsg(_e) |
|
|
|
|
toast.error(e.message) |
|
|
|
|
} finally { |
|
|
|
|
loadingAction.value = null |
|
|
|
|
loadingAction = null |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -83,149 +83,147 @@ const doAction = async (action: { key: string }) => {
|
|
|
|
|
|
|
|
|
|
const readPluginDetails = async () => { |
|
|
|
|
try { |
|
|
|
|
isLoading.value = true |
|
|
|
|
isLoading = true |
|
|
|
|
const res = await $api.plugin.read(id) |
|
|
|
|
const formDetails = JSON.parse(res.input_schema ?? '{}') |
|
|
|
|
const emptyParsedInput = formDetails.array ? [{}] : {} |
|
|
|
|
const parsedInput = res.input ? JSON.parse(res.input) : emptyParsedInput |
|
|
|
|
|
|
|
|
|
plugin.value = { ...res, formDetails, parsedInput } |
|
|
|
|
pluginFormData.value = plugin.value.parsedInput |
|
|
|
|
plugin = { ...res, formDetails, parsedInput } |
|
|
|
|
pluginFormData = plugin.parsedInput |
|
|
|
|
} catch (e) { |
|
|
|
|
console.log(e) |
|
|
|
|
} finally { |
|
|
|
|
isLoading.value = false |
|
|
|
|
isLoading = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const deleteRow = (index: number) => { |
|
|
|
|
pluginFormData.value.splice(index, 1) |
|
|
|
|
const deleteFormRow = (index: number) => { |
|
|
|
|
pluginFormData.splice(index, 1) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
onMounted(async () => { |
|
|
|
|
if (plugin.value === null) { |
|
|
|
|
if (plugin === null) { |
|
|
|
|
await readPluginDetails() |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
|
<div> |
|
|
|
|
<div v-if="isLoading" class="flex flex-row w-full justify-center"> |
|
|
|
|
<a-spin size="large" /> |
|
|
|
|
</div> |
|
|
|
|
<template v-else> |
|
|
|
|
<div class="flex flex-col"> |
|
|
|
|
<div class="flex flex-row justify-center pb-4 mb-2 border-b-1 w-full space-x-1"> |
|
|
|
|
<div |
|
|
|
|
v-if="plugin.logo" |
|
|
|
|
:style="{ background: plugin.title === 'SES' ? '#242f3e' : '' }" |
|
|
|
|
class="mr-1 d-flex align-center justify-center" |
|
|
|
|
:class="{ 'pa-2': plugin.title === 'SES' }" |
|
|
|
|
> |
|
|
|
|
<img :src="`/${plugin.logo}`" class="h-6" /> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<span class="font-semibold text-lg">{{ plugin.formDetails.title }}</span> |
|
|
|
|
<div v-if="isLoading" class="flex flex-row w-full justify-center items-center h-52"> |
|
|
|
|
<a-spin size="large" /> |
|
|
|
|
</div> |
|
|
|
|
<template v-else> |
|
|
|
|
<div class="flex flex-col"> |
|
|
|
|
<div class="flex flex-row justify-center pb-4 mb-2 border-b-1 w-full space-x-1"> |
|
|
|
|
<div |
|
|
|
|
v-if="plugin.logo" |
|
|
|
|
:style="{ background: plugin.title === 'SES' ? '#242f3e' : '' }" |
|
|
|
|
class="mr-1 d-flex align-center justify-center" |
|
|
|
|
:class="{ 'pa-2': plugin.title === 'SES' }" |
|
|
|
|
> |
|
|
|
|
<img :src="`/${plugin.logo}`" class="h-6" /> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-form ref="formRef" :model="pluginFormData" class="mx-auto mt-2"> |
|
|
|
|
<!-- Form with multiple entry --> |
|
|
|
|
<table v-if="plugin.formDetails.array" class="form-table"> |
|
|
|
|
<thead> |
|
|
|
|
<tr> |
|
|
|
|
<th v-for="(columnData, columnIndex) in plugin.formDetails.items" :key="columnIndex"> |
|
|
|
|
<div class="text-center font-normal"> |
|
|
|
|
{{ columnData.label }} <span v-if="columnData.required" class="text-red-600">*</span> |
|
|
|
|
</div> |
|
|
|
|
</th> |
|
|
|
|
</tr> |
|
|
|
|
</thead> |
|
|
|
|
<tbody> |
|
|
|
|
<tr v-for="(itemRow, itemIndex) in plugin.parsedInput" :key="itemIndex"> |
|
|
|
|
<td v-for="(columnData, columnIndex) in plugin.formDetails.items" :key="columnIndex" class="px-2"> |
|
|
|
|
<a-form-item |
|
|
|
|
:name="[`${itemIndex}`, columnData.key]" |
|
|
|
|
:rules="[{ required: columnData.required, message: `${columnData.label} is required` }]" |
|
|
|
|
> |
|
|
|
|
<a-input-password |
|
|
|
|
v-if="columnData.type === 'Password'" |
|
|
|
|
v-model:value="itemRow[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-textarea |
|
|
|
|
v-else-if="columnData.type === 'LongText'" |
|
|
|
|
v-model:value="itemRow[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-switch |
|
|
|
|
v-else-if="columnData.type === 'Checkbox'" |
|
|
|
|
v-model:value="itemRow[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-input v-else v-model:value="itemRow[columnData.key]" :placeholder="columnData.placeholder" /> |
|
|
|
|
</a-form-item> |
|
|
|
|
</td> |
|
|
|
|
<td v-if="itemIndex !== 0" class="pb-4"> |
|
|
|
|
<MdiDeleteOutlineIcon class="hover:text-red-400 cursor-pointer" @click="deleteRow(itemIndex)" /> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
</tbody> |
|
|
|
|
<span class="font-semibold text-lg">{{ plugin.formDetails.title }}</span> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-form ref="formRef" :model="pluginFormData" class="mx-auto mt-2"> |
|
|
|
|
<!-- Form with multiple entry --> |
|
|
|
|
<table v-if="plugin.formDetails.array" class="form-table"> |
|
|
|
|
<thead> |
|
|
|
|
<tr> |
|
|
|
|
<td :colspan="plugin.formDetails.items.length" class="text-center"> |
|
|
|
|
<a-button type="default" class="!bg-gray-100 rounded-md border-0" @click="addSetting"> |
|
|
|
|
<template #icon> |
|
|
|
|
<MdiPlusIcon class="flex mx-auto" /> |
|
|
|
|
</template> |
|
|
|
|
</a-button> |
|
|
|
|
<th v-for="(columnData, columnIndex) in plugin.formDetails.items" :key="columnIndex"> |
|
|
|
|
<div class="text-center font-normal"> |
|
|
|
|
{{ columnData.label }} <span v-if="columnData.required" class="text-red-600">*</span> |
|
|
|
|
</div> |
|
|
|
|
</th> |
|
|
|
|
</tr> |
|
|
|
|
</thead> |
|
|
|
|
<tbody> |
|
|
|
|
<tr v-for="(itemRow, itemIndex) in plugin.parsedInput" :key="itemIndex"> |
|
|
|
|
<td v-for="(columnData, columnIndex) in plugin.formDetails.items" :key="columnIndex" class="px-2"> |
|
|
|
|
<a-form-item |
|
|
|
|
:name="[`${itemIndex}`, columnData.key]" |
|
|
|
|
:rules="[{ required: columnData.required, message: `${columnData.label} is required` }]" |
|
|
|
|
> |
|
|
|
|
<a-input-password |
|
|
|
|
v-if="columnData.type === 'Password'" |
|
|
|
|
v-model:value="itemRow[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-textarea |
|
|
|
|
v-else-if="columnData.type === 'LongText'" |
|
|
|
|
v-model:value="itemRow[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-switch |
|
|
|
|
v-else-if="columnData.type === 'Checkbox'" |
|
|
|
|
v-model:value="itemRow[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-input v-else v-model:value="itemRow[columnData.key]" :placeholder="columnData.placeholder" /> |
|
|
|
|
</a-form-item> |
|
|
|
|
</td> |
|
|
|
|
<td v-if="itemIndex !== 0" class="pb-4"> |
|
|
|
|
<MdiDeleteOutlineIcon class="hover:text-red-400 cursor-pointer" @click="deleteFormRow(itemIndex)" /> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
</table> |
|
|
|
|
|
|
|
|
|
<!-- Form with only one entry --> |
|
|
|
|
<div v-else> |
|
|
|
|
<a-form-item |
|
|
|
|
v-for="(columnData, i) in plugin.formDetails.items" |
|
|
|
|
:key="i" |
|
|
|
|
:label="columnData.label" |
|
|
|
|
:name="columnData.key" |
|
|
|
|
:rules="[{ required: columnData.required, message: `${columnData.label} is required` }]" |
|
|
|
|
> |
|
|
|
|
<a-input-password |
|
|
|
|
v-if="columnData.type === 'Password'" |
|
|
|
|
v-model:value="pluginFormData[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-textarea |
|
|
|
|
v-else-if="columnData.type === 'LongText'" |
|
|
|
|
v-model:value="pluginFormData[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-switch |
|
|
|
|
v-else-if="columnData.type === 'Checkbox'" |
|
|
|
|
v-model:checked="pluginFormData[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-input v-else v-model:value="pluginFormData[columnData.key]" :placeholder="columnData.placeholder" /> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
<div class="flex flex-row space-x-4 justify-center mt-4"> |
|
|
|
|
<a-button |
|
|
|
|
v-for="(action, i) in plugin.formDetails.actions" |
|
|
|
|
:key="i" |
|
|
|
|
:loading="loadingAction === action.key" |
|
|
|
|
:type="action.key === 'save' ? 'primary' : 'default'" |
|
|
|
|
:disabled="!!loadingAction" |
|
|
|
|
@click="doAction(action)" |
|
|
|
|
> |
|
|
|
|
{{ action.label }} |
|
|
|
|
</a-button> |
|
|
|
|
</div> |
|
|
|
|
</a-form> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
</div> |
|
|
|
|
</tbody> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td :colspan="plugin.formDetails.items.length" class="text-center"> |
|
|
|
|
<a-button type="default" class="!bg-gray-100 rounded-md border-0" @click="addSetting"> |
|
|
|
|
<template #icon> |
|
|
|
|
<MdiPlusIcon class="flex mx-auto" /> |
|
|
|
|
</template> |
|
|
|
|
</a-button> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
</table> |
|
|
|
|
|
|
|
|
|
<!-- Form with only one entry --> |
|
|
|
|
<div v-else> |
|
|
|
|
<a-form-item |
|
|
|
|
v-for="(columnData, i) in plugin.formDetails.items" |
|
|
|
|
:key="i" |
|
|
|
|
:label="columnData.label" |
|
|
|
|
:name="columnData.key" |
|
|
|
|
:rules="[{ required: columnData.required, message: `${columnData.label} is required` }]" |
|
|
|
|
> |
|
|
|
|
<a-input-password |
|
|
|
|
v-if="columnData.type === 'Password'" |
|
|
|
|
v-model:value="pluginFormData[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-textarea |
|
|
|
|
v-else-if="columnData.type === 'LongText'" |
|
|
|
|
v-model:value="pluginFormData[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-switch |
|
|
|
|
v-else-if="columnData.type === 'Checkbox'" |
|
|
|
|
v-model:checked="pluginFormData[columnData.key]" |
|
|
|
|
:placeholder="columnData.placeholder" |
|
|
|
|
/> |
|
|
|
|
<a-input v-else v-model:value="pluginFormData[columnData.key]" :placeholder="columnData.placeholder" /> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
<div class="flex flex-row space-x-4 justify-center mt-4"> |
|
|
|
|
<a-button |
|
|
|
|
v-for="(action, i) in plugin.formDetails.actions" |
|
|
|
|
:key="i" |
|
|
|
|
:loading="loadingAction === action.key" |
|
|
|
|
:type="action.key === 'save' ? 'primary' : 'default'" |
|
|
|
|
:disabled="!!loadingAction" |
|
|
|
|
@click="doAction(action)" |
|
|
|
|
> |
|
|
|
|
{{ action.label }} |
|
|
|
|
</a-button> |
|
|
|
|
</div> |
|
|
|
|
</a-form> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
|