forked from nuxt/devtools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ModuleInstallList.vue
135 lines (117 loc) · 3.82 KB
/
ModuleInstallList.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<script setup lang="ts">
// @ts-expect-error missing types
import { RecycleScroller } from 'vue-virtual-scroller'
import type { InstallModuleReturn, ModuleStaticInfo } from '@nuxt/devtools-kit/types'
import Fuse from 'fuse.js'
const Dialog = createTemplatePromise<boolean, [info: ModuleStaticInfo, result: InstallModuleReturn, type: 'install' | 'uninstall']>()
const collection = await useModulesInfo()
const { packageModules } = useModules()
const nuxt3only = collection.map((module) => {
const installed = packageModules.value.find(m => m.entryPath.includes(module.name))
return {
...module,
installed,
}
})
const config = useServerConfig()
const router = useRouter()
const search = ref('')
const fuse = computed(() => new Fuse(nuxt3only, {
keys: [
'name',
'description',
'npm',
'category',
],
}))
const items = computed(() => {
if (!search.value)
return nuxt3only
return fuse.value.search(search.value).map(r => r.item)
})
async function action(item: ModuleStaticInfo, type: 'install' | 'uninstall') {
const method = type === 'install' ? rpc.installNuxtModule : rpc.unInstallNuxtModule
const result = await method(item.npm, true)
if (!result.commands)
return
if (!await Dialog.start(item, result, type))
return
router.push(`/modules/terminals?id=${encodeURIComponent(result.processId)}`)
await method(item.npm, false)
}
const openInEditor = useOpenInEditor()
</script>
<template>
<div h-full flex="~ col gap-4">
<NIconTitle
mx6 mt6
text-xl op75
icon="i-carbon-3d-mpr-toggle"
text="Install Module"
/>
<NTextInput
v-model="search"
placeholder="Search..."
icon="carbon-search" n="primary"
mx6 px-5 py-2
/>
<div flex-auto of-auto flex="~ col gap-2" pl6 pr4>
<RecycleScroller
v-slot="{ item }"
class="scroller"
:items="items"
:item-size="160"
key-field="name"
>
<ModuleItemBase
:mod="{}"
role="button"
:info="item"
mb2 h-full class="hover:bg-active!"
:class="{
'text-green border-green': item.installed,
}"
:compact="true"
@click="action(item, item.installed ? 'uninstall' : 'install')"
/>
</RecycleScroller>
</div>
</div>
<Dialog v-slot="{ resolve, args }">
<NDialog :model-value="true" @close="resolve(false)">
<ModuleItemBase :mod="{}" :info="args[0]" border="none" w-150 n-panel-grids />
<div flex="~ col gap-2" w-150 p4 border="t base">
<h2 text-xl>
{{ args[2] }} <span capitalize :class="args[2] === 'install' ? 'text-primary' : 'text-red'">{{ args[0].name }}</span> module?
</h2>
<p op50>
Following command will be executed in your terminal:
</p>
<NCodeBlock :code="args[1].commands.join(' ')" lang="bash" px4 py2 border="~ base rounded" :lines="false" />
<p op50>
Then your <NLink role="button" n="primary" @click="openInEditor(config?._nuxtConfigFile)" v-text="'Nuxt config'" /> will be updated as:
</p>
<CodeDiff
:from="args[1].configOriginal"
:to="args[1].configGenerated"
max-h-80 of-auto py2 border="~ base rounded"
lang="ts"
/>
<p>
<span op50>After module installed, Nuxt will </span><span text-orange>restart automatically</span>.
</p>
<div flex="~ gap-3" mt2 justify-end>
<NTip n="sm purple" flex-auto icon="carbon-chemistry">
Experimental. Make sure to backup your project.
</NTip>
<NButton @click="resolve(false)">
Cancel
</NButton>
<NButton n="solid primary" capitalize @click="resolve(true)">
{{ args[2] }}
</NButton>
</div>
</div>
</NDialog>
</Dialog>
</template>