Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(task): Add Display for Number of Running Tasks #7564

Merged
merged 1 commit into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions agent/app/api/v2/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,17 @@ func (b *BaseApi) PageTasks(c *gin.Context) {
Total: total,
})
}

// @Tags TaskLog
// @Summary Get the number of executing tasks
// @Success 200 {object} int64
// @Security ApiKeyAuth
// @Router /logs/tasks/executing/count [get]
func (b *BaseApi) CountExecutingTasks(c *gin.Context) {
count, err := taskService.CountExecutingTask()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, count)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There do not seem to be any inconsistencies between the two versions of code you provided. It seems they both serve identical purpose: getting an integer (representing a count). However, these methods don't appear to have been updated with recent changes that might impact their correctness or efficiency. If any specific function's behavior changed or parameters/conditions need modification please specify them so I can offer more tailored feedback.

Additionally, as this answer was written prior to August 2022, it is recommended we consult the most recent documentation from Gitea or GitHub directly when making such decisions. This helps ensure our responses stay relevant and accurate.

7 changes: 7 additions & 0 deletions agent/app/repo/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type ITaskRepo interface {
Page(page, size int, opts ...DBOption) (int64, []model.Task, error)
Update(ctx context.Context, task *model.Task) error
UpdateRunningTaskToFailed() error
CountExecutingTask() (int64, error)

WithByID(id string) DBOption
WithResourceID(id uint) DBOption
Expand Down Expand Up @@ -95,3 +96,9 @@ func (t TaskRepo) Update(ctx context.Context, task *model.Task) error {
func (t TaskRepo) UpdateRunningTaskToFailed() error {
return getTaskDb(commonRepo.WithByStatus(constant.StatusExecuting)).Model(&model.Task{}).Updates(map[string]interface{}{"status": constant.StatusFailed, "error_msg": "1Panel restart causes failure"}).Error
}

func (t TaskRepo) CountExecutingTask() (int64, error) {
var count int64
err := getTaskDb(commonRepo.WithByStatus(constant.StatusExecuting)).Model(&model.Task{}).Count(&count).Error
return count, err
}
5 changes: 5 additions & 0 deletions agent/app/service/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type TaskLogService struct{}
type ITaskLogService interface {
Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, error)
SyncForRestart() error
CountExecutingTask() (int64, error)
}

func NewITaskService() ITaskLogService {
Expand Down Expand Up @@ -45,3 +46,7 @@ func (u *TaskLogService) Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, e
func (u *TaskLogService) SyncForRestart() error {
return taskRepo.UpdateRunningTaskToFailed()
}

func (u *TaskLogService) CountExecutingTask() (int64, error) {
return taskRepo.CountExecutingTask()
}
1 change: 1 addition & 0 deletions agent/router/ro_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ func (s *LogRouter) InitRouter(Router *gin.RouterGroup) {
operationRouter.GET("/system/files", baseApi.GetSystemFiles)
operationRouter.POST("/system", baseApi.GetSystemLogs)
operationRouter.POST("/tasks/search", baseApi.PageTasks)
operationRouter.GET("/tasks/executing/count", baseApi.CountExecutingTasks)
}
}
4 changes: 4 additions & 0 deletions frontend/src/api/modules/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ export const cleanLogs = (param: Log.CleanLog) => {
export const searchTasks = (req: Log.SearchTaskReq) => {
return http.post<ResPage<Log.Task>>(`/logs/tasks/search`, req);
};

export const countExecutingTask = () => {
return http.get<number>(`/tasks/executing/count`);
};
18 changes: 17 additions & 1 deletion frontend/src/components/status/index.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<el-tooltip v-if="msg" effect="dark" placement="bottom">
<template #content>
<div style="width: 300px; word-break: break-all">{{ msg }}</div>
<div class="content">{{ msg }}</div>
</template>
<el-tag size="small" :type="getType(statusItem)" round effect="light">
<span class="flx-align-center">
Expand All @@ -19,6 +19,10 @@
<el-icon v-if="loadingIcon(statusItem)" class="is-loading">
<Loading />
</el-icon>
<el-icon size="15" v-if="operate">
<CaretRight v-if="statusItem == 'running'" />
<CaretBottom v-if="statusItem == 'stopped'" />
</el-icon>
</span>
</el-tag>
</template>
Expand All @@ -29,6 +33,11 @@ import { computed } from 'vue';
const props = defineProps({
status: String,
msg: String,
operate: {
type: Boolean,
default: false,
required: false,
},
});

const statusItem = computed(() => {
Expand Down Expand Up @@ -88,3 +97,10 @@ const loadingIcon = (status: string): boolean => {
return loadingStatus.indexOf(status) > -1;
};
</script>

<style lang="scss" scoped>
.content {
width: 300px;
word-break: break-all;
}
</style>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of the knowledge cutoff provided (September 1, 2021), there are no known issues with the above template snippet or any JavaScript components used in it.

Based on current information:

  • The code is well-formed and seems to utilize the React DOM (<template> elements) correctly without errors.

This version includes an updated CSS @import rule for SASS styles which can be found within a <style> element marked as "scoped," which indicates its intended use is internal styling.

It uses ES6 arrow functions and typescript syntax but does not include TypeScript compiler warnings since this context doesn't support the latest TypeScript features like async/await.

In terms of performance and compatibility issues, I did not encounter such concerns when looking at these changes.

However, if you have specific questions about how Vue.js renders HTML content, or related optimizations, please specify.

2 changes: 0 additions & 2 deletions frontend/src/components/svg-icon/svg-icon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ const props = defineProps({
default: '#005eeb',
},
});
// 图标在 iconfont 中的名字
const iconClassName = computed(() => {
return `#${props.iconName}`;
});
// 给图标添加上类名
const svgClass = computed(() => {
if (props.className) {
return `svg-icon ${props.className}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ defineProps<{ menuList: RouteRecordRaw[] }>();
</script>

<style scoped lang="scss">
@import '../index.scss';
@use '../index.scss';
</style>
1 change: 1 addition & 0 deletions frontend/src/layout/components/Sidebar/index.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@use '@/styles/var.scss' as *;
.el-menu {
user-select: none;
background: none;
Expand Down
83 changes: 53 additions & 30 deletions frontend/src/layout/components/Sidebar/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,37 @@
element-loading-background="rgba(122, 122, 122, 0.01)"
>
<Logo :isCollapse="isCollapse" />

<span v-if="nodes.length !== 0" class="el-dropdown-link">
{{ loadCurrentName() }}
</span>
<el-dropdown v-if="nodes.length !== 0" placement="right-start" @command="changeNode">
<el-icon class="ico"><Switch /></el-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="local">
{{ $t('terminal.local') }}
</el-dropdown-item>
<el-dropdown-item v-for="item in nodes" :key="item.name" :command="item.name">
{{ item.name }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>

<div class="el-dropdown-link flex justify-between items-center">
<el-button type="text" @click="openChangeNode" @mouseenter="openChangeNode">
<span>
{{ loadCurrentName() }}
</span>
</el-button>
<div>
<el-dropdown
ref="nodeChangeRef"
trigger="contextmenu"
v-if="nodes.length > 0"
placement="right-start"
@command="changeNode"
>
<span></span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="local">
<SvgIcon class="ico" iconName="p-host" />
{{ $t('terminal.local') }}
</el-dropdown-item>
<el-dropdown-item v-for="item in nodes" :key="item.name" :command="item.name">
<SvgIcon class="ico" iconName="p-host" />
{{ item.name }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<el-tag type="danger" size="small" effect="light" class="mr-2">{{ taskCount }}</el-tag>
</div>
<el-scrollbar>
<el-menu
:default-active="activeMenu"
Expand Down Expand Up @@ -59,16 +72,18 @@ import SubItem from './components/SubItem.vue';
import router, { menuList } from '@/routers/router';
import { logOutApi } from '@/api/modules/auth';
import i18n from '@/lang';
import { ElMessageBox } from 'element-plus';
import { DropdownInstance, ElMessageBox } from 'element-plus';
import { GlobalStore, MenuStore } from '@/store';
import { MsgSuccess } from '@/utils/message';
import { isString } from '@vueuse/core';
import { getSettingInfo, listNodeOptions } from '@/api/modules/setting';
import { countExecutingTask } from '@/api/modules/log';

const route = useRoute();
const menuStore = MenuStore();
const globalStore = GlobalStore();
const nodes = ref([]);
const nodeChangeRef = ref<DropdownInstance>();
defineProps({
menuRouter: {
type: Boolean,
Expand All @@ -86,6 +101,10 @@ let routerMenus = computed((): RouteRecordRaw[] => {
return menuStore.menuList.filter((route) => route.meta && !route.meta.hideInSidebar);
});

const openChangeNode = () => {
nodeChangeRef.value?.handleOpen();
};

const loadCurrentName = () => {
if (globalStore.currentNode) {
return globalStore.currentNode === 'local' ? i18n.global.t('terminal.local') : globalStore.currentNode;
Expand Down Expand Up @@ -223,15 +242,26 @@ const search = async () => {
menuStore.menuList = rstMenuList;
};

const taskCount = ref(0);
const checkTask = async () => {
try {
const res = await countExecutingTask();
taskCount.value = res.data;
} catch (error) {
console.error(error);
}
};

onMounted(() => {
menuStore.setMenuList(menuList);
search();
loadNodes();
checkTask();
});
</script>

<style lang="scss">
@import './index.scss';
@use './index.scss';

.sidebar-container {
position: relative;
Expand All @@ -252,20 +282,13 @@ onMounted(() => {

.el-dropdown-link {
margin-top: -5px;
margin-left: 30px;
margin-left: 15px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
color: var(--el-color-primary);
display: flex;
align-items: center;
height: 28px;
height: 38px;
}
.ico {
margin-top: -20px;
display: flex;
float: left;
position: absolute;
right: 25px;
height: 20px !important;
}
</style>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed solution includes:

  1. Style Sheet - The index.scss file should be adjusted to maintain the current styling structure without major changes.

  2. Data References -
    a) Fix issues with using global store ($route) where needed to avoid dependency hell.
    b) Correctly implement taskCount: Use $refs.taskCount instead of just taskCount.

  3. Event Handling

    • Move event handling logic like openChangeNode() within the corresponding vue components rather than importing and reassigning functions outside component's render lifecycle.
  4. Global Function Declaration

    • Remove global function declarations (getSettingInfo and countExecutingTask). Instead, make them local variables which can either pass through props or return their results inside the methods.
  5. Async Await

    • In some places (like search, use ES6 template literals for dynamic strings.
    • Ensure that all asynchronous operations (listNodeOptions()“ and checkTask()` have been fully wrapped under async/await expressions ensuring proper cleanup & better readability.

Overall, this is an efficient codebase with good practices followed throughout.

It appears there is no need for further technical debugging due to the clean separation between concerns as per best software engineering principles: Components manage data / interaction directly while routers handle navigation/middleware/data fetching etc. This makes the app easier to reason about and scale over time. However, you may still want to consider adding lint checks or unit tests depending on what specifically needs to be verified across various scenarios. For example,

componentTest(testCases)

for verifying certain conditions when testing the entire component.

I don't think there are any known bugs based on inspection alone, so I recommend running some tests at least once or twice to ensure that the final product behaves correctly given the current state of the codebase.

2 changes: 1 addition & 1 deletion frontend/src/views/app-store/installed/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ onUnmounted(() => {
</script>

<style scoped lang="scss">
@import '../index.scss';
@use '../index.scss';
@media only screen and (max-width: 1300px) {
.install-card-col-12 {
max-width: 100%;
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/views/website/website/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@
<template #default="{ row }">
<Status
v-if="row.status === 'Running'"
:operate="true"
:status="row.status"
@click="opWebsite('stop', row.id)"
/>
<Status v-else :status="row.status" @click="opWebsite('start', row.id)" />
<Status v-else :status="row.status" :operate="true" @click="opWebsite('start', row.id)" />
</template>
</el-table-column>
<el-table-column
Expand Down
Loading