mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-02-02 08:19:42 +00:00
Update example plugin and add plugins frontend page with save config endpoint
This commit is contained in:
parent
62bd7e73f4
commit
ad89fb2eac
11 changed files with 276 additions and 36 deletions
123
client/pages/config/plugins/_slug.vue
Normal file
123
client/pages/config/plugins/_slug.vue
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-settings-content :header-text="`Plugin: ${plugin.name}`">
|
||||
<template #header-prefix>
|
||||
<nuxt-link to="/config/plugins" class="w-8 h-8 flex items-center justify-center rounded-full cursor-pointer hover:bg-white hover:bg-opacity-10 text-center mr-2">
|
||||
<span class="material-symbols text-2xl">arrow_back</span>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
<template #header-items>
|
||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||
<a href="https://www.audiobookshelf.org/guides" target="_blank" class="inline-flex">
|
||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||
</a>
|
||||
</ui-tooltip>
|
||||
</template>
|
||||
|
||||
<div class="py-4">
|
||||
<p class="mb-4">{{ configDescription }}</p>
|
||||
|
||||
<form v-if="configFormFields.length" @submit.prevent="handleFormSubmit">
|
||||
<template v-for="field in configFormFields">
|
||||
<div :key="field.name" class="flex items-center mb-4">
|
||||
<label :for="field.name" class="w-1/3 text-gray-200">{{ field.label }}</label>
|
||||
<div class="w-2/3">
|
||||
<input :id="field.name" :type="field.type" :placeholder="field.placeholder" class="w-full bg-bg border border-white border-opacity-20 rounded-md p-2 text-gray-200" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<ui-btn class="bg-primary bg-opacity-70 text-white rounded-md p-2" :loading="processing" type="submit">{{ $strings.ButtonSave }}</ui-btn>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</app-settings-content>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData({ store, redirect, params }) {
|
||||
if (!store.getters['user/getIsAdminOrUp']) {
|
||||
redirect('/')
|
||||
}
|
||||
const plugin = store.state.plugins.find((plugin) => plugin.slug === params.slug)
|
||||
if (!plugin) {
|
||||
redirect('/config/plugins')
|
||||
}
|
||||
return {
|
||||
plugin
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
processing: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pluginConfig() {
|
||||
return this.plugin.config
|
||||
},
|
||||
pluginLocalization() {
|
||||
return this.plugin.localization || {}
|
||||
},
|
||||
localizedStrings() {
|
||||
const localeKey = this.$languageCodes.current
|
||||
if (!localeKey) return {}
|
||||
return this.pluginLocalization[localeKey] || {}
|
||||
},
|
||||
configDescription() {
|
||||
if (this.pluginConfig.descriptionKey && this.localizedStrings[this.pluginConfig.descriptionKey]) {
|
||||
return this.localizedStrings[this.pluginConfig.descriptionKey]
|
||||
}
|
||||
|
||||
return this.pluginConfig.description
|
||||
},
|
||||
configFormFields() {
|
||||
return this.pluginConfig.formFields || []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getFormData() {
|
||||
const formData = {}
|
||||
this.configFormFields.forEach((field) => {
|
||||
if (field.type === 'checkbox') {
|
||||
formData[field.name] = document.getElementById(field.name).checked
|
||||
} else {
|
||||
formData[field.name] = document.getElementById(field.name).value
|
||||
}
|
||||
})
|
||||
return formData
|
||||
},
|
||||
handleFormSubmit() {
|
||||
const formData = this.getFormData()
|
||||
console.log('Form data', formData)
|
||||
|
||||
const payload = {
|
||||
pluginSlug: this.plugin.slug,
|
||||
config: formData
|
||||
}
|
||||
|
||||
this.processing = true
|
||||
|
||||
this.$axios
|
||||
.$post(`/api/plugins/config`, payload)
|
||||
.then(() => {
|
||||
console.log('Plugin configuration saved')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error saving plugin configuration', error)
|
||||
this.$toast.error('Error saving plugin configuration')
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('Plugin', this.plugin)
|
||||
},
|
||||
beforeDestroy() {}
|
||||
}
|
||||
</script>
|
||||
44
client/pages/config/plugins/index.vue
Normal file
44
client/pages/config/plugins/index.vue
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-settings-content :header-text="'Plugins'">
|
||||
<template #header-items>
|
||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||
<a href="https://www.audiobookshelf.org/guides" target="_blank" class="inline-flex">
|
||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||
</a>
|
||||
</ui-tooltip>
|
||||
</template>
|
||||
|
||||
<h2 class="text-xl font-medium">Installed Plugins</h2>
|
||||
<template v-for="plugin in plugins">
|
||||
<nuxt-link :key="plugin.slug" :to="`/config/plugins/${plugin.slug}`" class="flex items-center bg-primary rounded-md shadow-sm p-4 my-4 space-x-4">
|
||||
<p class="text-lg">{{ plugin.name }}</p>
|
||||
<p class="text-sm text-gray-300">{{ plugin.description }}</p>
|
||||
<div class="flex-grow" />
|
||||
<span class="material-symbols text-4xl">chevron_right</span>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
</app-settings-content>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData({ store, redirect }) {
|
||||
if (!store.getters['user/getIsAdminOrUp']) {
|
||||
redirect('/')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
plugins() {
|
||||
return this.$store.state.plugins
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
mounted() {},
|
||||
beforeDestroy() {}
|
||||
}
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue