diff --git a/internal/glance/glance.go b/internal/glance/glance.go index 879a60f..6ebca75 100644 --- a/internal/glance/glance.go +++ b/internal/glance/glance.go @@ -456,6 +456,7 @@ func (a *application) server() (func() error, func() error) { mux.HandleFunc("POST /api/vikunja/{widgetID}/add-label", a.handleVikunjaAddLabel) mux.HandleFunc("POST /api/vikunja/{widgetID}/remove-label", a.handleVikunjaRemoveLabel) mux.HandleFunc("GET /api/vikunja/{widgetID}/labels", a.handleVikunjaGetLabels) + mux.HandleFunc("GET /api/vikunja/{widgetID}/projects", a.handleVikunjaGetProjects) mux.HandleFunc("GET /api/vikunja/{widgetID}/refresh", a.handleVikunjaRefresh) mux.HandleFunc("POST /api/vikunja/{widgetID}/create-task", a.handleVikunjaCreateTask) @@ -734,6 +735,40 @@ func (a *application) handleVikunjaGetLabels(w http.ResponseWriter, r *http.Requ json.NewEncoder(w).Encode(labels) } +func (a *application) handleVikunjaGetProjects(w http.ResponseWriter, r *http.Request) { + widgetIDStr := r.PathValue("widgetID") + widgetID, err := strconv.ParseUint(widgetIDStr, 10, 64) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("Invalid widget ID")) + return + } + + widget, exists := a.widgetByID[widgetID] + if !exists { + w.WriteHeader(http.StatusNotFound) + w.Write([]byte("Widget not found")) + return + } + + vikunjaWidget, ok := widget.(*vikunjaWidget) + if !ok { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("Widget is not a Vikunja widget")) + return + } + + projects, err := vikunjaWidget.fetchProjects() + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(projects) +} + func (a *application) handleVikunjaRefresh(w http.ResponseWriter, r *http.Request) { widgetIDStr := r.PathValue("widgetID") widgetID, err := strconv.ParseUint(widgetIDStr, 10, 64) @@ -792,9 +827,10 @@ func (a *application) handleVikunjaCreateTask(w http.ResponseWriter, r *http.Req } var request struct { - Title string `json:"title"` - DueDate string `json:"due_date"` - LabelIDs []int `json:"label_ids"` + Title string `json:"title"` + DueDate string `json:"due_date"` + LabelIDs []int `json:"label_ids"` + ProjectID int `json:"project_id"` } if err := json.NewDecoder(r.Body).Decode(&request); err != nil { @@ -803,7 +839,7 @@ func (a *application) handleVikunjaCreateTask(w http.ResponseWriter, r *http.Req return } - task, err := vikunjaWidget.createTask(request.Title, request.DueDate, request.LabelIDs) + task, err := vikunjaWidget.createTask(request.Title, request.DueDate, request.LabelIDs, request.ProjectID) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Failed to create task: %v", err))) diff --git a/internal/glance/static/js/vikunja.js b/internal/glance/static/js/vikunja.js index 1b820e4..a9e340f 100644 --- a/internal/glance/static/js/vikunja.js +++ b/internal/glance/static/js/vikunja.js @@ -303,11 +303,34 @@ function openCreateModal(widgetID) { const modal = document.getElementById('vikunja-create-modal'); const titleInput = document.getElementById('vikunja-create-title'); const dueDateInput = document.getElementById('vikunja-create-due-date'); + const projectSelect = document.getElementById('vikunja-create-project'); const labelsContainer = document.getElementById('vikunja-create-labels-container'); // Clear the form titleInput.value = ''; dueDateInput.value = ''; + + // Fetch and populate projects + projectSelect.innerHTML = ''; + + fetch(`${pageData.baseURL}/api/vikunja/${widgetID}/projects`) + .then(response => response.json()) + .then(projects => { + projectSelect.innerHTML = ''; + + if (projects && projects.length > 0) { + projects.forEach(project => { + const option = document.createElement('option'); + option.value = project.id; + option.textContent = project.title; + projectSelect.appendChild(option); + }); + } + }) + .catch(error => { + console.error('Error fetching projects:', error); + projectSelect.innerHTML = ''; + }); // Fetch and display labels labelsContainer.innerHTML = '
Ładowanie etykiet...
'; @@ -360,6 +383,7 @@ function openCreateModal(widgetID) { async function createTask() { const title = titleInput.value.trim(); const dueDate = dueDateInput.value; + const projectID = projectSelect.value ? parseInt(projectSelect.value) : 0; // Get selected label IDs const selectedLabels = Array.from(labelsContainer.querySelectorAll('input[type="checkbox"]:checked')) @@ -387,7 +411,8 @@ function openCreateModal(widgetID) { body: JSON.stringify({ title: title, due_date: formattedDueDate, - label_ids: selectedLabels + label_ids: selectedLabels, + project_id: projectID }) }); diff --git a/internal/glance/templates/vikunja.html b/internal/glance/templates/vikunja.html index 8ab6a95..ef757f3 100644 --- a/internal/glance/templates/vikunja.html +++ b/internal/glance/templates/vikunja.html @@ -79,6 +79,12 @@ +