Add luma pagination (#187)

This commit is contained in:
HCode
2025-02-22 14:47:23 +00:00
committed by GitHub
parent f701ae05b1
commit f837700d02
9 changed files with 105 additions and 29 deletions
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "add luma pagination",
"packageName": "@acedatacloud/nexior",
"email": "1348977728@qq.com",
"dependentChangeType": "patch"
}
+12 -2
View File
@@ -1,5 +1,5 @@
<template>
<div class="panel recent">
<div ref="panel" class="panel recent" @scroll="onHandleScroll">
<div v-if="tasks?.items === undefined" class="tasks">
<div v-for="_ in 3" :key="_" class="task placeholder">
<div class="left">
@@ -40,6 +40,7 @@ export default defineComponent({
ElSkeleton,
ElSkeletonItem
},
emits: ['reach-top'],
data() {
return {
job: 0
@@ -50,9 +51,18 @@ export default defineComponent({
// reverse the order of the tasks.items
return {
...this.$store.state.luma?.tasks,
items: this.$store.state.luma?.tasks?.items?.slice().reverse()
items: this.$store.state.luma?.tasks?.items?.slice()
};
}
},
methods: {
onHandleScroll() {
const el = this.$refs.panel as HTMLElement;
console.log('reach-top reach-top reach-top');
if (el.scrollTop === 0) {
this.$emit('reach-top');
}
}
}
});
</script>
+1 -1
View File
@@ -10,7 +10,7 @@
type="textarea"
class="prompt"
:placeholder="$t('luma.placeholder.prompt')"
:maxlength="300"
:maxlength="2000"
show-word-limit
/>
</div>
+6 -9
View File
@@ -14,13 +14,7 @@
<p v-if="modelValue?.request?.prompt" class="prompt mt-2">
{{ modelValue?.request?.prompt }}
<span v-if="!modelValue?.response"> - ({{ $t('luma.status.pending') }}) </span>
<span
v-if="
modelValue?.response?.data?.state === 'processing' ||
modelValue?.response?.data?.state === 'pending' ||
modelValue?.response?.data?.state === 'completed'
"
>
<span v-if="modelValue?.response?.state === 'processing' || modelValue?.response?.state === 'pending'">
- ({{ $t('luma.status.processing') }})
</span>
</p>
@@ -57,7 +51,10 @@
</el-alert>
</div>
<!-- Display error message -->
<div v-if="modelValue?.response?.success === false" :class="{ content: true }">
<div
v-if="modelValue?.response?.state === 'failed' || modelValue?.response?.success === false"
:class="{ content: true }"
>
<el-alert :closable="false" class="failure">
<template #template>
<font-awesome-icon icon="fa-solid fa-exclamation-triangle" class="mr-1" />
@@ -78,7 +75,7 @@
<p class="description">
<font-awesome-icon icon="fa-solid fa-hashtag" class="mr-1" />
{{ $t('luma.name.traceId') }}:
{{ modelValue?.response?.trace_id }}
{{ modelValue?.trace_id }}
<copy-to-clipboard :content="modelValue?.response?.trace_id" class="btn-copy" />
</p>
</el-alert>
+2 -1
View File
@@ -48,7 +48,8 @@ export interface ILumaGenerateResponse {
export interface ILumaTask {
id: string;
created_at?: string;
created_at?: number;
trace_id?: string;
request?: ILumaGenerateRequest;
response?: ILumaGenerateResponse;
}
+19 -1
View File
@@ -23,7 +23,15 @@ class LumaOperator {
}
async tasks(
filter: { ids?: string[]; applicationId?: string; userId?: string; limit?: number; offset?: number },
filter: {
ids?: string[];
applicationId?: string;
userId?: string;
limit?: number;
offset?: number;
createdAtMax?: number;
createdAtMin?: number;
},
options: { token: string }
): Promise<AxiosResponse<ILumaTasksResponse>> {
return await axios.post(
@@ -54,6 +62,16 @@ class LumaOperator {
? {
offset: filter.offset
}
: {}),
...(filter.createdAtMax !== undefined
? {
created_at_max: filter.createdAtMax
}
: {}),
...(filter.createdAtMin !== undefined
? {
created_at_min: filter.createdAtMin
}
: {})
},
{
+38 -10
View File
@@ -14,7 +14,7 @@
@refresh="onGetApplication"
@select="$store.dispatch('luma/setApplication', $event)"
/>
<recent-panel class="panel recent" />
<recent-panel class="panel recent" @reach-top="onReachTop" />
<!-- <operation-panel class="panel operation" @generate="onGenerate" /> -->
</template>
</layout>
@@ -37,6 +37,7 @@ const CALLBACK_URL = 'https://webhook.acedata.cloud/luma';
interface IData {
task: ILumaTask | undefined;
job: number;
timer: NodeJS.Timer;
}
export default defineComponent({
@@ -50,7 +51,9 @@ export default defineComponent({
data(): IData {
return {
task: undefined,
job: 0
job: 0,
// @ts-ignore
timer: undefined
};
},
computed: {
@@ -75,8 +78,20 @@ export default defineComponent({
application() {
return this.$store.state.luma.application;
},
applications() {
return this.$store.state.luma.applications;
tasks() {
return this.$store.state.luma.tasks;
}
},
watch: {
tasks: {
handler(value, oldValue) {
// scroll down if new tasks are added
if (value?.items?.length > oldValue?.items?.length) {
console.debug('new tasks detected');
// this.onScrollDown();
}
},
deep: true
}
},
async mounted() {
@@ -84,7 +99,7 @@ export default defineComponent({
await this.onGetApplication();
await this.onScrollDown();
await this.onGetTasks();
await this.onScrollDown();
// await this.onScrollDown();
// @ts-ignore
this.job = setInterval(() => {
this.onGetTasks();
@@ -92,8 +107,15 @@ export default defineComponent({
},
async unmounted() {
clearInterval(this.job);
clearInterval(this.timer);
},
methods: {
async onReachTop() {
console.debug('reached top');
await this.onGetTasks({
createdAtMax: this.tasks?.items?.[0]?.created_at
});
},
async onGetService() {
console.debug('start onGetService');
await this.$store.dispatch('luma/getService');
@@ -130,14 +152,18 @@ export default defineComponent({
}
}, 500);
},
async onGetTasks() {
async onGetTasks(payload?: { limit?: number; createdAtMin?: number; createdAtMax?: number }) {
if (this.loading) {
console.debug('loading');
return;
}
console.debug('start onGetTasks', payload);
const { limit = 5, createdAtMin, createdAtMax } = payload || {};
console.debug('limit', limit, 'createdAtMin', createdAtMin, 'createdAtMax', createdAtMax);
await this.$store.dispatch('luma/getTasks', {
limit: 30,
offset: 0
limit,
createdAtMin,
createdAtMax
});
},
async onGenerateVideo() {
@@ -170,8 +196,10 @@ export default defineComponent({
}
})
.finally(async () => {
await this.onGetTasks();
await this.onScrollDown();
setTimeout(async () => {
await this.onGetTasks();
await this.onScrollDown();
}, 1000);
});
}
}
+19 -4
View File
@@ -5,6 +5,7 @@ import { IRootState } from '../common/models';
import { IApplication, ICredential, ILumaConfig, ILumaTask, IService, IApplicationType } from '@/models';
import { Status } from '@/models/common';
import { LUMA_SERVICE_ID } from '@/constants';
import { mergeAndSortLists } from '@/utils/merge';
export const resetAll = ({ commit }: ActionContext<ILumaState, IRootState>): void => {
commit('resetAll');
@@ -120,7 +121,12 @@ export const getService = async ({ commit, state }: ActionContext<ILumaState, IR
export const getTasks = async (
{ commit, state, rootState }: ActionContext<ILumaState, IRootState>,
{ offset, limit }: { offset?: number; limit?: number }
{
offset,
limit,
createdAtMin,
createdAtMax
}: { offset?: number; limit?: number; createdAtMin?: number; createdAtMax?: number }
): Promise<ILumaTask[]> => {
return new Promise((resolve, reject) => {
console.debug('start to get tasks', offset, limit);
@@ -132,15 +138,24 @@ export const getTasks = async (
lumaOperator
.tasks(
{
userId: rootState?.user?.id
userId: rootState?.user?.id,
createdAtMin,
createdAtMax
},
{
token
}
)
.then((response) => {
console.debug('get imagine tasks success', response.data.items);
commit('setTasksItems', response.data.items);
console.debug('get luma tasks success', response.data.items);
// merge with existing tasks
const existingItems = state?.tasks?.items || [];
console.debug('existing items', existingItems);
const newItems = response.data.items || [];
console.debug('new items', newItems);
// sort and de-duplicate using created_at
const mergedItems = mergeAndSortLists(existingItems, newItems);
commit('setTasksItems', mergedItems);
commit('setTasksTotal', response.data.count);
resolve(response.data.items);
})
+1 -1
View File
@@ -1 +1 @@
export default ['luma.credential', 'luma.application', 'luma.tasks'];
export default ['luma.credential', 'luma.application'];