diff --git a/resources/assets/src/components/mixins/enablePlugin.ts b/resources/assets/src/components/mixins/enablePlugin.ts
new file mode 100644
index 00000000..a8e01505
--- /dev/null
+++ b/resources/assets/src/components/mixins/enablePlugin.ts
@@ -0,0 +1,52 @@
+import Vue from 'vue'
+
+export default Vue.extend({
+ data: () => ({ plugins: [] }),
+ methods: {
+ async enablePlugin({
+ name, dependencies: { requirements }, originalIndex,
+ }: {
+ name: string,
+ dependencies: { requirements: string[] },
+ originalIndex: number
+ }) {
+ if (requirements.length === 0) {
+ try {
+ await this.$confirm(
+ this.$t('admin.noDependenciesNotice'),
+ { type: 'warning' }
+ )
+ } catch {
+ return
+ }
+ }
+
+ const {
+ errno, msg, reason,
+ } = await this.$http.post(
+ '/admin/plugins/manage',
+ { action: 'enable', name }
+ ) as { errno: number, msg: string, reason: string[] }
+ if (errno === 0) {
+ this.$message.success(msg)
+ this.$set(this.plugins[originalIndex], 'enabled', true)
+ } else {
+ const div = document.createElement('div')
+ const p = document.createElement('p')
+ p.textContent = msg
+ div.appendChild(p)
+ const ul = document.createElement('ul')
+ reason.forEach(item => {
+ const li = document.createElement('li')
+ li.textContent = item
+ ul.appendChild(li)
+ })
+ div.appendChild(ul)
+ this.$alert(div.innerHTML.replace(/`([\w-_]+)`/g, '$1
'), {
+ dangerouslyUseHTMLString: true,
+ type: 'warning',
+ })
+ }
+ },
+ },
+})
diff --git a/resources/assets/src/views/admin/Market.vue b/resources/assets/src/views/admin/Market.vue
index 7188b9db..31e77489 100644
--- a/resources/assets/src/views/admin/Market.vue
+++ b/resources/assets/src/views/admin/Market.vue
@@ -73,6 +73,7 @@
diff --git a/resources/assets/src/views/admin/Plugins.vue b/resources/assets/src/views/admin/Plugins.vue
index d9927db5..5481cae8 100644
--- a/resources/assets/src/views/admin/Plugins.vue
+++ b/resources/assets/src/views/admin/Plugins.vue
@@ -77,6 +77,7 @@