import {OOElement} from '../oo-element' import {html} from '../../lib/html' import stepSignIn from '../_organisms/oo-organisms-ask-step-sign-in' import askForm from '../oo-ask-form' import define from '../../lib/define' import createProject from '../../lib/oo-api-create-project' import weakMap from '../../lib/weak-map' import {HTMLElementEventChangeAsk, ProjectCreatedDetail, ProjectCreated} from '../../type/event' import {Scope} from '../../type/scope' import customEvent from '../../lib/custom-event' import {asTags, asScope, asSignInFlow} from '../../lib/as' import {SignInFlow} from '../../type/sign-in-flow' import {Currency} from '../../type/currency' define('oo-organisms-ask-step-sign-in', stepSignIn) define('oo-ask-form', askForm) const ATTR = { DATA_IAM: 'data-iam', DATA_TAGS: 'data-tags', DATA_SCOPE: 'data-scope', DATA_SIGN_IN_FLOW: 'data-sign-in-flow' } const EVENT = { PROJECT_CREATED: (detail: ProjectCreatedDetail): ProjectCreated => customEvent('projectcreated', detail), PROJECT_CREATION_FAILED: detail => customEvent('projectcreationfailed', detail) } const stateIam = weakMap() const stateTitle = weakMap() const stateMessage = weakMap() const stateOfferer = weakMap() const stateScope = weakMap() const stateCurrency = weakMap() const stateTags = weakMap>() const stateAuthorized = weakMap() const stateSignInFlow = weakMap() const statePrevActiveStep = weakMap() const stateProgress = weakMap() const validation = (el: HTMLElement): boolean => { const body = stateMessage.get(el) if (body === undefined || body.match(/./) === null) { return false } const author = stateOfferer.get(el) if (author === undefined) { return false } return true } const fitHeight = (el: HTMLElement, target: HTMLElement): boolean => { const height = el.offsetHeight if (height > 0) { target.style.height = `${height}px` return true } return false } export default class extends OOElement { static get observedAttributes() { return [ATTR.DATA_IAM, ATTR.DATA_SCOPE, ATTR.DATA_TAGS, ATTR.DATA_SIGN_IN_FLOW] } constructor() { super() stateAuthorized.set(this, false) } attributeChangedCallback(attr, prev, next) { if (prev === next) { return } switch(attr) { case ATTR.DATA_IAM: stateIam.set(this, next) break case ATTR.DATA_TAGS: stateTags.set(this, asTags(next)) break case ATTR.DATA_SCOPE: stateScope.set(this, asScope(next)) break case ATTR.DATA_SIGN_IN_FLOW: stateSignInFlow.set(this, asSignInFlow(next)) break default: break } if (this.connected) { this.update() } } render() { const uid = stateIam.get(this) const auth = stateAuthorized.get(this) const sender = stateOfferer.get(this) const flow = stateSignInFlow.get(this) const progress = stateProgress.get(this) const scope = stateScope.get(this) const tags = stateTags.get(this) || [] const step = (() => { if (sender !== undefined && sender !== '') { return 'submit' } return auth ? 'signin' : 'ask' })() const doOverflowHidden = step === 'ask' || step === 'signin' return html`
  • Next step: Authenticate account with Google, Facebook or GitHub.

` } async renderedCallback() { const items = this.shadowRoot.querySelector('.steps ul') if (items) { const item = this.shadowRoot.querySelector('.step[active]') if (statePrevActiveStep.get(this) !== item) { statePrevActiveStep.set(this, item) let fit = false let count = 100 while(!fit && count > 0) { fit = fitHeight(item as HTMLElement, items as HTMLElement) count -= 1 await new Promise(resolve => setTimeout(resolve, 10)) } } } } onAskChanged(e: HTMLElementEventChangeAsk) { const {detail} = e const {title, message: m, tags, scope, currency} = detail stateTitle.set(this, title) stateMessage.set(this, m) stateTags.set(this, tags) stateScope.set(this, scope) stateCurrency.set(this, currency) } onAuthorization() { stateAuthorized.set(this, true) this.update() } onSignedIn(e: CustomEvent) { const {detail} = e const {uid} = detail stateOfferer.set(this, uid) this.update() } async createProject() { if (validation(this) === false) { return } stateProgress.set(this, true) this.update() const iam = stateIam.get(this) const offerer = stateOfferer.get(this) const title = stateTitle.get(this) const body = stateMessage.get(this) const tags = stateTags.get(this) const currency = stateCurrency.get(this) const author = stateOfferer.get(this) const scope = stateScope.get(this) const opts: { body: string, author: string, scope: Scope, title?: string, users?: Array, tags?: Array, assignee?: string, currency?: Currency } = { body, author, scope } if (typeof title === 'string') { opts.title = title } if (typeof iam === 'string' && iam !== '') { opts.assignee = iam if (typeof offerer === 'string' && offerer !== '') { opts.users = [iam, offerer] } } if (Array.isArray(tags)) { opts.tags = tags } if (currency) { opts.currency = currency } const project = await createProject(opts) const {response} = project if (Array.isArray(response)) { this.dispatchEvent(EVENT.PROJECT_CREATED(project)) } else { this.dispatchEvent(EVENT.PROJECT_CREATION_FAILED(project)) } stateProgress.set(this, false) this.update() } }