mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 21:38:57 +08:00
feat: Optimize the structure of installed apps in the App Store
This commit is contained in:
parent
15bc6cf884
commit
b965b1357b
9 changed files with 439 additions and 395 deletions
|
|
@ -626,10 +626,10 @@ func (w WebsiteService) GetWebsite(id uint) (response.WebsiteDTO, error) {
|
|||
dName := d.GetName()
|
||||
if _, ok := dto.LBAlgorithms[dName]; ok {
|
||||
res.Algorithm = dName
|
||||
break
|
||||
}
|
||||
}
|
||||
res.Servers = getNginxUpstreamServers(up.UpstreamServers)
|
||||
break
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ export namespace App {
|
|||
webUI: string;
|
||||
appKey?: string;
|
||||
serviceName: string;
|
||||
appStatus?: string;
|
||||
appType?: string;
|
||||
version?: string;
|
||||
}
|
||||
|
||||
export interface AppInstalledInfo {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ export interface SearchWithPage {
|
|||
}
|
||||
export interface CommonModel {
|
||||
id: number;
|
||||
CreatedAt?: string;
|
||||
UpdatedAt?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
export interface DescriptionUpdate {
|
||||
id: number;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ const getApp = async () => {
|
|||
try {
|
||||
const res = await getAppByKey(appKey.value);
|
||||
app.value = res.data;
|
||||
app.value.icon = 'data:image/png;base64,' + res.data.icon;
|
||||
version.value = app.value.versions[0];
|
||||
getDetail(app.value.id, version.value);
|
||||
} finally {
|
||||
|
|
|
|||
78
frontend/src/views/app-store/installed/app/card.vue
Normal file
78
frontend/src/views/app-store/installed/app/card.vue
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<div class="install-card">
|
||||
<el-card class="e-card">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="3" :sm="3" :md="3" :lg="4" :xl="3">
|
||||
<AppIcon
|
||||
@open-detail="$emit('openDetail')"
|
||||
:appID="installed.appID"
|
||||
:currentNode="currentNode"
|
||||
></AppIcon>
|
||||
</el-col>
|
||||
<el-col :xs="21" :sm="21" :md="21" :lg="20" :xl="21">
|
||||
<div class="a-detail">
|
||||
<AppHeader
|
||||
:installed="installed"
|
||||
:mode="mode"
|
||||
:defaultLink="defaultLink"
|
||||
@open-backups="$emit('openBackups')"
|
||||
@open-log="$emit('openLog')"
|
||||
@open-terminal="$emit('openTerminal')"
|
||||
@open-operate="$emit('openOperate')"
|
||||
@favorite-install="$emit('favoriteInstall')"
|
||||
@to-folder="$emit('toFolder')"
|
||||
@open-uploads="$emit('openUploads')"
|
||||
@ignore-app="$emit('ignoreApp')"
|
||||
@to-container="$emit('toContainer')"
|
||||
></AppHeader>
|
||||
<AppInfo
|
||||
:installed="installed"
|
||||
:defaultLink="defaultLink"
|
||||
@open-link="$emit('openLink')"
|
||||
@to-link="$emit('toLink')"
|
||||
@jump-to-path="$emit('jumpToPath', '/settings/panel')"
|
||||
></AppInfo>
|
||||
<div class="app-divider" />
|
||||
<slot name="buttons"></slot>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import AppIcon from '@/views/app-store/installed/app/icon.vue';
|
||||
import AppHeader from '@/views/app-store/installed/app/header.vue';
|
||||
import AppInfo from '@/views/app-store/installed/app/info.vue';
|
||||
|
||||
import { App } from '@/api/interface/app';
|
||||
|
||||
interface Props {
|
||||
installed: App.AppInstalled;
|
||||
mode: string;
|
||||
defaultLink: string;
|
||||
currentNode: string;
|
||||
}
|
||||
defineProps<Props>();
|
||||
|
||||
defineEmits([
|
||||
'toFolder',
|
||||
'openUploads',
|
||||
'openDetail',
|
||||
'openBackups',
|
||||
'openLog',
|
||||
'openTerminal',
|
||||
'openOperate',
|
||||
'favoriteInstall',
|
||||
'openLink',
|
||||
'toLink',
|
||||
'jumpToPath',
|
||||
'ignoreApp',
|
||||
'toContainer',
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use '@/views/app-store/index.scss';
|
||||
</style>
|
||||
193
frontend/src/views/app-store/installed/app/header.vue
Normal file
193
frontend/src/views/app-store/installed/app/header.vue
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
<template>
|
||||
<div class="d-name">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="min-w-50 flex items-center justify-start gap-1">
|
||||
<el-button link type="info">
|
||||
<el-tooltip :content="installed.name" placement="top">
|
||||
<span class="name">{{ installed.name }}</span>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
<span class="status">
|
||||
<Status :key="installed.status" :status="installed.status"></Status>
|
||||
</span>
|
||||
<span class="msg">
|
||||
<el-popover
|
||||
v-if="isAppErr(installed)"
|
||||
placement="bottom"
|
||||
:width="400"
|
||||
trigger="hover"
|
||||
:content="installed.message"
|
||||
:popper-options="options"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button link type="danger">
|
||||
<el-icon><Warning /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
<div class="app-error">
|
||||
{{ installed.message }}
|
||||
</div>
|
||||
</el-popover>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip effect="dark" :content="$t('app.toFolder')" placement="top">
|
||||
<el-button type="primary" link @click="$emit('toFolder')" icon="FolderOpened"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip
|
||||
v-if="mode !== 'upgrade'"
|
||||
effect="dark"
|
||||
:content="$t('commons.button.log')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="$emit('openLog')"
|
||||
:disabled="installed.status === 'DownloadErr'"
|
||||
>
|
||||
<el-icon><Tickets /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip v-if="mode !== 'upgrade'" effect="dark" :content="$t('menu.terminal')" placement="top">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="$emit('openTerminal')"
|
||||
:disabled="installed.status !== 'Running'"
|
||||
>
|
||||
<el-icon>
|
||||
<SvgIcon iconName="p-terminal2" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip v-if="mode !== 'upgrade'" effect="dark" :content="$t('menu.container')" placement="top">
|
||||
<el-button type="primary" link @click="$emit('toContainer')">
|
||||
<el-icon>
|
||||
<SvgIcon iconName="p-docker" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1" v-if="mode === 'installed'">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('website.cancelFavorite')"
|
||||
placement="top-start"
|
||||
v-if="installed.favorite"
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
size="large"
|
||||
icon="StarFilled"
|
||||
type="warning"
|
||||
@click="$emit('favoriteInstall')"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('website.favorite')" placement="top-start" v-else>
|
||||
<el-button link icon="Star" type="info" @click="$emit('favoriteInstall')"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
@click="$emit('openUploads')"
|
||||
v-if="mode === 'installed'"
|
||||
>
|
||||
{{ $t('database.loadBackup') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
@click="$emit('openBackups')"
|
||||
v-if="mode === 'installed'"
|
||||
>
|
||||
{{ $t('commons.button.backup') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
:disabled="installed.status === 'Upgrading'"
|
||||
@click="$emit('ignoreApp')"
|
||||
v-if="mode === 'upgrade'"
|
||||
>
|
||||
{{ $t('commons.button.ignore') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
:disabled="
|
||||
(installed.status !== 'Running' && installed.status !== 'UpgradeErr') ||
|
||||
installed.appStatus === 'TakeDown'
|
||||
"
|
||||
@click="$emit('openOperate')"
|
||||
v-if="mode === 'upgrade'"
|
||||
>
|
||||
{{ $t('commons.button.upgrade') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { App } from '@/api/interface/app';
|
||||
|
||||
interface Props {
|
||||
installed: App.AppInstalled;
|
||||
mode: string;
|
||||
}
|
||||
defineProps<Props>();
|
||||
|
||||
defineEmits([
|
||||
'toFolder',
|
||||
'openLog',
|
||||
'openTerminal',
|
||||
'toContainer',
|
||||
'openBackups',
|
||||
'openOperate',
|
||||
'ignoreApp',
|
||||
'openUploads',
|
||||
'favoriteInstall',
|
||||
]);
|
||||
|
||||
const options = {
|
||||
modifiers: [
|
||||
{
|
||||
name: 'flip',
|
||||
options: {
|
||||
padding: 5,
|
||||
fallbackPlacements: ['bottom-start', 'top-start', 'right', 'left'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const isAppErr = (row: any) => {
|
||||
return row.status.includes('Err') || row.status.includes('Error') || row.status.includes('UnHealthy');
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@use '@/views/app-store/index.scss';
|
||||
|
||||
.svg-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
17
frontend/src/views/app-store/installed/app/icon.vue
Normal file
17
frontend/src/views/app-store/installed/app/icon.vue
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<template>
|
||||
<div class="icon">
|
||||
<el-avatar @click="$emit('openDetail')" shape="square" :size="77" :src="getAppIconUrl(appID, currentNode)" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getAppIconUrl } from '@/api/modules/app';
|
||||
|
||||
interface Props {
|
||||
currentNode: string;
|
||||
appID: number;
|
||||
}
|
||||
defineProps<Props>();
|
||||
|
||||
defineEmits(['openDetail']);
|
||||
</script>
|
||||
98
frontend/src/views/app-store/installed/app/info.vue
Normal file
98
frontend/src/views/app-store/installed/app/info.vue
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="d-description flex flex-wrap items-center justify-start gap-1.5">
|
||||
<el-button class="mr-1" plain size="small">
|
||||
{{ $t('app.version') }}{{ $t('commons.colon') }}{{ installed.version }}
|
||||
</el-button>
|
||||
<el-button v-if="installed.httpPort > 0" class="mr-1" plain size="small">
|
||||
{{ $t('commons.table.port') }}{{ $t('commons.colon') }}{{ installed.httpPort }}
|
||||
</el-button>
|
||||
<el-button v-if="installed.httpsPort > 0" plain size="small">
|
||||
{{ $t('commons.table.port') }}:{{ installed.httpsPort }}
|
||||
</el-button>
|
||||
|
||||
<el-popover placement="top-start" trigger="hover" v-if="hasLinkButton(installed)" :width="400">
|
||||
<template #reference>
|
||||
<el-button plain icon="Promotion" size="small" @click="$emit('openLink')">
|
||||
{{ $t('app.toLink') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr v-if="defaultLink != ''">
|
||||
<td v-if="installed.httpPort > 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="$emit('toLink', 'http://' + defaultLink + ':' + installed.httpPort)"
|
||||
>
|
||||
{{ 'http://' + defaultLink + ':' + installed.httpPort }}
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="defaultLink != ''">
|
||||
<td v-if="installed.httpsPort > 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="$emit('toLink', 'https://' + defaultLink + ':' + installed.httpsPort)"
|
||||
>
|
||||
{{ 'https://' + defaultLink + ':' + installed.httpsPort }}
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="installed.webUI != ''">
|
||||
<td>
|
||||
<el-button type="primary" link @click="$emit('toLink')">
|
||||
{{ installed.webUI }}
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<span v-if="defaultLink == '' && installed.webUI == ''">
|
||||
{{ $t('app.webUIConfig') }}
|
||||
<el-link icon="Position" @click="$emit('jumpToPath')" type="primary">
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</el-link>
|
||||
</span>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="description">
|
||||
<span>
|
||||
{{ $t('app.alreadyRun') }}{{ $t('commons.colon') }}
|
||||
{{ getAge(installed.createdAt) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { App } from '@/api/interface/app';
|
||||
import { getAge } from '@/utils/util';
|
||||
|
||||
interface Props {
|
||||
installed: App.AppInstalled;
|
||||
defaultLink: string;
|
||||
}
|
||||
defineProps<Props>();
|
||||
|
||||
defineEmits(['openLink', 'toLink', 'jumpToPath']);
|
||||
|
||||
const hasLinkButton = (installed: any) => {
|
||||
return (
|
||||
(installed.appType == 'website' || installed.appKey?.startsWith('local')) &&
|
||||
(installed.httpPort > 0 || installed.httpsPort > 0 || installed.webUI != '')
|
||||
);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use '@/views/app-store/index.scss';
|
||||
|
||||
.d-description {
|
||||
.el-button + .el-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -29,7 +29,6 @@
|
|||
>
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</el-link>
|
||||
|
||||
</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
|
@ -49,343 +48,46 @@
|
|||
:lg="12"
|
||||
:xl="12"
|
||||
>
|
||||
<div class="install-card">
|
||||
<el-card class="e-card">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="3" :sm="3" :md="3" :lg="4" :xl="4">
|
||||
<div class="icon">
|
||||
<el-avatar
|
||||
@click="openDetail(installed.appKey)"
|
||||
shape="square"
|
||||
:size="66"
|
||||
:src="getAppIconUrl(installed.appID, currentNode)"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="21" :md="21" :lg="20" :xl="20">
|
||||
<div class="a-detail">
|
||||
<div class="d-name">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="min-w-50 flex items-center justify-start gap-1">
|
||||
<el-button link type="info">
|
||||
<el-tooltip :content="installed.name" placement="top">
|
||||
<span class="name">{{ installed.name }}</span>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
<span class="status">
|
||||
<Status
|
||||
:key="installed.status"
|
||||
:status="installed.status"
|
||||
></Status>
|
||||
</span>
|
||||
<span class="msg">
|
||||
<el-popover
|
||||
v-if="isAppErr(installed)"
|
||||
placement="bottom"
|
||||
:width="400"
|
||||
trigger="hover"
|
||||
:content="installed.message"
|
||||
:popper-options="options"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button link type="danger">
|
||||
<el-icon><Warning /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
<div class="app-error">
|
||||
{{ installed.message }}
|
||||
</div>
|
||||
</el-popover>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('app.toFolder')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="routerToFileWithPath(installed.path)"
|
||||
icon="FolderOpened"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip
|
||||
v-if="mode !== 'upgrade'"
|
||||
effect="dark"
|
||||
:content="$t('commons.button.log')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="openLog(installed)"
|
||||
:disabled="installed.status === 'DownloadErr'"
|
||||
>
|
||||
<el-icon><Tickets /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip
|
||||
v-if="mode !== 'upgrade'"
|
||||
effect="dark"
|
||||
:content="$t('menu.terminal')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="openTerminal(installed)"
|
||||
:disabled="installed.status !== 'Running'"
|
||||
>
|
||||
<el-icon>
|
||||
<SvgIcon iconName="p-terminal2" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip
|
||||
v-if="mode !== 'upgrade'"
|
||||
effect="dark"
|
||||
:content="$t('menu.container')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="toContainer(installed)"
|
||||
>
|
||||
<el-icon>
|
||||
<SvgIcon iconName="p-docker" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span class="ml-1" v-if="mode === 'installed'">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('website.cancelFavorite')"
|
||||
placement="top-start"
|
||||
v-if="installed.favorite"
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
size="large"
|
||||
icon="StarFilled"
|
||||
type="warning"
|
||||
@click="favoriteInstall(installed)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('website.favorite')"
|
||||
placement="top-start"
|
||||
v-else
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
icon="Star"
|
||||
type="info"
|
||||
@click="favoriteInstall(installed)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
@click="openUploads(installed.appKey, installed.name)"
|
||||
v-if="mode === 'installed'"
|
||||
>
|
||||
{{ $t('database.loadBackup') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
@click="openBackups(installed)"
|
||||
v-if="mode === 'installed'"
|
||||
>
|
||||
{{ $t('commons.button.backup') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
:disabled="installed.status === 'Upgrading'"
|
||||
@click="ignoreApp(installed)"
|
||||
v-if="mode === 'upgrade'"
|
||||
>
|
||||
{{ $t('commons.button.ignore') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="h-button"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
:disabled="
|
||||
(installed.status !== 'Running' &&
|
||||
installed.status !== 'UpgradeErr') ||
|
||||
installed.appStatus === 'TakeDown'
|
||||
"
|
||||
@click="openOperate(installed, 'upgrade')"
|
||||
v-if="mode === 'upgrade'"
|
||||
>
|
||||
{{ $t('commons.button.upgrade') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-description flex flex-wrap items-center justify-start gap-1.5"
|
||||
>
|
||||
<el-button class="mr-1" plain size="small">
|
||||
{{ $t('app.version') }}{{ $t('commons.colon')
|
||||
}}{{ installed.version }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="installed.httpPort > 0"
|
||||
class="mr-1"
|
||||
plain
|
||||
size="small"
|
||||
>
|
||||
{{ $t('commons.table.port') }}{{ $t('commons.colon')
|
||||
}}{{ installed.httpPort }}
|
||||
</el-button>
|
||||
<el-button v-if="installed.httpsPort > 0" plain size="small">
|
||||
{{ $t('commons.table.port') }}:{{ installed.httpsPort }}
|
||||
</el-button>
|
||||
|
||||
<el-popover
|
||||
placement="top-start"
|
||||
trigger="hover"
|
||||
v-if="hasLinkButton(installed)"
|
||||
:width="400"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
plain
|
||||
icon="Promotion"
|
||||
size="small"
|
||||
@click="openLink(defaultLink, installed)"
|
||||
>
|
||||
{{ $t('app.toLink') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr v-if="defaultLink != ''">
|
||||
<td v-if="installed.httpPort > 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="
|
||||
toLink(
|
||||
'http://' +
|
||||
defaultLink +
|
||||
':' +
|
||||
installed.httpPort,
|
||||
)
|
||||
"
|
||||
>
|
||||
{{
|
||||
'http://' +
|
||||
defaultLink +
|
||||
':' +
|
||||
installed.httpPort
|
||||
}}
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="defaultLink != ''">
|
||||
<td v-if="installed.httpsPort > 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="
|
||||
toLink(
|
||||
'https://' +
|
||||
defaultLink +
|
||||
':' +
|
||||
installed.httpsPort,
|
||||
)
|
||||
"
|
||||
>
|
||||
{{
|
||||
'https://' +
|
||||
defaultLink +
|
||||
':' +
|
||||
installed.httpsPort
|
||||
}}
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="installed.webUI != ''">
|
||||
<td>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="toLink(installed.webUI)"
|
||||
>
|
||||
{{ installed.webUI }}
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<span v-if="defaultLink == '' && installed.webUI == ''">
|
||||
{{ $t('app.webUIConfig') }}
|
||||
<el-link
|
||||
icon="Position"
|
||||
@click="jumpToPath(router, '/settings/panel')"
|
||||
type="primary"
|
||||
>
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</el-link>
|
||||
</span>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="description">
|
||||
<span>
|
||||
{{ $t('app.alreadyRun') }}{{ $t('commons.colon') }}
|
||||
{{ getAge(installed.createdAt) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="app-divider" />
|
||||
<div
|
||||
class="d-button flex flex-wrap items-center justify-start gap-1.5"
|
||||
v-if="mode === 'installed' && installed.status != 'Installing'"
|
||||
>
|
||||
<el-button
|
||||
class="app-button"
|
||||
v-for="(button, key) in buttons"
|
||||
:key="key"
|
||||
:type="
|
||||
button.disabled && button.disabled(installed) ? 'info' : ''
|
||||
"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
@click="button.click(installed)"
|
||||
:disabled="button.disabled && button.disabled(installed)"
|
||||
>
|
||||
{{ button.label }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
<AppCard
|
||||
:installed="installed"
|
||||
:mode="mode"
|
||||
:defaultLink="defaultLink"
|
||||
:currentNode="currentNode"
|
||||
@open-detail="openDetail(installed.appKey)"
|
||||
@open-backups="openBackups(installed)"
|
||||
@open-log="openLog(installed)"
|
||||
@open-terminal="openTerminal(installed)"
|
||||
@open-operate="openOperate(installed, 'upgrade')"
|
||||
@favorite-install="favoriteInstall(installed)"
|
||||
@to-folder="routerToFileWithPath(installed.path)"
|
||||
@open-uploads="openUploads(installed.appKey, installed.name)"
|
||||
@open-link="openLink(defaultLink, installed)"
|
||||
@to-link="toLink(installed.webUI)"
|
||||
@jump-to-path="jumpToPath(router, '/settings/panel')"
|
||||
@to-container="toContainer(installed)"
|
||||
@ignore-app="ignoreApp(installed)"
|
||||
>
|
||||
<template #buttons>
|
||||
<div
|
||||
class="d-button flex flex-wrap items-center justify-start gap-1.5"
|
||||
v-if="mode === 'installed' && installed.status != 'Installing'"
|
||||
>
|
||||
<el-button
|
||||
class="app-button"
|
||||
v-for="(button, key) in buttons"
|
||||
:key="key"
|
||||
:type="button.disabled && button.disabled(installed) ? 'info' : ''"
|
||||
plain
|
||||
round
|
||||
size="small"
|
||||
@click="button.click(installed)"
|
||||
:disabled="button.disabled && button.disabled(installed)"
|
||||
>
|
||||
{{ button.label }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</AppCard>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</MainDiv>
|
||||
|
|
@ -407,7 +109,6 @@
|
|||
<AppDelete ref="deleteRef" @close="search" />
|
||||
<AppParams ref="appParamRef" @close="search" />
|
||||
<AppUpgrade ref="upgradeRef" @close="search" />
|
||||
<PortJumpDialog ref="dialogPortJumpRef" />
|
||||
<AppIgnore ref="ignoreRef" @close="search" />
|
||||
<ComposeLogs ref="composeLogRef" />
|
||||
<TerminalDialog ref="dialogTerminalRef" />
|
||||
|
|
@ -417,30 +118,28 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import AppCard from '@/views/app-store/installed/app/card.vue';
|
||||
import Backups from '@/components/backup/index.vue';
|
||||
import Uploads from '@/components/upload/index.vue';
|
||||
import PortJumpDialog from '@/components/port-jump/index.vue';
|
||||
import AppResources from './check/index.vue';
|
||||
import AppDelete from './delete/index.vue';
|
||||
import AppParams from './detail/index.vue';
|
||||
import AppUpgrade from './upgrade/index.vue';
|
||||
import AppIgnore from './ignore/index.vue';
|
||||
import Status from '@/components/status/index.vue';
|
||||
import TaskLog from '@/components/log/task/index.vue';
|
||||
import Detail from '@/views/app-store/detail/index.vue';
|
||||
import Tags from '@/views/app-store/components/tag.vue';
|
||||
import SvgIcon from '@/components/svg-icon/svg-icon.vue';
|
||||
import MainDiv from '@/components/main-div/index.vue';
|
||||
import ComposeLogs from '@/components/log/compose/index.vue';
|
||||
import IgnoreApp from '@/views/app-store/installed/ignore/create/index.vue';
|
||||
import TerminalDialog from '@/views/container/container/terminal/index.vue';
|
||||
|
||||
import { searchAppInstalled, installedOp, appInstalledDeleteCheck, getAppIconUrl } from '@/api/modules/app';
|
||||
import { searchAppInstalled, installedOp, appInstalledDeleteCheck } from '@/api/modules/app';
|
||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { App } from '@/api/interface/app';
|
||||
import { getAge, jumpToPath, toLink } from '@/utils/util';
|
||||
import { jumpToPath, toLink } from '@/utils/util';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { getAgentSettingByKey } from '@/api/modules/setting';
|
||||
|
|
@ -472,7 +171,6 @@ const deleteRef = ref();
|
|||
const appParamRef = ref();
|
||||
const upgradeRef = ref();
|
||||
const ignoreRef = ref();
|
||||
const dialogPortJumpRef = ref();
|
||||
const composeLogRef = ref();
|
||||
const dialogTerminalRef = ref();
|
||||
const taskLogRef = ref();
|
||||
|
|
@ -491,18 +189,6 @@ const defaultLink = ref('');
|
|||
const detailRef = ref();
|
||||
const ignoreAppRef = ref();
|
||||
|
||||
const options = {
|
||||
modifiers: [
|
||||
{
|
||||
name: 'flip',
|
||||
options: {
|
||||
padding: 5,
|
||||
fallbackPlacements: ['bottom-start', 'top-start', 'right', 'left'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const openDetail = (key: string) => {
|
||||
detailRef.value.acceptParams(key, 'install');
|
||||
};
|
||||
|
|
@ -515,13 +201,6 @@ const changeTag = (key: string) => {
|
|||
search();
|
||||
};
|
||||
|
||||
const hasLinkButton = (installed: any) => {
|
||||
return (
|
||||
(installed.appType == 'website' || installed.appKey?.startsWith('local')) &&
|
||||
(installed.httpPort > 0 || installed.httpsPort > 0 || installed.webUI != '')
|
||||
);
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
searchReq.page = paginationConfig.currentPage;
|
||||
searchReq.pageSize = paginationConfig.pageSize;
|
||||
|
|
@ -579,10 +258,6 @@ const openIgnore = () => {
|
|||
ignoreRef.value.acceptParams();
|
||||
};
|
||||
|
||||
const ignoreApp = (row: App.AppInstalled) => {
|
||||
ignoreAppRef.value.acceptParams(row);
|
||||
};
|
||||
|
||||
const operate = async () => {
|
||||
open.value = false;
|
||||
loading.value = true;
|
||||
|
|
@ -702,6 +377,10 @@ const buttons = [
|
|||
},
|
||||
];
|
||||
|
||||
const ignoreApp = (row: App.AppInstalled) => {
|
||||
ignoreAppRef.value.acceptParams(row);
|
||||
};
|
||||
|
||||
const toContainer = async (row: App.AppInstalled) => {
|
||||
routerToNameWithQuery('ContainerItem', {
|
||||
filters: 'com.docker.compose.project=' + row.serviceName,
|
||||
|
|
@ -733,10 +412,6 @@ const openParam = (row: any) => {
|
|||
appParamRef.value.acceptParams({ id: row.id });
|
||||
};
|
||||
|
||||
const isAppErr = (row: any) => {
|
||||
return row.status.includes('Err') || row.status.includes('Error') || row.status.includes('UnHealthy');
|
||||
};
|
||||
|
||||
const openLog = (row: any) => {
|
||||
switch (row.status) {
|
||||
case 'Installing':
|
||||
|
|
@ -819,28 +494,9 @@ onUnmounted(() => {
|
|||
<style scoped lang="scss">
|
||||
@use '../index';
|
||||
|
||||
.app-error {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.d-name {
|
||||
.el-button + .el-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.d-button {
|
||||
.el-button + .el-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.d-description {
|
||||
.el-button + .el-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.svg-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue