mirror of https://github.com/1Panel-dev/1Panel
feat: 应用商店分类增加排序 (#2455)
parent
9d0eca723c
commit
154ea0b4ce
|
@ -98,6 +98,7 @@ type AppConfigVersion struct {
|
|||
type Tag struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
type AppForm struct {
|
||||
|
|
|
@ -4,4 +4,5 @@ type Tag struct {
|
|||
BaseModel
|
||||
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||
Sort int `json:"sort" gorm:"type:int;not null;default:1"`
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func (t TagRepo) DeleteAll(ctx context.Context) error {
|
|||
|
||||
func (t TagRepo) All() ([]model.Tag, error) {
|
||||
var tags []model.Tag
|
||||
if err := getDb().Where("1 = 1 ").Find(&tags).Error; err != nil {
|
||||
if err := getDb().Where("1 = 1 ").Order("sort asc").Find(&tags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tags, nil
|
||||
|
|
|
@ -774,6 +774,7 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
|||
tags = append(tags, &model.Tag{
|
||||
Key: t.Key,
|
||||
Name: t.Name,
|
||||
Sort: t.Sort,
|
||||
})
|
||||
}
|
||||
oldApps, err := appRepo.GetBy(appRepo.WithResource(constant.AppResourceRemote))
|
||||
|
|
|
@ -46,6 +46,7 @@ func Init() {
|
|||
|
||||
migrations.AddDefaultNetwork,
|
||||
migrations.UpdateRuntime,
|
||||
migrations.UpdateTag,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
|
|
@ -34,3 +34,13 @@ var UpdateRuntime = &gormigrate.Migration{
|
|||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var UpdateTag = &gormigrate.Migration{
|
||||
ID: "20231008-update-tag",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.Tag{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ export namespace App {
|
|||
export interface Tag {
|
||||
key: string;
|
||||
name: string;
|
||||
sort: number;
|
||||
}
|
||||
|
||||
export interface AppResPage {
|
||||
|
|
|
@ -82,3 +82,7 @@
|
|||
.el-sub-menu__title {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.p-mr-5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
>
|
||||
{{ $t('app.all') }}
|
||||
</el-button>
|
||||
<div v-for="item in tags" :key="item.key" style="display: inline">
|
||||
<div v-for="item in tags.slice(0, 6)" :key="item.key" class="inline">
|
||||
<el-button
|
||||
class="tag-button"
|
||||
:class="activeTag === item.key ? '' : 'no-active'"
|
||||
|
@ -23,6 +23,31 @@
|
|||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="inline">
|
||||
<el-dropdown>
|
||||
<el-button
|
||||
class="tag-button"
|
||||
:type="moreTag !== '' ? 'primary' : ''"
|
||||
:class="moreTag !== '' ? '' : 'no-active'"
|
||||
>
|
||||
{{ moreTag == '' ? $t('tabs.more') : getTagValue(moreTag) }}
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in tags.slice(6)"
|
||||
@click="changeTag(item.key)"
|
||||
:key="item.key"
|
||||
>
|
||||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
|
||||
<div class="search-button">
|
||||
|
@ -103,12 +128,12 @@
|
|||
</span>
|
||||
</div>
|
||||
<div class="app-tag">
|
||||
<el-tag v-for="(tag, ind) in app.tags" :key="ind" style="margin-right: 5px">
|
||||
<span :style="{ color: getColor(ind) }">
|
||||
<el-tag v-for="(tag, ind) in app.tags" :key="ind" class="p-mr-5">
|
||||
<span>
|
||||
{{ language == 'zh' || language == 'tw' ? tag.name : tag.key }}
|
||||
</span>
|
||||
</el-tag>
|
||||
<el-tag v-if="app.status === 'TakeDown'" style="margin-right: 5px">
|
||||
<el-tag v-if="app.status === 'TakeDown'" class="p-mr-5">
|
||||
<span style="color: red">{{ $t('app.takeDown') }}</span>
|
||||
</el-tag>
|
||||
</div>
|
||||
|
@ -170,7 +195,6 @@ const req = reactive({
|
|||
|
||||
const apps = ref<App.AppDTO[]>([]);
|
||||
const tags = ref<App.Tag[]>([]);
|
||||
const colorArr = ['#005eeb', '#008B45', '#BEBEBE', '#FFF68F', '#FFFF00', '#8B0000'];
|
||||
const loading = ref(false);
|
||||
const activeTag = ref('all');
|
||||
const showDetail = ref(false);
|
||||
|
@ -179,10 +203,7 @@ const syncing = ref(false);
|
|||
const detailRef = ref();
|
||||
const installRef = ref();
|
||||
const installKey = ref('');
|
||||
|
||||
const getColor = (index: number) => {
|
||||
return colorArr[index];
|
||||
};
|
||||
const moreTag = ref('');
|
||||
|
||||
const search = async (req: App.AppReq) => {
|
||||
loading.value = true;
|
||||
|
@ -244,9 +265,22 @@ const changeTag = (key: string) => {
|
|||
if (key !== 'all') {
|
||||
req.tags = [key];
|
||||
}
|
||||
const index = tags.value.findIndex((tag) => tag.key === key);
|
||||
if (index > 5) {
|
||||
moreTag.value = key;
|
||||
} else {
|
||||
moreTag.value = '';
|
||||
}
|
||||
search(req);
|
||||
};
|
||||
|
||||
const getTagValue = (key: string) => {
|
||||
const tag = tags.value.find((tag) => tag.key === key);
|
||||
if (tag) {
|
||||
return language == 'zh' || language == 'tw' ? tag.name : tag.key;
|
||||
}
|
||||
};
|
||||
|
||||
const searchByName = (name: string) => {
|
||||
req.name = name;
|
||||
search(req);
|
||||
|
@ -345,6 +379,7 @@ onMounted(() => {
|
|||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) and (max-width: 1200px) {
|
||||
.app-col-12 {
|
||||
max-width: 50%;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
>
|
||||
{{ $t('app.all') }}
|
||||
</el-button>
|
||||
<div v-for="item in tags" :key="item.key" class="inline">
|
||||
<div v-for="item in tags.slice(0, 6)" :key="item.key" class="inline">
|
||||
<el-button
|
||||
class="tag-button"
|
||||
:class="activeTag === item.key ? '' : 'no-active'"
|
||||
|
@ -24,8 +24,34 @@
|
|||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="inline">
|
||||
<el-dropdown>
|
||||
<el-button
|
||||
class="tag-button"
|
||||
:type="moreTag !== '' ? 'primary' : ''"
|
||||
:class="moreTag !== '' ? '' : 'no-active'"
|
||||
>
|
||||
{{ moreTag == '' ? $t('tabs.more') : getTagValue(moreTag) }}
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in tags.slice(6)"
|
||||
@click="changeTag(item.key)"
|
||||
:key="item.key"
|
||||
>
|
||||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
|
||||
<div class="search-button">
|
||||
<el-input
|
||||
|
@ -341,7 +367,7 @@ const searchReq = reactive({
|
|||
const router = useRouter();
|
||||
const activeName = ref(i18n.global.t('app.installed'));
|
||||
const mode = ref('installed');
|
||||
|
||||
const moreTag = ref('');
|
||||
const language = useI18n().locale.value;
|
||||
|
||||
const sync = () => {
|
||||
|
@ -362,9 +388,22 @@ const changeTag = (key: string) => {
|
|||
if (key !== 'all') {
|
||||
searchReq.tags = [key];
|
||||
}
|
||||
const index = tags.value.findIndex((tag) => tag.key === key);
|
||||
if (index > 5) {
|
||||
moreTag.value = key;
|
||||
} else {
|
||||
moreTag.value = '';
|
||||
}
|
||||
search();
|
||||
};
|
||||
|
||||
const getTagValue = (key: string) => {
|
||||
const tag = tags.value.find((tag) => tag.key === key);
|
||||
if (tag) {
|
||||
return language == 'zh' || language == 'tw' ? tag.name : tag.key;
|
||||
}
|
||||
};
|
||||
|
||||
const search = () => {
|
||||
loading.value = true;
|
||||
searchReq.page = paginationConfig.currentPage;
|
||||
|
|
Loading…
Reference in New Issue