blob: e50089c98ccf760936b9372d8a9a4e4bdf207277 [file] [log] [blame]
/**
* @module modules/favorites-dialog-sk
* @description <h2><code>favorites-dialog-sk</code></h2>
*
* This module is a modal that contains a form to capture user
* input for adding/editing a new favorite.
*/
import { html } from 'lit/html.js';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { $$ } from '../../../infra-sk/modules/dom';
import { define } from '../../../elements-sk/modules/define';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';
import '../../../elements-sk/modules/spinner-sk';
import '../../../elements-sk/modules/icons/close-icon-sk';
// FavoritesDialogSk is a modal that contains a form to capture user
// input for adding/editing a new favorite.
export class FavoritesDialogSk extends ElementSk {
favId: string = '';
name: string = '';
description: string = '';
url: string = '';
private dialog: HTMLDialogElement | null = null;
private updatingFavorite: boolean = false;
private resolve: ((value?: any) => void) | null = null;
private reject: ((value?: any) => void) | null = null;
constructor() {
super(FavoritesDialogSk.template);
}
connectedCallback(): void {
super.connectedCallback();
this._render();
this.dialog = $$('dialog', this);
}
private dismiss(): void {
this.dialog!.close();
this.reject!();
}
private async confirm(): Promise<void> {
if (this.name === '' || this.url === '') {
errorMessage('Name and url must be non empty');
return;
}
let apiUrl = '/_/favorites/new';
let body: {
id?: string;
name: string;
description: string;
url: string;
} = {
name: this.name,
description: this.description,
url: this.url,
};
if (this.favId !== '') {
body = { ...body, id: this.favId };
apiUrl = '/_/favorites/edit';
}
try {
this.updatingFavorite = true;
this._render();
const resp = await fetch(apiUrl, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
});
if (!resp.ok) {
const msg = await resp.text();
errorMessage(`${resp.statusText}: ${msg}`);
}
} finally {
this.updatingFavorite = false;
this.dialog!.close();
this.resolve!();
}
}
// open shows the popup dialog when called.
public open(
favId?: string,
name?: string,
description?: string,
url?: string
): Promise<void> {
this.favId = favId || '';
this.name = name || '';
this.description = description || '';
this.url = url || window.location.href;
this._render();
this.dialog!.showModal();
// If the dialog closes it could be due to 2 reasons:
// 1: User pressed on close
// 2: The favorite got added/edited.
// In this module, we want to re-fetch the favorites when the dialog is closed
// but we only want to re-fetch if closed due to reason 2.
// So we're using the reject function when the user presses on close dialog
// which is eventually used in favorites-sk to decide if it wants to
// re-fetch the favorites or not.
return new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
private filterName(e: Event): void {
this.name = (e.target as HTMLInputElement).value;
this._render();
}
private filterDescription(e: Event): void {
this.description = (e.target as HTMLInputElement).value;
this._render();
}
private filterUrl(e: Event): void {
this.url = (e.target as HTMLInputElement).value;
this._render();
}
private static template = (ele: FavoritesDialogSk) => html`
<dialog id="favDialog">
<h2>Favorite</h2>
<button id="favCloseIcon" @click=${ele.dismiss}>
<close-icon-sk></close-icon-sk>
</button>
<div id=spinContainer>
<spinner-sk ?active=${ele.updatingFavorite}></spinner-sk>
</div>
<span class="label">
<label>Name*</label>
</span>
<input
id="name"
placeholder="Name"
.value="${ele.name}"
@input=${(e: Event) => ele.filterName(e)}>
</input>
<br/>
<span class="label">
<label>Description</label>
</span>
<input
id="desc"
placeholder="Description"
.value="${ele.description}"
@input=${(e: Event) => ele.filterDescription(e)}></input>
<br/>
<span class="label">
<label>URL*</label>
</span>
<input
id="url"
placeholder="URL"
value="${ele.url}"
@input=${(e: Event) => ele.filterUrl(e)}></input>
<br/><br/>
<div ?hidden="${!ele.updatingFavorite}">
Working on it...
</div>
<div class="buttons">
<button ?disabled="${ele.updatingFavorite}" @click=${
ele.dismiss
}>Cancel</button>
<button ?disabled="${ele.updatingFavorite}" @click=${
ele.confirm
}>Save</button>
</div>
</dialog>`;
}
define('favorites-dialog-sk', FavoritesDialogSk);