flows: rewrite shell to webcomponents

This commit is contained in:
Jens Langhammer 2020-10-12 17:53:35 +02:00
parent 8ede4b6a13
commit b03a508475
5 changed files with 128 additions and 92 deletions

View File

@ -21,21 +21,12 @@
{% endblock %} {% endblock %}
{% block main_container %} {% block main_container %}
<main class="pf-c-login__main" id="flow-body"> <flow-shell-card
<div class="pf-c-login__main-body pb-loading"> class="pf-c-login__main"
<span class="pf-c-spinner" role="progressbar" aria-valuetext="Loading..."> flowBodyUrl="{{ exec_url }}">
<span class="pf-c-spinner__clipper"></span> </flow-shell-card>
<span class="pf-c-spinner__lead-ball"></span>
<span class="pf-c-spinner__tail-ball"></span>
</span>
</div>
</main>
<script> <script>
const flowBodyUrl = "{{ exec_url }}";
const messagesUrl = "{{ msg_url }}"; const messagesUrl = "{{ msg_url }}";
const flowBody = document.querySelector("#flow-body");
const spinner = document.querySelector(".pb-loading");
const updateMessages = () => { const updateMessages = () => {
let messageContainer = document.querySelector(".pf-c-alert-group"); let messageContainer = document.querySelector(".pf-c-alert-group");
fetch(messagesUrl).then(response => { fetch(messagesUrl).then(response => {
@ -79,77 +70,8 @@ const updateMessages = () => {
}); });
}); });
}; };
const updateCard = (data) => {
switch (data.type) {
case "redirect":
window.location = data.to
break;
case "template":
flowBody.innerHTML = data.body;
checkAutofocus();
updateMessages();
loadFormCode();
setFormSubmitHandlers();
default:
break;
}
};
const showSpinner = () => {
flowBody.innerHTML = "";
flowBody.appendChild(spinner);
};
const loadFormCode = () => {
document.querySelectorAll("#flow-body script").forEach(script => {
let newScript = document.createElement("script");
newScript.src = script.src;
document.head.appendChild(newScript);
});
};
const checkAutofocus = () => {
const autofocusElement = document.querySelector("#flow-body [autofocus]");
if (autofocusElement !== null) {
autofocusElement.focus();
}
};
const updateFormAction = (form) => {
for (let index = 0; index < form.elements.length; index++) {
const element = form.elements[index];
if (element.value === form.action) {
console.log("pb-flow: Found Form action URL in form elements, not changing form action.");
return false;
}
}
form.action = flowBodyUrl;
console.log(`pb-flow: updated form.action ${flowBodyUrl}`);
return true;
};
const checkAutosubmit = (form) => {
if ("autosubmit" in form.attributes) {
return form.submit();
}
};
const setFormSubmitHandlers = () => {
document.querySelectorAll("#flow-body form").forEach(form => {
console.log(`pb-flow: Checking for autosubmit attribute ${form}`);
checkAutosubmit(form);
console.log(`pb-flow: Setting action for form ${form}`);
updateFormAction(form);
console.log(`pb-flow: Adding handler for form ${form}`);
form.addEventListener('submit', (e) => {
e.preventDefault();
let formData = new FormData(form);
showSpinner();
fetch(flowBodyUrl, {
method: 'post',
body: formData,
}).then(response => response.json()).then(data => {
updateCard(data);
});
});
form.classList.add("pb-flow-wrapped");
});
};
fetch(flowBodyUrl).then(response => response.json()).then(data => updateCard(data));
// fetch(flowBodyUrl).then(response => response.json()).then(data => updateCard(data));
</script> </script>
{% endblock %} {% endblock %}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,113 @@
import { LitElement, html } from 'lit-element';
class FetchFillSlot extends LitElement {
static get properties() {
return {
flowBodyUrl: { type: String },
flowBody: { type: String },
};
}
createRenderRoot() {
return this;
}
firstUpdated() {
fetch(this.flowBodyUrl).then(r => r.json()).then(r => this.updateCard(r));
}
async updateCard(data) {
switch (data.type) {
case "redirect":
window.location = data.to
break;
case "template":
this.flowBody = data.body;
await this.requestUpdate();
this.checkAutofocus();
// this.updateMessages();
this.loadFormCode();
this.setFormSubmitHandlers();
default:
break;
}
};
loadFormCode() {
this.querySelectorAll("script").forEach(script => {
let newScript = document.createElement("script");
newScript.src = script.src;
document.head.appendChild(newScript);
});
}
checkAutofocus() {
const autofocusElement = this.querySelector("[autofocus]");
if (autofocusElement !== null) {
autofocusElement.focus();
}
}
updateFormAction(form) {
for (let index = 0; index < form.elements.length; index++) {
const element = form.elements[index];
if (element.value === form.action) {
console.log("pb-flow: Found Form action URL in form elements, not changing form action.");
return false;
}
}
form.action = this.flowBodyUrl;
console.log(`pb-flow: updated form.action ${this.flowBodyUrl}`);
return true;
}
checkAutosubmit(form) {
if ("autosubmit" in form.attributes) {
return form.submit();
}
}
setFormSubmitHandlers() {
this.querySelectorAll("form").forEach(form => {
console.log(`pb-flow: Checking for autosubmit attribute ${form}`);
this.checkAutosubmit(form);
console.log(`pb-flow: Setting action for form ${form}`);
this.updateFormAction(form);
console.log(`pb-flow: Adding handler for form ${form}`);
form.addEventListener('submit', (e) => {
e.preventDefault();
let formData = new FormData(form);
this.flowBody = undefined;
fetch(this.flowBodyUrl, {
method: 'post',
body: formData,
}).then(response => response.json()).then(data => {
this.updateCard(data);
});
});
form.classList.add("pb-flow-wrapped");
});
}
loading() {
return html`
<div class="pf-c-login__main-body pb-loading">
<span class="pf-c-spinner" role="progressbar" aria-valuetext="Loading...">
<span class="pf-c-spinner__clipper"></span>
<span class="pf-c-spinner__lead-ball"></span>
<span class="pf-c-spinner__tail-ball"></span>
</span>
</div>`;
}
render() {
if (this.flowBody !== undefined) {
// return html`<main class="pf-c-login__main">${unsafeHTML(this.flowBody)}</div>`;
return html([this.flowBody]);
}
return this.loading();
}
}
customElements.define('flow-shell-card', FetchFillSlot);

View File

@ -1,4 +1,5 @@
import './FetchFillSlot.js'; import './FetchFillSlot.js';
import './FlowShellCard.js';
// Button Dropdowns // Button Dropdowns
document.querySelectorAll("button.pf-c-dropdown__toggle").forEach((b) => { document.querySelectorAll("button.pf-c-dropdown__toggle").forEach((b) => {