mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-11-09 19:20:56 +08:00
fix(website): Add pinning feature for websites. (#8462)
This commit is contained in:
parent
86cef9803c
commit
9d48e591af
16 changed files with 131 additions and 35 deletions
|
|
@ -7,7 +7,7 @@ import (
|
|||
type WebsiteSearch struct {
|
||||
dto.PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=primary_domain type status createdAt expire_date created_at"`
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=primary_domain type status createdAt expire_date created_at favorite"`
|
||||
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
||||
WebsiteGroupID uint `json:"websiteGroupId"`
|
||||
Type string `json:"type"`
|
||||
|
|
@ -85,6 +85,7 @@ type WebsiteUpdate struct {
|
|||
WebsiteGroupID uint `json:"webSiteGroupID"`
|
||||
ExpireDate string `json:"expireDate"`
|
||||
IPV6 bool `json:"IPV6"`
|
||||
Favorite bool `json:"favorite"`
|
||||
}
|
||||
|
||||
type WebsiteDelete struct {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ type WebsiteRes struct {
|
|||
AppInstallID uint `json:"appInstallId"`
|
||||
ChildSites []string `json:"childSites"`
|
||||
RuntimeType string `json:"runtimeType"`
|
||||
Favorite bool `json:"favorite"`
|
||||
}
|
||||
|
||||
type WebsiteOption struct {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ type Website struct {
|
|||
DbType string `json:"dbType"`
|
||||
DbID uint `json:"dbID"`
|
||||
|
||||
Favorite bool `json:"favorite"`
|
||||
|
||||
Domains []WebsiteDomain `json:"domains" gorm:"-:migration"`
|
||||
WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ func (w WebsiteService) PageWebsite(req request.WebsiteSearch) (int64, []respons
|
|||
SitePath: sitePath,
|
||||
AppInstallID: appInstallID,
|
||||
RuntimeType: runtimeType,
|
||||
Favorite: web.Favorite,
|
||||
}
|
||||
|
||||
sites, _ := websiteRepo.List(websiteRepo.WithParentID(web.ID))
|
||||
|
|
@ -529,6 +530,7 @@ func (w WebsiteService) UpdateWebsite(req request.WebsiteUpdate) error {
|
|||
website.WebsiteGroupID = req.WebsiteGroupID
|
||||
website.Remark = req.Remark
|
||||
website.IPV6 = req.IPV6
|
||||
website.Favorite = req.Favorite
|
||||
|
||||
if req.ExpireDate != "" {
|
||||
expireDate, err := time.Parse(constant.DateLayout, req.ExpireDate)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ func InitAgentDB() {
|
|||
migrations.AddLocalSSHSetting,
|
||||
migrations.AddAppIgnore,
|
||||
migrations.UpdateWebsiteSSL,
|
||||
migrations.UpdateWebsite,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
|
|
|||
|
|
@ -342,3 +342,13 @@ var UpdateWebsiteSSL = &gormigrate.Migration{
|
|||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var UpdateWebsite = &gormigrate.Migration{
|
||||
ID: "20250424-update-website",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.Website{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ export namespace Website {
|
|||
childSites?: string[];
|
||||
dbID: number;
|
||||
dbType: string;
|
||||
favorite: boolean;
|
||||
}
|
||||
|
||||
export interface WebsiteDTO extends Website {
|
||||
|
|
@ -100,6 +101,7 @@ export namespace Website {
|
|||
webSiteGroupId: number;
|
||||
expireDate?: string;
|
||||
IPV6: boolean;
|
||||
favorite: boolean;
|
||||
}
|
||||
|
||||
export interface WebSiteOp {
|
||||
|
|
|
|||
|
|
@ -2420,6 +2420,8 @@ const message = {
|
|||
cacheWarn: 'Please turn off the cache switch in the reverse proxy first',
|
||||
loadBalanceHelper:
|
||||
'This section only creates load balancing rules, to use the rules please reverse proxy http(s)://<load balance name>',
|
||||
favorite: 'Favorite',
|
||||
cancelFavorite: 'Cancel Favorite',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Short tag support',
|
||||
|
|
|
|||
|
|
@ -2327,6 +2327,8 @@ const message = {
|
|||
cacheWarn: 'まずリバースプロキシのキャッシュスイッチをオフにしてください',
|
||||
loadBalanceHelper:
|
||||
'This section only creates load balancing rules, to use the rules please reverse proxy http(s)://<load balance name>',
|
||||
favorite: 'お気に入り',
|
||||
cancelFavorite: 'お気に入りを解除',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短いタグサポート',
|
||||
|
|
|
|||
|
|
@ -2288,6 +2288,8 @@ const message = {
|
|||
cacheWarn: '먼저 리버스 프록시의 캐시 스위치를 끄십시오',
|
||||
loadBalanceHelper:
|
||||
'여기서는 로드 밸런싱 규칙만 생성합니다. 규칙을 사용하려면 리버스 프록시 http(s)://<로드 밸런스 이름>을 사용하십시오',
|
||||
favorite: '즐겨찾기',
|
||||
cancelFavorite: '즐겨찾기 취소',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '짧은 태그 지원',
|
||||
|
|
|
|||
|
|
@ -2381,6 +2381,8 @@ const message = {
|
|||
cacheWarn: 'Sila matikan suis cache dalam pembalikan proksi terlebih dahulu',
|
||||
loadBalanceHelper:
|
||||
'Di sini hanya mencipta peraturan keseimbangan beban, untuk menggunakan peraturan sila proksi terbalik http(s)://<nama keseimbangan beban>',
|
||||
favorite: 'Kegemaran',
|
||||
cancelFavorite: 'Batalkan Kegemaran',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Sokongan tag pendek',
|
||||
|
|
|
|||
|
|
@ -2377,6 +2377,8 @@ const message = {
|
|||
cacheWarn: 'Por favor, desligue o interruptor de cache no proxy reverso primeiro',
|
||||
loadBalanceHelper:
|
||||
'Esta seção apenas cria regras de balanceamento de carga, para usar as regras, por favor, proxy reverso http(s)://<nome do balanceamento de carga>',
|
||||
favorite: 'Favorito',
|
||||
cancelFavorite: 'Cancelar Favorito',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Suporte para short tags',
|
||||
|
|
|
|||
|
|
@ -2378,6 +2378,8 @@ const message = {
|
|||
cacheWarn: 'Пожалуйста, сначала выключите кэш в обратном прокси',
|
||||
loadBalanceHelper:
|
||||
'Здесь создаются только правила балансировки нагрузки, чтобы использовать правила, пожалуйста, используйте обратный прокси http(s)://<имя балансировки нагрузки>',
|
||||
favorite: 'Избранное',
|
||||
cancelFavorite: 'Отменить избранное',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Поддержка коротких тегов',
|
||||
|
|
|
|||
|
|
@ -2245,6 +2245,8 @@ const message = {
|
|||
runtimePortWarn: '當前運行環境沒有端口,無法代理',
|
||||
cacheWarn: '請先關閉反代中的緩存開關',
|
||||
loadBalanceHelper: '此處只是創建負載均衡規則,使用規則請反向代理 http(s)://<負載均衡名稱>',
|
||||
favorite: '收藏',
|
||||
cancelFavorite: '取消收藏',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短標簽支持',
|
||||
|
|
|
|||
|
|
@ -2235,6 +2235,8 @@ const message = {
|
|||
runtimePortWarn: '当前运行环境没有端口,无法代理',
|
||||
cacheWarn: '请先关闭反代中的缓存开关',
|
||||
loadBalanceHelper: '此处只是创建负载均衡规则,使用规则请反向代理 http://<负载均衡名称>',
|
||||
favorite: '收藏',
|
||||
cancelFavorite: '取消收藏',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短标签支持',
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@
|
|||
sortable
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="name-row" @mouseenter="showFavorite($index)" @mouseleave="hideFavorite">
|
||||
<div>
|
||||
<el-text type="primary" class="cursor-pointer" @click="openConfig(row.id)">
|
||||
{{ row.primaryDomain }}
|
||||
</el-text>
|
||||
|
|
@ -107,7 +109,11 @@
|
|||
<tbody>
|
||||
<tr v-for="(domain, index) in domains" :key="index">
|
||||
<td>
|
||||
<el-button type="primary" link @click="openUrl(getUrl(domain, row))">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="openUrl(getUrl(domain, row))"
|
||||
>
|
||||
{{ getUrl(domain, row) }}
|
||||
</el-button>
|
||||
</td>
|
||||
|
|
@ -118,6 +124,37 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('website.cancelFavorite')"
|
||||
placement="top-start"
|
||||
v-if="row.favorite"
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
icon="Star"
|
||||
type="warning"
|
||||
@click="favoriteWebsite(row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('website.favorite')"
|
||||
placement="top-start"
|
||||
v-if="!row.favorite && hoveredRowIndex === $index"
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
icon="Star"
|
||||
type="info"
|
||||
@click="favoriteWebsite(row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
|
|
@ -222,8 +259,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<fu-table-operations
|
||||
:ellipsis="10"
|
||||
width="300px"
|
||||
:ellipsis="1"
|
||||
width="150px"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
:fixed="mobile ? false : 'right'"
|
||||
|
|
@ -314,6 +351,7 @@ let groups = ref<Group.GroupInfo[]>([]);
|
|||
const dataRef = ref();
|
||||
const domains = ref<Website.Domain[]>([]);
|
||||
const columns = ref([]);
|
||||
const hoveredRowIndex = ref(-1);
|
||||
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'website-page-size',
|
||||
|
|
@ -325,8 +363,8 @@ let req = reactive({
|
|||
name: '',
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
orderBy: 'createdAt',
|
||||
order: 'null',
|
||||
orderBy: 'favorite',
|
||||
order: 'descending',
|
||||
websiteGroupId: 0,
|
||||
type: '',
|
||||
});
|
||||
|
|
@ -338,6 +376,19 @@ const goRouter = async (key: string) => {
|
|||
router.push({ name: 'AppAll', query: { install: key } });
|
||||
};
|
||||
|
||||
const showFavorite = (index: any) => {
|
||||
hoveredRowIndex.value = index;
|
||||
};
|
||||
|
||||
const hideFavorite = () => {
|
||||
hoveredRowIndex.value = -1;
|
||||
};
|
||||
|
||||
const favoriteWebsite = (row: Website.Website) => {
|
||||
row.favorite = !row.favorite;
|
||||
updateWebsitConfig(row);
|
||||
};
|
||||
|
||||
const changeSort = ({ prop, order }) => {
|
||||
if (order) {
|
||||
switch (prop) {
|
||||
|
|
@ -353,8 +404,8 @@ const changeSort = ({ prop, order }) => {
|
|||
req.orderBy = prop;
|
||||
req.order = order;
|
||||
} else {
|
||||
req.orderBy = 'created_at';
|
||||
req.order = 'null';
|
||||
req.orderBy = 'favorite';
|
||||
req.order = 'descending';
|
||||
}
|
||||
search();
|
||||
};
|
||||
|
|
@ -460,6 +511,7 @@ const updateWebsitConfig = (row: any) => {
|
|||
webSiteGroupId: row.webSiteGroupId,
|
||||
expireDate: reqDate,
|
||||
IPV6: row.IPV6,
|
||||
favorite: row.favorite,
|
||||
};
|
||||
|
||||
updateWebsite(req).then(() => {
|
||||
|
|
@ -588,3 +640,12 @@ onMounted(() => {
|
|||
listGroup();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue