diff --git a/src/UI/Components/Button.js b/src/UI/Components/Button.js deleted file mode 100644 index 662652db..00000000 --- a/src/UI/Components/Button.js +++ /dev/null @@ -1,18 +0,0 @@ -export default class Button extends Component { - static PROPERTIES = { - label_key: { - description: 'The key to use to look up the label for the button', - }, - click: { - description: 'The function to call when the button is clicked', - }, - } - - create_template ({ template }) { - $(template).html(` - - `); - } -} \ No newline at end of file diff --git a/src/UI/Components/CodeEntryView.js b/src/UI/Components/CodeEntryView.js index d016de1f..48c590f7 100644 --- a/src/UI/Components/CodeEntryView.js +++ b/src/UI/Components/CodeEntryView.js @@ -76,8 +76,8 @@ export default class CodeEntryView extends Component { e.preventDefault(); e.stopPropagation(); - $(this.dom_).find('.code-confirm-btn').prop('disabled', true); - $(this.dom_).find('.error').hide(); + $(this).prop('disabled', true); + $(this).closest('.error').hide(); // Check if already checking code to prevent multiple requests if(is_checking_code) @@ -86,7 +86,7 @@ export default class CodeEntryView extends Component { is_checking_code = true; // set animation - $(this.dom_).find('.code-confirm-btn').html(`circle anim`); + $(this).html(`circle anim`); }) // Elements @@ -126,10 +126,10 @@ export default class CodeEntryView extends Component { for(let i=0; i< numberCodeInputs.length; i++){ current_code += numberCodeInputs[i].value; } - this.set('value', current_code); // Automatically submit if 6 digits entered if(current_code.length === 6){ + this.set('value', current_code); $(this.dom_).find('.code-confirm-btn').prop('disabled', false); $(this.dom_).find('.code-confirm-btn').trigger('click'); } diff --git a/src/UI/Components/Flexer.js b/src/UI/Components/Flexer.js index aaf6cd0e..dd53a34f 100644 --- a/src/UI/Components/Flexer.js +++ b/src/UI/Components/Flexer.js @@ -19,7 +19,6 @@ export default class Flexer extends Component { on_ready () { console.log('Flexer on_ready called'); - debugger; for ( const child of this.get('children') ) { child.setAttribute('slot', 'inside'); child.attach(this); diff --git a/src/UI/Components/QRCode.js b/src/UI/Components/QRCode.js index 7562a60a..b966a2fc 100644 --- a/src/UI/Components/QRCode.js +++ b/src/UI/Components/QRCode.js @@ -18,8 +18,6 @@ export default class QRCodeView extends Component { ` create_template ({ template }) { - // TODO: The way we handle loading assets doesn't work well - // with web components, so for now it goes in the template. $(template).html(`
diff --git a/src/UI/Components/StepView.js b/src/UI/Components/StepView.js new file mode 100644 index 00000000..4f8dadec --- /dev/null +++ b/src/UI/Components/StepView.js @@ -0,0 +1,67 @@ +import { Component } from "../../util/Component.js"; + +export default class StepView extends Component { + static PROPERTIES = { + children: {}, + done: { value: false }, + position: { value: 0 }, + } + + static CSS = ` + #wrapper { display: none } + `; + + create_template ({ template }) { + $(template).html(` +
+ +
+ `); + } + + on_ready ({ listen }) { + for ( const child of this.get('children') ) { + child.setAttribute('slot', 'inside'); + child.attach(this); + $(child).hide(); + } + + // show the first child + $(this.children[0]).show(); + + // listen for changes to the current step + listen('position', position => { + // hide all children + for ( const child of this.children ) { + $(child).hide(); + } + + // show the child at the current position + $(this.children[position]).show(); + }); + + // now that we're ready, show the wrapper + $(this.dom_).find('#wrapper').show(); + } + + back () { + if ( this.get('position') === 0 ) return; + this.set('position', this.get('position') - 1); + } + + next () { + if ( this.get('position') === this.children.length - 1 ) { + this.set('done', true); + return; + } + this.set('position', this.get('position') + 1); + } +} + +// TODO: This is necessary because files can be loaded from +// both `/src/UI` and `/UI` in the URL; we need to fix that +if ( ! window.__component_stepView ) { + window.__component_stepView = true; + + customElements.define('c-step-view', StepView); +} diff --git a/src/UI/Components/TestView.js b/src/UI/Components/TestView.js new file mode 100644 index 00000000..b6b7dae9 --- /dev/null +++ b/src/UI/Components/TestView.js @@ -0,0 +1,28 @@ +import { Component } from "../../util/Component.js"; + +/** + * A simple component when you just need to test something. + */ +export default class TestView extends Component { + static CSS = ` + div { + background-color: lightblue; + padding: 1em; + border-radius: 0.5em; + } + `; + + create_template ({ template }) { + $(template).html(` +
I am a test view
+ `); + } +} + +// TODO: This is necessary because files can be loaded from +// both `/src/UI` and `/UI` in the URL; we need to fix that +if ( ! window.__component_testView ) { + window.__component_testView = true; + + customElements.define('c-test-view', TestView); +} diff --git a/src/UI/UIWindow2FASetup.js b/src/UI/UIWindow2FASetup.js index 45286b22..882f391e 100644 --- a/src/UI/UIWindow2FASetup.js +++ b/src/UI/UIWindow2FASetup.js @@ -22,6 +22,8 @@ import CodeEntryView from "./Components/CodeEntryView.js"; import Flexer from "./Components/Flexer.js"; import QRCodeView from "./Components/QRCode.js"; +import StepView from "./Components/StepView.js"; +import TestView from "./Components/TestView.js"; import UIComponentWindow from "./UIComponentWindow.js"; const UIWindow2FASetup = async function UIWindow2FASetup () { @@ -35,18 +37,29 @@ const UIWindow2FASetup = async function UIWindow2FASetup () { }); const data = await resp.json(); - const component = new Flexer({ - children: [ - new QRCodeView({ - value: data.url, - }), - new CodeEntryView({ - on_update () { - // NEXT - } - }), - ] - }); + let stepper; + const component = + new StepView({ + _ref: me => stepper = me, + children: [ + new Flexer({ + children: [ + new QRCodeView({ + value: data.url, + }), + new CodeEntryView({ + [`property.value`] (value) { + console.log('value? ', value) + stepper.next(); + } + }), + new TestView(), + ] + }), + new TestView(), + ] + }) + ; UIComponentWindow({ component, diff --git a/src/util/Component.js b/src/util/Component.js index 77579610..3e9e6d28 100644 --- a/src/util/Component.js +++ b/src/util/Component.js @@ -24,8 +24,20 @@ export class Component extends HTMLElement { let initial_value; if ( property_values && key in property_values ) { initial_value = property_values[key]; + } else if ( this.constructor.PROPERTIES[key].value !== undefined ) { + initial_value = this.constructor.PROPERTIES[key].value; } this.values_[key] = ValueHolder.adapt(initial_value); + + const listener_key = `property.${key}`; + if ( property_values[listener_key] ) { + this.values_[key].sub(property_values[listener_key]); + } + } + + // Convenience for setting a property while composing components + if ( property_values && property_values.hasOwnProperty('_ref') ) { + property_values._ref(this); } }