mirror of
https://github.com/khoj-ai/khoj.git
synced 2025-02-17 08:04:21 +00:00
Set subject dynamically when creating new tasks, and make some minor improvments to the automations UI
This commit is contained in:
parent
d1b2037676
commit
c30ba2e551
2 changed files with 62 additions and 32 deletions
|
@ -5,12 +5,11 @@
|
|||
<h2 class="section-title">
|
||||
<img class="card-icon" src="/static/assets/icons/automation.svg?v={{ khoj_version }}" alt="Automate">
|
||||
<span class="card-title-text">Automate</span>
|
||||
<div class="instructions">
|
||||
<!-- <div class="instructions">
|
||||
<a href="https://docs.khoj.dev/features/automations">ⓘ Help</a>
|
||||
</div>
|
||||
</div> -->
|
||||
</h2>
|
||||
<div class="section-body">
|
||||
<h4>Automations</h4>
|
||||
<button id="create-automation-button" type="button" class="positive-button">
|
||||
<img class="automation-action-icon" src="/static/assets/icons/new.svg" alt="Automations">
|
||||
<span id="create-automation-button-text">Create</span>
|
||||
|
@ -34,6 +33,7 @@
|
|||
}
|
||||
div#automations {
|
||||
margin-bottom: 12px;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
button.negative-button {
|
||||
background-color: gainsboro;
|
||||
|
@ -44,6 +44,35 @@
|
|||
.positive-button:hover {
|
||||
background-color: var(--summer-sun);
|
||||
}
|
||||
|
||||
div.automation-buttons {
|
||||
display: grid;
|
||||
grid-gap: 8px;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
}
|
||||
|
||||
button.save-automation-button {
|
||||
background-color: var(--summer-sun);
|
||||
}
|
||||
|
||||
button.save-automation-button:hover {
|
||||
background-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
div.new-automation {
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 6px 0 hsla(0, 0%, 0%, 0.2);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
transition: box-shadow 0.3s ease, transform 0.3s ease;
|
||||
}
|
||||
|
||||
div.new-automation:hover {
|
||||
box-shadow: 0 10px 15px 0 hsla(0, 0%, 0%, 0.1);
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
function deleteAutomation(automationId) {
|
||||
|
@ -84,13 +113,12 @@
|
|||
let automationEl = document.createElement("div");
|
||||
automationEl.innerHTML = `
|
||||
<div class="card automation" id="automation-card-${automationId}">
|
||||
<label for="subject">Subject</label>
|
||||
<input type="text"
|
||||
id="automation-subject-${automationId}"
|
||||
name="subject"
|
||||
data-original="${automation.subject}"
|
||||
value="${automation.subject}">
|
||||
<label for="query-to-run">Query to Run</label>
|
||||
<label for="query-to-run">Your automation</label>
|
||||
<textarea id="automation-queryToRun-${automationId}"
|
||||
data-original="${automation.query_to_run}"
|
||||
name="query-to-run">${automation.query_to_run}</textarea>
|
||||
|
@ -102,12 +130,14 @@
|
|||
data-original="${automation.schedule}"
|
||||
title="${automationNextRun}"
|
||||
value="${automation.schedule}">
|
||||
<button type="button"
|
||||
class="save-automation-button positive-button"
|
||||
id="save-automation-button-${automationId}">Save</button>
|
||||
<button type="button"
|
||||
class="delete-automation-button negative-button"
|
||||
id="delete-automation-button-${automationId}">Delete</button>
|
||||
<div class="automation-buttons">
|
||||
<button type="button"
|
||||
class="delete-automation-button negative-button"
|
||||
id="delete-automation-button-${automationId}">Delete</button>
|
||||
<button type="button"
|
||||
class="save-automation-button positive-button"
|
||||
id="save-automation-button-${automationId}">Save</button>
|
||||
</div>
|
||||
<div id="automation-success-${automationId}" style="display: none;"></div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -155,14 +185,13 @@
|
|||
}
|
||||
|
||||
async function saveAutomation(automationId, create=false) {
|
||||
const subject = encodeURIComponent(document.getElementById(`automation-subject-${automationId}`).value);
|
||||
const queryToRun = encodeURIComponent(document.getElementById(`automation-queryToRun-${automationId}`).value);
|
||||
const scheduleEl = document.getElementById(`automation-schedule-${automationId}`);
|
||||
const notificationEl = document.getElementById(`automation-success-${automationId}`);
|
||||
const saveButtonEl = document.getElementById(`save-automation-button-${automationId}`);
|
||||
const actOn = create ? "Create" : "Save";
|
||||
|
||||
if (subject === "" || queryToRun == "" || scheduleEl.value == "") {
|
||||
if (queryToRun == "" || scheduleEl.value == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -186,10 +215,13 @@
|
|||
const encodedCrontime = encodeURIComponent(crontime);
|
||||
|
||||
// Construct query string and select method for API call
|
||||
let query_string = `q=${queryToRun}&subject=${subject}&crontime=${encodedCrontime}&city=${ip_data.city}®ion=${ip_data.region}&country=${ip_data.country_name}&timezone=${ip_data.timezone}`;
|
||||
let query_string = `q=${queryToRun}&crontime=${encodedCrontime}&city=${ip_data.city}®ion=${ip_data.region}&country=${ip_data.country_name}&timezone=${ip_data.timezone}`;
|
||||
|
||||
let method = "POST";
|
||||
if (!create) {
|
||||
const subject = encodeURIComponent(document.getElementById(`automation-subject-${automationId}`).value);
|
||||
query_string += `&automation_id=${automationId}`;
|
||||
query_string += `&subject=${subject}`;
|
||||
method = "PUT"
|
||||
}
|
||||
|
||||
|
@ -231,29 +263,27 @@
|
|||
var automationEl = document.createElement("div");
|
||||
automationEl.classList.add("card");
|
||||
automationEl.classList.add("automation");
|
||||
automationEl.classList.add("new-automation")
|
||||
const placeholderId = Date.now();
|
||||
automationEl.id = "automation-card-" + placeholderId;
|
||||
automationEl.innerHTML = `
|
||||
<label for="subject">Subject</label>
|
||||
<input type="text"
|
||||
id="automation-subject-${placeholderId}"
|
||||
name="subject"
|
||||
placeholder="My Personal Newsletter">
|
||||
<label for="query-to-run">Query to Run</label>
|
||||
<label for="query-to-run">Your new automation</label>
|
||||
<textarea id="automation-queryToRun-${placeholderId}" placeholder="Share a Newsletter including: 1. Weather forecast for this Week. 2. A Book Highlight from my Notes. 3. Recap News from Last Week"></textarea>
|
||||
<label for="schedule">Schedule</label>
|
||||
<input type="text"
|
||||
id="automation-schedule-${placeholderId}"
|
||||
name="schedule"
|
||||
placeholder="9AM every morning">
|
||||
<button type="button"
|
||||
class="save-automation-button"
|
||||
onclick="saveAutomation(${placeholderId}, true)"
|
||||
id="save-automation-button-${placeholderId}">Create</button>
|
||||
<button type="button"
|
||||
class="delete-automation-button"
|
||||
onclick="deleteAutomation(${placeholderId}, true)"
|
||||
id="delete-automation-button-${placeholderId}">Delete</button>
|
||||
<div class="automation-buttons">
|
||||
<button type="button"
|
||||
class="delete-automation-button negative-button"
|
||||
onclick="deleteAutomation(${placeholderId}, true)"
|
||||
id="delete-automation-button-${placeholderId}">Cancel</button>
|
||||
<button type="button"
|
||||
class="save-automation-button"
|
||||
onclick="saveAutomation(${placeholderId}, true)"
|
||||
id="save-automation-button-${placeholderId}">Create</button>
|
||||
</div>
|
||||
<div id="automation-success-${placeholderId}" style="display: none;"></div>
|
||||
`;
|
||||
document.getElementById("automations").insertBefore(automationEl, document.getElementById("automations").firstChild);
|
||||
|
|
|
@ -34,6 +34,7 @@ from khoj.routers.helpers import (
|
|||
ApiUserRateLimiter,
|
||||
CommonQueryParams,
|
||||
ConversationCommandRateLimiter,
|
||||
acreate_title_from_query,
|
||||
schedule_automation,
|
||||
update_telemetry_state,
|
||||
)
|
||||
|
@ -425,7 +426,6 @@ def delete_automation(request: Request, automation_id: str) -> Response:
|
|||
async def post_automation(
|
||||
request: Request,
|
||||
q: str,
|
||||
subject: str,
|
||||
crontime: str,
|
||||
city: Optional[str] = None,
|
||||
region: Optional[str] = None,
|
||||
|
@ -435,8 +435,8 @@ async def post_automation(
|
|||
user: KhojUser = request.user.object
|
||||
|
||||
# Perform validation checks
|
||||
if is_none_or_empty(q) or is_none_or_empty(subject) or is_none_or_empty(crontime):
|
||||
return Response(content="A query, subject and crontime is required", status_code=400)
|
||||
if is_none_or_empty(q) or is_none_or_empty(crontime):
|
||||
return Response(content="A query and crontime is required", status_code=400)
|
||||
if not cron_descriptor.get_description(crontime):
|
||||
return Response(content="Invalid crontime", status_code=400)
|
||||
|
||||
|
@ -452,7 +452,7 @@ async def post_automation(
|
|||
crontime = " ".join(crontime.split(" ")[:5])
|
||||
# Convert crontime to standard unix crontime
|
||||
crontime = crontime.replace("?", "*")
|
||||
subject = subject.strip()
|
||||
subject = await acreate_title_from_query(q)
|
||||
|
||||
# Schedule automation with query_to_run, timezone, subject directly provided by user
|
||||
try:
|
||||
|
|
Loading…
Add table
Reference in a new issue