1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-09-16 17:30:11 +00:00

add remaining modals

This commit is contained in:
Harvey Tindall 2020-12-23 01:34:22 +00:00
parent e50a7948e7
commit d59d5faa03
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
12 changed files with 163 additions and 1533 deletions

3
.gitignore vendored
View File

@ -24,3 +24,6 @@ version.go
notes
docs/*
!docs/go.mod
main.js*
modal.js*

View File

@ -5,9 +5,9 @@ This branch is for experimenting with [a17t](https://a17t.miles.land/) to possib
* [x] accounts tab mockup
* [x] settings tab mockup
* [x] modal implementation
* [ ] modal content
* [ ] animations
* [ ] JS to TS, utilities
* [x] modals
* [x] animations
* [x] JS to TS, utilities
* [ ] Integration with existing code
#### screenshots
@ -15,6 +15,7 @@ This branch is for experimenting with [a17t](https://a17t.miles.land/) to possib
<img src="images/invites.png" alt="invites" style="width: 32%; height: auto;">
<img src="images/accounts.png" alt="accounts" style="width: 32%; height: auto;">
<img src="images/settings.png" alt="settings" style="width: 32%; height: auto;">
<img src="images/login-modal.png" alt="settings" style="width: 32%; height: auto;">
<img src="images/login-modal.png" alt="login modal" style="width: 32%; height: auto;">
<img src="images/modify-settings.png" alt="modify user settings modal" style="width: 32%; height: auto;">
</p>

View File

@ -48,6 +48,9 @@ input[type=number] {
.mb-2 {
margin-bottom: 2rem;
}
.mt-1 {
margin-top: 1rem;
}
.mt-half {
margin-top: 0.5rem;
}
@ -193,7 +196,6 @@ input[type=number] {
.full-width {
box-sizing: border-box;
width: 100%;
justify-content: center;
}
.unfocused {
display: none;
@ -242,3 +244,24 @@ input[type=number] {
font-size: 1rem;
}
.inline {
display: inline;
}
.flex-row {
display: flex;
flex-direction: row;
}
.fw-group {
display: block;
flex-grow: 1;
}
.center {
justify-content: center;
}
.textarea {
resize: vertical;
}

BIN
images/modify-settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -12,7 +12,7 @@
<span class="heading">Login</span>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="username" id="login-user">
<input type="password" class="field input ~neutral !high mb-1" placeholder="password" id="login-password">
<input type="submit" class="button ~positive !normal full-width supra submit" value="Login">
<input type="submit" class="button ~positive !normal full-width center supra submit" value="Login">
</form>
</div>
<div id="modal-add-user" class="modal">
@ -20,7 +20,7 @@
<span class="heading">New User <span class="modal-close">&times;</span></span>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="username" id="add-user-user">
<input type="password" class="field input ~neutral !high mb-1" placeholder="password" id="add-user-password">
<input type="submit" class="button ~positive !normal full-width supra submit" value="Create">
<input type="submit" class="button ~positive !normal full-width center supra submit" value="Create">
</form>
</div>
<div id="modal-about" class="modal">
@ -33,6 +33,82 @@
<p><a href="https://github.com/hrfee/jfa-go/blob/main/LICENSE">Available under the MIT License.</a></p>
</div>
</div>
<div id="modal-modify-user" class="modal">
<form class="modal-content card" id="form-modify-user" href="">
<span class="heading"><span id="header-modify-user">Modify Settings</span> <span class="modal-close">&times;</span></span>
<p class="content">Apply settings from an existing profile, or source them directly from a user.</p>
<div class="flex-row mb-1">
<label class="fw-group mr-1">
<input type="radio" name="modify-user-source" class="hidden" id="radio-use-profile" checked>
<span class="button ~neutral !high supra full-width center">Profile</span>
</label>
<label class="fw-group ml-1">
<input type="radio" name="modify-user-source" class="hidden" id="radio-use-user">
<span class="button ~neutral !normal supra full-width center">User</span>
</label>
</div>
<div id="modify-user-profiles" class="select ~neutral !normal mb-1">
<select>
<option>Friends</option>
<option>Family</option>
<option>Default</option>
</select>
</div>
<div id="modify-user-users" class="select ~neutral !normal mb-1 hidden">
<select>
<option>Person</option>
<option>Other person</option>
</select>
</div>
<label class="switch mb-1">
<input type="checkbox" id="modify-user-homescreen" checked>
<span>Apply homescreen layout</span>
</label>
<input type="submit" class="button ~positive !normal full-width center supra submit" value="Apply">
</form>
</div>
<div id="modal-delete-user" class="modal">
<form class="modal-content card" id="form-delete-user" href="">
<span class="heading"><span id="header-delete-user">Delete User</span> <span class="modal-close">&times;</span></span>
<div class="content mt-half">
<label class="switch mb-1">
<input type="checkbox" id="delete-user-notify" checked>
<span>Send notification email</span>
</label>
<textarea id="textarea-delete-user" class="textarea full-width ~neutral !normal mb-1" placeholder="Your account has been deleted."></textarea>
<input type="submit" class="button ~positive !normal full-width center supra submit" value="Apply">
</div>
</form>
</div>
<div id="modal-restart" class="modal">
<div class="modal-content card ~critical !normal">
<span class="heading">Restart needed <span class="modal-close">&times;</span></span>
<p class="content pb-1">A restart is needed to apply some settings you changed. Do it now or later?</p>
<div class="fr">
<span class="button ~info !normal">Apply, restart later</span>
<span class="button ~critical !normal">Apply &amp; restart</span>
</div>
</div>
</div>
<div id="modal-refresh" class="modal">
<div class="modal-content card ~positive !normal">
<span class="heading">Settings applied.</span>
<p class="content">Refresh the page in a few seconds.</p>
</div>
</div>
<div id="modal-ombi-defaults" class="modal">
<form class="modal-content card" id="form-ombi-defaults" href="">
<span class="heading">Ombi user defaults <span class="modal-close">&times;</span></span>
<p class="content">Create an Ombi user and configure it, then select it here. It's settings/permissions will be stored and applied to new ombi users created by jfa-go.</p>
<div class="select ~neutral !normal mb-1">
<select>
<option>Person</option>
<option>Other person</option>
</select>
</div>
<input type="submit" class="button ~positive !normal full-width center supra submit" value="Submit">
</form>
</div>
<div class="pageContainer max-w-screen-lg px-6 py-4 mx-auto lg:mx-auto md:py-8">
<div class="relative mb-1">
<header class="flex flex-wrap items-center justify-between">
@ -50,7 +126,7 @@
<span id="modalButton" class="button ~neutral !normal mb-1">Trigger Login</span>
</div>
</div>
<div id="invitesTab" class="unfocused">
<div id="invitesTab">
<div class="card ~neutral !high invites mb-1">
<span class="heading">Invites</span>
<div class="inv">
@ -161,7 +237,7 @@
<input type="checkbox" id="inv-email-enabled" aria-label="Send to address enabled">
</label>
</div>
<span class="button ~positive !normal supra full-width button-lg">Create</span>
<span class="button ~positive !normal supra full-width center button-lg">Create</span>
</div>
</div>
</div>
@ -172,7 +248,7 @@
<div class="fr">
<span class="button ~neutral !normal" id="accounts-add-user">Add User</span>
<span class="button ~positive !normal" id="accounts-modify-user">Modify Settings</span>
<span class="button ~critical !normal" id="accounts-delte-user">Delete User</span>
<span class="button ~critical !normal" id="accounts-delete-user">Delete User</span>
</div>
<div class="card ~neutral !normal accounts-header mt-half">
<table class="table">
@ -202,9 +278,12 @@
</div>
</div>
</div>
<div id="settingsTab">
<div id="settingsTab" class="unfocused">
<div class="card ~neutral !high settings">
<span class="heading">Settings</span>
<div class="fr">
<span class="button ~neutral !normal" id="accounts-add-user">Save</span>
</div>
<div class="row">
<div class="card ~neutral !normal col">
<aside class="aside small ~info mb-half">Note: <sup class="text-critical">*</sup> indicates a required field, <sup class="text-critical">R</sup> indicates changes require a restart.</aside>
@ -233,12 +312,10 @@
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="modal.js"></script>
<script src="main.js"></script>

110
main.js
View File

@ -1,110 +0,0 @@
const whichAnimationEvent = () => {
const el = document.createElement("fakeElement");
if (el.style["animation"] !== void 0) {
return "animationend";
}
return "webkitAnimationEnd";
};
window.animationEvent = whichAnimationEvent();
const toggles = Array.from(document.getElementsByClassName("toggle-details"));
for (let toggle of toggles) {
toggle.onclick = () => {
const el = toggle.parentElement.parentElement.parentElement.nextElementSibling;
if (el.classList.contains("visible")) {
el.classList.toggle("visible");
el.classList.toggle("hidden");
} else {
el.classList.toggle("hidden");
el.classList.toggle("visible");
}
toggle.previousElementSibling.classList.toggle("rotated");
toggle.previousElementSibling.classList.toggle("not-rotated");
};
}
const checkInfUses = function(check, mode = 2) {
const uses = document.getElementById("inv-uses");
if (mode == 2) {
uses.disabled = check.checked;
check.parentElement.classList.toggle("!normal");
check.parentElement.classList.toggle("!high");
} else if (mode == 1) {
uses.disabled = true;
check.checked = true;
check.parentElement.classList.remove("!normal");
check.parentElement.classList.add("!high");
} else {
uses.disabled = false;
check.checked = false;
check.parentElement.classList.remove("!high");
check.parentElement.classList.add("!normal");
}
};
let invInfUses = document.getElementById("inv-inf-uses");
invInfUses.onclick = () => {
checkInfUses(invInfUses, 2);
};
const checkEmailEnabled = function(check, mode = 2) {
const input = document.getElementById("inv-email");
if (mode == 2) {
input.disabled = !check.checked;
check.parentElement.classList.toggle("!normal");
check.parentElement.classList.toggle("!high");
} else if (mode == 1) {
input.disabled = false;
check.checked = true;
check.parentElement.classList.remove("!normal");
check.parentElement.classList.add("!high");
} else {
input.disabled = true;
check.checked = false;
check.parentElement.classList.remove("!high");
check.parentElement.classList.add("!normal");
}
};
let invEmailEnabled = document.getElementById("inv-email-enabled");
invEmailEnabled.onchange = () => {
checkEmailEnabled(invEmailEnabled, 2);
};
checkInfUses(invInfUses, 0);
checkEmailEnabled(invEmailEnabled, 0);
const loadAccounts = function() {
const rows = Array.from(document.getElementById("accounts-list").children);
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const editButton = row.querySelector(".icon");
const emailInput = row.querySelector(".input");
editButton.onclick = function() {
emailInput.classList.toggle("stealth-input-hidden");
emailInput.readOnly = !emailInput.readOnly;
editButton.classList.toggle("icon-edit");
editButton.classList.toggle("icon-check");
};
}
};
loadAccounts();
const tabs = ["invitesTab", "accountsTab", "settingsTab"];
for (let tab of tabs) {
document.getElementById(`${tab}-button`).onclick = function() {
for (let t of tabs) {
const tabEl = document.getElementById(t);
const tabButtonEl = document.getElementById(`${t}-button`);
if (t == tab) {
tabButtonEl.classList.add("active", "~positive");
tabEl.classList.remove("unfocused");
} else {
tabButtonEl.classList.remove("active");
tabButtonEl.classList.remove("~positive");
tabEl.classList.add("unfocused");
}
}
};
}
const modalLogin = new Modal(document.getElementById("modal-login"), true);
document.getElementById("form-login").addEventListener("submit", modalLogin.close);
document.getElementById("modalButton").onclick = modalLogin.toggle;
const modalAddUser = new Modal(document.getElementById("modal-add-user"));
document.getElementById("accounts-add-user").onclick = modalAddUser.toggle;
document.getElementById("form-add-user").addEventListener("submit", modalAddUser.close);
const modalAbout = new Modal(document.getElementById("modal-about"));
document.getElementById("setting-about").onclick = modalAbout.toggle;
//# sourceMappingURL=main.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,41 +0,0 @@
class Modal {
constructor(modal, important = false) {
this.close = (event) => {
if (event) {
event.preventDefault();
}
this.modal.classList.add("modal-hiding");
const modal = this.modal;
const listenerFunc = function() {
modal.classList.remove("modal-shown");
modal.classList.remove("modal-hiding");
modal.removeEventListener(window.animationEvent, listenerFunc);
};
this.modal.addEventListener(window.animationEvent, listenerFunc, false);
};
this.show = () => {
this.modal.classList.add("modal-shown");
};
this.toggle = () => {
if (this.modal.classList.contains("modal-shown")) {
this.close();
} else {
this.show();
}
};
this.modal = modal;
const closeButton = this.modal.querySelector("span.modal-close");
if (closeButton !== null) {
this.closeButton = closeButton;
this.closeButton.onclick = this.close;
}
if (!important) {
window.addEventListener("click", (event) => {
if (event.target == this.modal) {
this.close();
}
});
}
}
}
//# sourceMappingURL=modal.js.map

View File

@ -1,7 +0,0 @@
{
"version": 3,
"sources": ["ts/modal.ts"],
"sourcesContent": ["declare var window: Window;\n\nclass Modal {\n modal: HTMLDivElement;\n closeButton: HTMLSpanElement;\n constructor(modal: HTMLDivElement, important: boolean = false) {\n this.modal = modal;\n const closeButton = this.modal.querySelector('span.modal-close')\n if (closeButton !== null) {\n this.closeButton = closeButton as HTMLSpanElement;\n this.closeButton.onclick = this.close;\n }\n if (!important) {\n window.addEventListener('click', (event: Event) => {\n if (event.target == this.modal) { this.close(); }\n });\n }\n }\n close = (event?: Event) => {\n if (event) {\n event.preventDefault();\n }\n this.modal.classList.add('modal-hiding');\n const modal = this.modal;\n const listenerFunc = function () {\n modal.classList.remove('modal-shown');\n modal.classList.remove('modal-hiding');\n modal.removeEventListener(window.animationEvent, listenerFunc);\n };\n this.modal.addEventListener(window.animationEvent, listenerFunc, false);\n }\n show = () => {\n this.modal.classList.add('modal-shown');\n }\n toggle = () => {\n if (this.modal.classList.contains('modal-shown')) {\n this.close();\n } else {\n this.show();\n }\n }\n}\n"],
"mappings": "AAAA;AAAA,EAKI,YAAY,mBAA4C;AAaxD,iBAAQ;AACJ,UAAI;AACA,cAAM;AAAA;AAEV,WAAK,MAAM,UAAU,IAAI;AACzB,oBAAc,KAAK;AACnB,2BAAqB;AACjB,cAAM,UAAU,OAAO;AACvB,cAAM,UAAU,OAAO;AACvB,cAAM,oBAAoB,OAAO,gBAAgB;AAAA;AAErD,WAAK,MAAM,iBAAiB,OAAO,gBAAgB,cAAc;AAAA;AAErE,gBAAO;AACH,WAAK,MAAM,UAAU,IAAI;AAAA;AAE7B,kBAAS;AACL,UAAI,KAAK,MAAM,UAAU,SAAS;AAC9B,aAAK;AAAA;AAEL,aAAK;AAAA;AAAA;AAhCT,SAAK,QAAQ;AACb,wBAAoB,KAAK,MAAM,cAAc;AAC7C,QAAI,gBAAgB;AAChB,WAAK,cAAc;AACnB,WAAK,YAAY,UAAU,KAAK;AAAA;AAEpC,QAAI,CAAC;AACD,aAAO,iBAAiB,SAAS;AAC7B,YAAI,MAAM,UAAU,KAAK;AAAS,eAAK;AAAA;AAAA;AAAA;AAAA;AAAA;",
"names": []
}

1340
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
{
"name": "jfa-go-a17t",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"a17t": "^0.3.0",
"icons.css": "git+https://github.com/picturepan2/icons.css.git"
}
}

View File

@ -96,6 +96,37 @@ const loadAccounts = function () {
loadAccounts();
const modifySettingsSource = function () {
const profile = document.getElementById('radio-use-profile') as HTMLInputElement;
const user = document.getElementById('radio-use-user') as HTMLInputElement;
const profileSelect = document.getElementById('modify-user-profiles') as HTMLDivElement;
const userSelect = document.getElementById('modify-user-users') as HTMLDivElement;
(user.nextElementSibling as HTMLSpanElement).classList.toggle('!normal');
(user.nextElementSibling as HTMLSpanElement).classList.toggle('!high');
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('!normal');
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('!high');
profileSelect.classList.toggle('hidden');
userSelect.classList.toggle('hidden');
}
const radioUseProfile = document.getElementById('radio-use-profile') as HTMLInputElement;
radioUseProfile.addEventListener("change", modifySettingsSource);
radioUseProfile.checked = true;
const radioUseUser = document.getElementById('radio-use-user') as HTMLInputElement;
radioUseUser.addEventListener("change", modifySettingsSource);
radioUseUser.checked = false;
const checkDeleteUserNotify = function () {
if ((document.getElementById('delete-user-notify') as HTMLInputElement).checked) {
document.getElementById('textarea-delete-user').classList.remove('hidden');
} else {
document.getElementById('textarea-delete-user').classList.add('hidden');
}
};
(document.getElementById('delete-user-notify') as HTMLInputElement).onchange = checkDeleteUserNotify;
checkDeleteUserNotify();
const tabs = ["invitesTab", "accountsTab", "settingsTab"]
for (let tab of tabs) {
(document.getElementById(`${tab}-button`) as HTMLSpanElement).onclick = function () {
@ -125,3 +156,18 @@ document.getElementById('form-add-user').addEventListener('submit', modalAddUser
const modalAbout = new Modal(document.getElementById('modal-about'));
(document.getElementById('setting-about') as HTMLSpanElement).onclick = modalAbout.toggle;
const modalModifyUser = new Modal(document.getElementById('modal-modify-user'));
document.getElementById('form-modify-user').addEventListener('submit', modalModifyUser.close);
(document.getElementById('accounts-modify-user') as HTMLSpanElement).onclick = modalModifyUser.toggle;
const modalDeleteUser = new Modal(document.getElementById('modal-delete-user'));
document.getElementById('form-delete-user').addEventListener('submit', modalDeleteUser.close);
(document.getElementById('accounts-delete-user') as HTMLSpanElement).onclick = modalDeleteUser.toggle;
const modalRestart = new Modal(document.getElementById('modal-restart'));
const modalRefresh = new Modal(document.getElementById('modal-refresh'));
const modalOmbiDefaults = new Modal(document.getElementById('modal-ombi-defaults'));
document.getElementById('form-ombi-defaults').addEventListener('submit', modalOmbiDefaults.close);