|
|
@@ -1,5 +1,5 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { computed } from 'vue'
|
|
|
+import { computed, ref } from 'vue'
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
import { useVersionsStore } from '@/stores/versions'
|
|
|
import { useInstallStore } from '@/stores/install'
|
|
|
@@ -54,6 +54,29 @@ function handleInstall() {
|
|
|
function handleCancel() {
|
|
|
emit('cancel')
|
|
|
}
|
|
|
+
|
|
|
+// pnpm 安装相关
|
|
|
+const pnpmInstalling = ref(false)
|
|
|
+const pnpmError = ref('')
|
|
|
+
|
|
|
+const pnpmInstalled = computed(() => installStore.isInstalled('pnpm'))
|
|
|
+const pnpmInstalledVersion = computed(() => installStore.getInstalledVersion('pnpm'))
|
|
|
+
|
|
|
+async function handleInstallPnpm() {
|
|
|
+ if (pnpmInstalling.value || pnpmInstalled.value) return
|
|
|
+
|
|
|
+ pnpmInstalling.value = true
|
|
|
+ pnpmError.value = ''
|
|
|
+
|
|
|
+ try {
|
|
|
+ await window.electronAPI.install('pnpm', {})
|
|
|
+ } catch (error) {
|
|
|
+ pnpmError.value = (error as Error).message
|
|
|
+ } finally {
|
|
|
+ pnpmInstalling.value = false
|
|
|
+ await installStore.checkInstallStatus('pnpm')
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -88,18 +111,6 @@ function handleCancel() {
|
|
|
</el-select>
|
|
|
</div>
|
|
|
|
|
|
- <!-- pnpm 安装选项 -->
|
|
|
- <div class="pnpm-option">
|
|
|
- <div class="pnpm-row">
|
|
|
- <el-checkbox v-model="installStore.installOptions.nodejs.installPnpm" :disabled="installStore.isInstalled('pnpm')">
|
|
|
- {{ t('software.nodejs.installPnpm') }}
|
|
|
- </el-checkbox>
|
|
|
- <el-tag v-if="installStore.isInstalled('pnpm')" type="success" size="small">
|
|
|
- {{ t('common.installed') }} v{{ installStore.getInstalledVersion('pnpm') }}
|
|
|
- </el-tag>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
<div class="button-group">
|
|
|
<el-button type="primary" :disabled="isDisabled" :loading="status.installing" @click="handleInstall">
|
|
|
{{ buttonText }}
|
|
|
@@ -107,6 +118,30 @@ function handleCancel() {
|
|
|
<el-button v-if="status.installing" @click="handleCancel">{{ t('common.cancel') }}</el-button>
|
|
|
</div>
|
|
|
|
|
|
+ <!-- pnpm 安装选项 -->
|
|
|
+ <div class="pnpm-option">
|
|
|
+ <div class="ext-header">
|
|
|
+ <span class="ext-title">{{ t('software.nodejs.pnpmTitle') }}</span>
|
|
|
+ <el-tag v-if="pnpmInstalled" type="success" size="small">
|
|
|
+ {{ t('common.installed') }} v{{ pnpmInstalledVersion }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ <p class="ext-desc">{{ t('software.nodejs.pnpmDesc') }}</p>
|
|
|
+ <div class="ext-actions">
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ :type="pnpmInstalled ? 'success' : 'primary'"
|
|
|
+ :disabled="pnpmInstalled || pnpmInstalling || !isInstalled"
|
|
|
+ :loading="pnpmInstalling"
|
|
|
+ @click="handleInstallPnpm"
|
|
|
+ >
|
|
|
+ {{ pnpmInstalled ? t('common.installed') : pnpmInstalling ? t('common.installing') : t('software.nodejs.installPnpmBtn') }}
|
|
|
+ </el-button>
|
|
|
+ <span v-if="!isInstalled" class="ext-hint">{{ t('software.nodejs.installNodejsFirst') }}</span>
|
|
|
+ </div>
|
|
|
+ <p v-if="pnpmError" class="ext-error">{{ pnpmError }}</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div class="status-container">
|
|
|
<p :class="['status-text', { success: status.success, error: status.error }]">{{ statusText }}</p>
|
|
|
<el-progress
|
|
|
@@ -135,10 +170,39 @@ function handleCancel() {
|
|
|
border: 1px solid var(--border-color-lighter);
|
|
|
border-radius: var(--border-radius);
|
|
|
|
|
|
- .pnpm-row {
|
|
|
+ .ext-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: var(--spacing-sm);
|
|
|
+ margin-bottom: var(--spacing-xs);
|
|
|
+ }
|
|
|
+
|
|
|
+ .ext-title {
|
|
|
+ font-weight: 500;
|
|
|
+ color: var(--text-primary);
|
|
|
+ }
|
|
|
+
|
|
|
+ .ext-desc {
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--text-secondary);
|
|
|
+ margin: 0 0 var(--spacing-sm) 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ext-actions {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- gap: var(--spacing-md);
|
|
|
+ gap: var(--spacing-sm);
|
|
|
+ }
|
|
|
+
|
|
|
+ .ext-hint {
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--text-secondary);
|
|
|
+ }
|
|
|
+
|
|
|
+ .ext-error {
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--el-color-danger);
|
|
|
+ margin: var(--spacing-xs) 0 0 0;
|
|
|
}
|
|
|
}
|
|
|
}
|