Set subject dynamically when creating new tasks, and make some minor improvments to the automations UI

This commit is contained in:
sabaimran 2024-05-01 13:54:59 +05:30
parent d1b2037676
commit c30ba2e551
2 changed files with 62 additions and 32 deletions

View file

@ -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}&region=${ip_data.region}&country=${ip_data.country_name}&timezone=${ip_data.timezone}`;
let query_string = `q=${queryToRun}&crontime=${encodedCrontime}&city=${ip_data.city}&region=${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);

View file

@ -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: