playback-device-server/www/src/modals/edit-remote-modal.jsx

146 lines
4.0 KiB
JavaScript

import {
createEffect,
createMemo,
createResource,
createSignal,
} from "solid-js";
import ListManager from "../components/list-manager.jsx";
import ValidatedTextInput from "../components/validated-text-input.jsx";
import Remote from "../data/remote.js";
import RemoteService from "../services/remotes-service.js";
import EventEmitter from "../tools/event-emitter.js";
import ModalHandler from "./modal-handler.js";
import Modal from "./modal.jsx";
const eventEmitter = new EventEmitter();
const REMOTE_EDITED_EVENT = "success";
const MIN_TITLE_LENGTH = 3;
const modalHandler = new ModalHandler();
const [remoteId, setRemoteId] = createSignal(null);
function EditRemoteModal(props) {
const [title, setTitle] = createSignal("");
const [commands, setCommands] = createSignal([]);
const [availableCommands, { refetch: refetchAvailableCommands }] =
createResource(RemoteService.getCommands);
const [remote, {}] = createResource(
remoteId,
() => RemoteService.getRemote(remoteId()),
{ initialValue: new Remote() }
);
const [error, setError] = createSignal("");
const isTitleValid = createMemo(() => title().length >= MIN_TITLE_LENGTH);
const isFormValid = createMemo(() => isTitleValid());
createEffect(() => {
if (!remote()) return;
setTitle(remote().getTitle());
setCommands(remote().getCommands());
});
modalHandler.onShow(() => {
refetchAvailableCommands();
});
async function handleEditRemote() {
try {
await RemoteService.updateRemote(
new Remote({
id: remote().getId(),
title: title(),
commands: commands(),
})
);
} catch (e) {
setError(e.message);
console.error(e);
return;
}
resetFields();
EditRemoteModal.Handler.hide();
eventEmitter.dispatchEvent(REMOTE_EDITED_EVENT);
}
function resetFields() {
setTitle("");
setCommands([]);
setRemoteId("");
setError("");
}
function handleCommandSelect(item) {
setCommands([...commands(), item]);
}
function handleCommandDeselect(item) {
setCommands(
commands().filter((command) => command.getId() !== item.getId())
);
}
return (
<Modal
ref={props.ref}
id="editRemoteModal"
modalTitle="New Remote"
centered={true}
>
<div class="modal-body bg-body-tertiary">
<Show when={error() !== ""}>
<div class="alert alert-danger" role="alert">
{error()}
</div>
</Show>
<div class="mb-3 row">
<label for="edit_remote_title" class="col-form-label col-sm-1">
Title
</label>
<ValidatedTextInput
class="col-sm-11"
id="edit_remote_title"
valid={isTitleValid()}
value={title()}
onInput={(e) => setTitle(e.target.value)}
errorText={`Title must be at least ${MIN_TITLE_LENGTH} characters long`}
/>
</div>
<ListManager
style="height: 20em;"
items={commands()}
availableItems={availableCommands()}
itemToString={(command) =>
`${command.getTitle()} (${command.getProtocol()}:${command.getCommandType()})`
}
onItemSelect={handleCommandSelect}
onItemDeselect={handleCommandDeselect}
itemsTitle="Selected Commands"
availableItemsTitle="Available Commands"
itemsEqual={(a, b) => a.getId() === b.getId()}
/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Cancel
</button>
<button
type="button"
onClick={handleEditRemote}
class="btn btn-primary"
disabled={!isFormValid()}
>
Edit
</button>
</div>
</Modal>
);
}
EditRemoteModal.Handler = modalHandler;
EditRemoteModal.onRemoteEdited = (callback) =>
eventEmitter.on(REMOTE_EDITED_EVENT, callback);
EditRemoteModal.setRemoteId = setRemoteId;
export default EditRemoteModal;