Skip to content
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
4 changes: 2 additions & 2 deletions src/lib/helpers/types/agentTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@
* @property {string} content - Task detail.
* @property {boolean} enabled
* @property {string} status
* @property {Date} created_datetime
* @property {Date} updated_datetime
* @property {Date} created_time
* @property {Date} updated_time
* @property {string} agent_id - Description.
* @property {string} agent_name - Task detail.
* @property {string} [direct_agent_id] - Run task directly in this agent.
Expand Down
1 change: 1 addition & 0 deletions src/lib/services/api-endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const endpoints = {
// agent task
agentTaskListUrl: `${host}/agent/tasks`,
agentTaskDetailUrl: `${host}/agent/{agentId}/task/{taskId}`,
agentTaskUpdateUrl: `${host}/agent/{agentId}/task/{taskId}`,

// agent instruct
instructCompletionUrl: `${host}/instruct/{agentId}`,
Expand Down
14 changes: 14 additions & 0 deletions src/lib/services/task-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,18 @@ export async function getAgentTaskDetail(agentId, taskid) {
const url = replaceUrl(endpoints.agentTaskDetailUrl, { agentId: agentId, taskId: taskid });
var response = await axios.get(url);
return response.data;
}

/**
* Update agent task
* @param {string} agentId
* @param {string} taskId
* @param {import('$agentTypes').AgentTaskModel} task
*/
export async function updateAgentTask(agentId, taskId, task) {
const url = replaceUrl(endpoints.agentTaskUpdateUrl, { agentId: agentId, taskId: taskId });
var response = await axios.put(url, {
...task
});
return response.data;
}
177 changes: 107 additions & 70 deletions src/routes/page/task/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<script>
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n'
import { _ } from 'svelte-i18n';
import Swal from 'sweetalert2';
import 'overlayscrollbars/overlayscrollbars.css';
import { OverlayScrollbars } from 'overlayscrollbars';
import {
Button,
Card,
Expand All @@ -17,15 +20,12 @@
import Breadcrumb from '$lib/common/Breadcrumb.svelte';
import HeadTitle from '$lib/common/HeadTitle.svelte';
import TablePagination from '$lib/common/TablePagination.svelte';
import { getAgentTasks } from '$lib/services/task-service';
import { utcToLocal } from '$lib/helpers/datetime';
import Swal from 'sweetalert2';
import { replaceNewLine } from '$lib/helpers/http';
import 'overlayscrollbars/overlayscrollbars.css';
import { OverlayScrollbars } from 'overlayscrollbars';
import LoadingToComplete from '$lib/common/LoadingToComplete.svelte';
import { getAgentTasks, updateAgentTask } from '$lib/services/task-service';
import { AgentTaskStatus } from '$lib/helpers/enums';
import TaskItem from './task-item.svelte';


let isError = false;
const duration = 3000;
const firstPage = 1;
const pageSize = 10;
Expand All @@ -42,6 +42,10 @@
}
};

let isLoading = false;
let isComplete = false;
let successText = "Update completed!";

/** @type {import('$commonTypes').PagedItems<import('$agentTypes').AgentTaskModel>} */
let tasks = { count: 0, items: [] };

Expand Down Expand Up @@ -123,42 +127,6 @@
refreshPager(tasks.count);
}

/** @param {string} taskId */
function handleTaskDeletion(taskId) {
/*deleteConversation(conversationId).then(async () => {
isLoading = false;
isComplete = true;
setTimeout(() => {
isComplete = false;
}, duration);
await reloadConversations();
}).catch(err => {
isLoading = false;
isComplete = false;
isError = true;
setTimeout(() => {
isError = false;
}, duration);
});*/
}

/** @param {string} taskId */
function openDeleteModal(taskId) {
// @ts-ignore
Swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
customClass: 'custom-modal',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.value) {
handleTaskDeletion(taskId);
}
});
}

/**
* @param {any} e
*/
Expand Down Expand Up @@ -200,10 +168,99 @@
};
}
}

/** @param {any} e */
function onTaskSaved(e) {
const task = e.detail.task;
if (!task) return;

openSaveModal(task);
}

/** @param {import('$agentTypes').AgentTaskModel} task */
function openSaveModal(task) {
// @ts-ignore
Swal.fire({
title: 'Are you sure?',
text: "You can change it back.",
icon: 'warning',
customClass: 'custom-modal',
showCancelButton: true,
confirmButtonText: 'Yes, save it!'
}).then((result) => {
if (result.value) {
handleTaskSave(task);
}
});
}

/** @param {import('$agentTypes').AgentTaskModel} task */
function handleTaskSave(task) {
updateAgentTask(task.agent_id, task.id, task).then(async () => {
isLoading = false;
isComplete = true;
successText = "Update completed!";
setTimeout(() => {
isComplete = false;
successText = '';
}, duration);
}).catch(() => {
isLoading = false;
isComplete = false;
successText = '';
});
}



/** @param {any} e */
function onTaskDeleted(e) {
const task = e.detail.task;
if (!task) return;

openDeleteModal(task.id);
}

/** @param {string} taskId */
function openDeleteModal(taskId) {
// @ts-ignore
Swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
customClass: 'custom-modal',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.value) {
handleTaskDeletion(taskId);
}
});
}

/** @param {string} taskId */
function handleTaskDeletion(taskId) {
/*deleteConversation(conversationId).then(async () => {
isLoading = false;
isComplete = true;
setTimeout(() => {
isComplete = false;
}, duration);
await reloadConversations();
}).catch(err => {
isLoading = false;
isComplete = false;
isError = true;
setTimeout(() => {
isError = false;
}, duration);
});*/
}
</script>

<HeadTitle title="{$_('Task List')}" />
<Breadcrumb title="{$_('Agent')}" pagetitle="{$_('Task')}" />
<LoadingToComplete isLoading={isLoading} isComplete={isComplete} />

<Row>
<Col lg="12">
Expand Down Expand Up @@ -263,39 +320,19 @@
<th scope="col">{$_('Description')}</th>
<th scope="col">{$_('Agent')}</th>
<th scope="col">{$_('Details')}</th>
<th scope="col">{$_('Updated Date')}</th>
<th scope="col">{$_('Updated Time')}</th>
<th scope="col">{$_('Enabled')}</th>
<th scope="col">{$_('Status')}</th>
<th scope="col">{$_('Action')}</th>
</tr>
</thead>
<tbody>
{#each tasks.items as task}
<tr>
<td scope="row">
<a href="page/conversation/{task.id}">{task.name}</a>
</td>
<td>{task.description}</td>
<td>{task.agent_name}</td>
<td><div style="max-height: 100px;" class="scrollbar">{@html replaceNewLine(task.content)}</div></td>
<td>{utcToLocal(task.updated_datetime)}</td>
<td><span class="badge bg-success">{task.enabled ? $_("Enabled") : $_("Disabled")}</span></td>
<td><span class="badge bg-info">{task.status}</span></td>
<td>
<ul class="list-unstyled hstack gap-1 mb-0">
<li data-bs-toggle="tooltip" data-bs-placement="top" title="View">
<a href="page/task/{task.id}?agentId={task.agent_id}" target="_blank" class="btn btn-sm btn-soft-danger">
<i class="mdi mdi-eye-outline" />
</a>
</li>
<li data-bs-toggle="tooltip" data-bs-placement="top" title="Delete">
<Button on:click={() => openDeleteModal(task.id)} class="btn btn-sm btn-soft-danger">
<i class="mdi mdi-delete-outline" />
</Button>
</li>
</ul>
</td>
</tr>
<TaskItem
task={task}
on:save={e => onTaskSaved(e)}
on:delete={e => onTaskDeleted(e)}
/>
{/each}
</tbody>
</Table>
Expand Down
70 changes: 70 additions & 0 deletions src/routes/page/task/task-item.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<script>
import { createEventDispatcher } from 'svelte';
import { _ } from 'svelte-i18n';
import { Button } from "@sveltestrap/sveltestrap";
import { utcToLocal } from "$lib/helpers/datetime";
import { replaceNewLine } from "$lib/helpers/http";

const svelteDispatch = createEventDispatcher();

/** @type {import('$agentTypes').AgentTaskModel} */
export let task;

/** @type {boolean} */
export let disabled = false;

function toggleTask() {
task.enabled = !task.enabled;
}

function handleSaveTask() {
svelteDispatch("save", {
task: task
});
}

function handleDeleteTask() {
svelteDispatch("delete", {
task: task
});
}
</script>

<tr>
<td scope="row" class="text-primary">{task.name}</td>
<td>{task.description}</td>
<td>{task.agent_name}</td>
<td><div style="max-height: 100px;" class="scrollbar">{@html replaceNewLine(task.content)}</div></td>
<td>{utcToLocal(task.updated_time)}</td>
<td>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<span class="clickable" on:click={() => toggleTask()}>
{#if task.enabled}
<span class="badge bg-success">{$_("Enabled")}</span>
{:else}
<span class="badge bg-danger">{$_("Disabled")}</span>
{/if}
</span>
</td>
<td><span class="badge bg-info">{task.status}</span></td>
<td>
<ul class="list-unstyled hstack gap-1 mb-0">
<li data-bs-toggle="tooltip" data-bs-placement="top" title="View">
<a href="page/task/{task.id}?agentId={task.agent_id}" target="_blank" class="btn btn-sm btn-soft-primary">
<i class="mdi mdi-eye-outline" />
</a>
</li>
<li data-bs-toggle="tooltip" data-bs-placement="top" title="Save">
<Button on:click={() => handleSaveTask()} class="btn btn-sm btn-soft-info">
<i class="mdi mdi-content-save-all" />
</Button>
</li>
<li data-bs-toggle="tooltip" data-bs-placement="top" title="Delete">
<Button on:click={() => handleDeleteTask()} class="btn btn-sm btn-soft-danger">
<i class="mdi mdi-delete-outline" />
</Button>
</li>
</ul>
</td>
</tr>