Skip to content

Commit

Permalink
Modal for editing and saving query
Browse files Browse the repository at this point in the history
  • Loading branch information
dkumiszhan committed Aug 17, 2023
1 parent 87d571e commit 04f33ad
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 172 deletions.
7 changes: 3 additions & 4 deletions backend/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,17 +183,16 @@ func (cs *server) updateQueryHandler(w http.ResponseWriter, r *http.Request, p h
}
decoder := json.NewDecoder(r.Body)
defer r.Body.Close()
var t entities.Query
err = decoder.Decode(&t)
err = decoder.Decode(&q)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if id != t.ID {
if id != q.ID {
http.Error(w, "Ids dont match", http.StatusBadRequest)
return
}
err = cs.queryRepo.Update(t.ID, t.Content, t.Description, t.Active)
err = cs.queryRepo.Update(q.ID, q.Content, q.Description, q.Active)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
Expand Down
4 changes: 3 additions & 1 deletion frontend/components/Filter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
}
function openSaveQuery() {
saveModal.showModal(filter);
saveModal.showModal({
content: filter,
});
}
</script>

Expand Down
162 changes: 48 additions & 114 deletions frontend/components/QueryList.svelte
Original file line number Diff line number Diff line change
@@ -1,130 +1,64 @@
<script lang="ts">
import { onMount } from 'svelte';
import { token } from '../store';
import type { Query } from '../query';
import { API_ENDPOINT } from '../constants';
let queryList = getQueries();
let queryToEdit = undefined;
async function getQueries(): Promise<Query[]> {
console.log('fetching queries');
const res = await fetch(`${API_ENDPOINT}/queries`, {
method: 'GET',
headers: {
Authorization: `Bearer ${$token}`,
'Content-Type': 'application/json',
},
});
if (res.ok) {
console.log('received success ');
const data = await res.json();
console.log(data);
return data;
} else {
console.log('failed to save ' + res.text());
throw new Error('Could not fetch queries');
}
}
import { token, userQueries } from '../store';
import { Query, deleteQuery, getQueries, updateQuery } from '../query';
import QueryModal from './QueryModal.svelte';
async function updateQuery() {
console.log('updating a query');
const res = await fetch(`${API_ENDPOINT}/queries/${queryToEdit.id}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${$token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: queryToEdit.id,
content: queryToEdit.content,
description: queryToEdit.description,
active: queryToEdit.active,
}),
});
if (res.ok) {
console.log('received success');
queryList = getQueries();
queryToEdit = undefined;
} else {
console.log('failed to update');
throw new Error('Could not update a query');
}
}
let saveModal: QueryModal;
function editQuery(query: Query) {
queryToEdit = query;
onMount(() => {
reloadQueries();
});
async function reloadQueries() {
let updatedQueries = await getQueries($token);
userQueries.set(updatedQueries);
}
function hideForm() {
queryToEdit = undefined;
async function deleteQueryAndReload(id: string) {
await deleteQuery(id, $token);
await reloadQueries();
}
async function deleteQuery(id) {
console.log(`deleting query with id ${id}`);
const res = await fetch(`${API_ENDPOINT}/queries/${id}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${$token}`,
'Content-Type': 'application/json',
async function toggleActive(query: Query) {
console.log('toggling active in query', query);
await updateQuery(
{
id: query.id,
active: !query.active,
},
});
if (res.ok) {
console.log('received success');
queryList = getQueries();
} else {
console.log('failed to delete');
throw new Error('Could not delete a query');
}
$token,
);
await reloadQueries();
}
</script>

{#await queryList then data}
<h2 class="queryList__title">Saved Queries</h2>
<ul class="queryList__items">
{#each data as query, index (query.id)}
<li class="queryList__item">
<div class="queryList__item-container">
{index + 1}.
<div class="queryList__info-container">
<p class="queryList__info-field queryList__content">{query.content}</p>
<p class="queryList__info-field queryList__description">
{#if query.description}{query.description}{/if}
</p>
<p class="queryList__info-field queryList__active">
{#if query.active}active{:else}inactive{/if}
</p>
</div>
</div>
<div class="queryList__buttons-container">
<button on:click={() => editQuery(query)}>Edit</button>
<button on:click={() => deleteQuery(query.id)}>Delete</button>
<h2 class="queryList__title">Saved Queries</h2>
<ul class="queryList__items">
{#each $userQueries as query, index (query.id)}
<li class="queryList__item">
<div class="queryList__item-container">
{index + 1}.
<div class="queryList__info-container">
<p class="queryList__info-field queryList__content">{query.content}</p>
<p class="queryList__info-field queryList__description">
{#if query.description}{query.description}{/if}
</p>
<p class="queryList__info-field queryList__active">
{#if query.active}active{:else}inactive{/if}
</p>
</div>
</li>
{/each}
</ul>
{#if queryToEdit}
<form class="queryList__form">
<label>
content
<input name="content" type="text" bind:value={queryToEdit.content} required />
</label>
<label>
description
<input name="description" type="text" bind:value={queryToEdit.description} />
</label>
<label>
active
<input name="active" type="checkbox" bind:checked={queryToEdit.active} />
</label>
<button type="button" on:click={updateQuery}>Save</button>
<button type="button" on:click={hideForm}>Cancel</button>
</form>
{/if}
{/await}
</div>
<div class="queryList__buttons-container">
<QueryModal bind:this={saveModal} />
<button on:click={() => saveModal.showModal(query)}>edit</button>
<button on:click={() => deleteQueryAndReload(query.id)}>Delete</button>
<button on:click={() => toggleActive(query)}>Toggle</button>
</div>
</li>
{/each}
</ul>

<style>
.queryList__items {
Expand Down
110 changes: 62 additions & 48 deletions frontend/components/QueryModal.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
<script lang="ts">
import { debounce } from '../util';
import { filterActive, token } from '../store';
import { escape } from 'svelte/internal';
import { token, userQueries } from '../store';
import { API_ENDPOINT } from '../constants';
import { Query, createQuery, getQueries, updateQuery } from '../query';
let dialog;
let currentFilter: string;
let currentDescription: string;
let currentActive: boolean;
let queryToEdit: Query = {};
export function showModal(filter: string) {
export function showModal(objectToEdit: Query) {
if (!dialog.open) {
dialog.showModal();
}
currentFilter = filter;
currentActive = $filterActive;
queryToEdit = objectToEdit;
}
function closeModal() {
Expand All @@ -23,57 +19,71 @@
}
}
function handleInputChange() {}
async function saveQuery() {
async function saveQueryAndReload() {
console.log('saving query');
const res = await fetch(`${API_ENDPOINT}/queries`, {
method: 'POST',
headers: {
Authorization: `Bearer ${$token}`,
'Content-Type': 'application/json',
await createQuery(
{
content: queryToEdit.content,
description: queryToEdit.description,
active: queryToEdit.active,
},
body: JSON.stringify({
content: currentFilter,
description: currentDescription,
active: currentActive,
}),
});
$token,
);
await reloadQueries();
}
if (res.ok) {
console.log('received success ' + res.text());
} else {
console.log('failed to save ' + res.text());
}
async function reloadQueries() {
$userQueries = await getQueries($token);
}
async function updateQueryAndReload() {
await updateQuery(
{
id: queryToEdit.id,
content: queryToEdit.content,
description: queryToEdit.description,
active: queryToEdit.active,
},
$token,
);
queryToEdit = {};
await reloadQueries();
}
async function confirmAndCloseModal() {
console.log('closing modal');
await saveQuery();
await saveQueryAndReload();
closeModal();
}
async function updateAndCloseModal() {
await updateQueryAndReload();
closeModal();
}
</script>

<dialog bind:this={dialog}>
<div on:click|stopPropagation>
<p>Content</p>
<input id="messages-input-box" type="text" bind:value={currentFilter} />
<p>Description</p>
<input id="messages-input-box" type="text" bind:value={currentDescription} />
<p>Active</p>
<input id="messages-input-box" type="checkbox" bind:checked={currentActive} />
<!-- <p>Model</p>
<label>
<input type="radio" bind:group={$env} name="currentEnv" id="dev" value="dev" />
Development
<form on:click|stopPropagation class="queryModal__form">
<label
>Content
<input id="messages-input-box" type="text" bind:value={queryToEdit.content} />
</label>
<label
>Description
<input id="messages-input-box" type="text" bind:value={queryToEdit.description} />
</label>
<label
>Active
<input id="messages-input-box" type="checkbox" bind:checked={queryToEdit.active} />
</label>
<label>
<input type="radio" bind:group={$env} name="currentEnv" id="prod" value="prod" />
Production
</label> -->
<button on:click={confirmAndCloseModal}>Confirm</button>
<button on:click={closeModal}>Cancel</button>
</div>
{#if queryToEdit && queryToEdit.id}
<button type="button" on:click={updateAndCloseModal}>Update</button>
{:else}
<button type="button" on:click={confirmAndCloseModal}>Confirm</button>
{/if}

<button type="button" on:click={closeModal}>Cancel</button>
</form>
</dialog>

<style>
Expand All @@ -86,7 +96,7 @@
dialog::backdrop {
background: rgba(0, 0, 0, 0.3);
}
dialog > div {
dialog > form {
padding: 1em;
}
dialog[open] {
Expand All @@ -104,4 +114,8 @@
border: 2px red solid;
outline: none;
}
.queryModal__form {
margin: 20px 20px;
}
</style>
Loading

0 comments on commit 04f33ad

Please sign in to comment.