import './scenario-instance-log-view.js' import gql from 'graphql-tag' import { css, html, LitElement } from 'lit' import { customElement, property, query } from 'lit/decorators.js' import { subscribe } from '@operato/graphql' import { AppController } from '@operato/shell' import { ScrollbarStyles } from '@operato/styles' @customElement('scenario-instance-view') export class ScenarioInstanceView extends LitElement { static styles = [ ScrollbarStyles, css` :host { display: flex; flex-direction: column; background-color: var(--md-sys-color-background); } [diagram] { flex: 1; height: 100%; border: none; } [content] { flex: 1; display: flex; flex-direction: column; overflow: hidden; } [tab] { display: flex; } [tab] span { display: inline; padding: var(--spacing-large) var(--spacing-large) var(--spacing-small) var(--spacing-large); border-bottom: 3px solid transparent; color: var(--md-sys-color-secondary); text-transform: capitalize; } [tab] span[active] { border-color: var(--md-sys-color-primary); font-weight: bold; } [detail] { flex: 1; background-color: var(--md-sys-color-surface); border-top: var(--border-dim-color); overflow: hidden; padding: var(--spacing-large); } [detail] > * { display: none; width: 100%; height: 100%; color: var(--md-sys-color-secondary); } [detail] > [active] { display: flex; overflow: auto; } pre { margin: 0; } [detail] ul { margin: 0; padding: 0; flex: 1; list-style: inside '- '; } [detail] li { padding: var(--spacing-medium) var(--spacing-small) var(--spacing-small) var(--spacing-small); border-bottom: var(--border-dim-color); } li[active] { font-weight: bold; } [value] { flex: 1; overflow: auto; padding: var(--spacing-large); } scenario-instance-log-view [active] { padding: 0; } @media only screen and (max-width: 460px) { [info][active] { display: block; } [detail] { padding: var(--spacing-medium); overflow: auto; } [detail] > * { height: auto; } [diagram] { width: 100%; min-height: 500px; } } ` ] @property({ type: String }) scenarioName?: string @property({ type: String }) instanceName?: string @property({ type: Object }) instance?: any @property({ type: String }) tab?: string @property({ type: String }) step?: string @property({ type: String }) key?: string private _appCtrl = new AppController(this) subscription: any render() { const tab = this.tab || 'info' const { scenarioName, instanceName, description, state, progress, variables, data, message } = this.instance || {} const { rate = 0, steps = 0, step = 0, rounds = 0 } = progress || {} const diagram = `${this._appCtrl.contextPath || ''}/scenario-view/${this.scenarioName}` return html`
(this.tab = 'info')} ?active=${tab == 'info'}>info (this.tab = 'variables')} ?active=${tab == 'variables'}>variables (this.tab = 'data')} ?active=${tab == 'data'}>data (this.tab = 'log')} ?active=${tab == 'log'}>log
  • scenario name : ${scenarioName}
  • instance name : ${instanceName}
  • description : ${description}
  • state : ${state}
  • total steps : ${steps}
  • current step : ${step}
  • rounds : ${rounds}
  • messge : ${message}
${this.renderVariableObject(variables)}
${this.renderDataObject(data)}
` } firstUpdated() { this.startSubscribe() } disconnectedCallback() { super.disconnectedCallback() this.stopSubscribe() } renderDataObject(data) { const keys = Object.keys(data || {}) if (keys.length == 0) { return html`
no data
` } const currentStep = this.step || keys[0] return html`
${data[currentStep] ? JSON.stringify(data[currentStep], null, 2) : ''}
` } renderVariableObject(data) { const keys = Object.keys(data || {}) if (keys.length == 0) { return html`
no data
` } const currentKey = this.key || keys[0] return html`
${data[currentKey] ? JSON.stringify(data[currentKey], null, 2) : ''}
` } async startSubscribe() { this.subscription = await subscribe( { query: gql` subscription ($instanceName: String, $scenarioName: String) { scenarioInstanceState(instanceName: $instanceName, scenarioName: $scenarioName) { instanceName scenarioName state progress { rate steps step rounds } variables data } } `, variables: { instanceName: this.instanceName, scenarioName: this.scenarioName } }, { next: async ({ data }) => { data && (this.instance = data.scenarioInstanceState) } } ) } async stopSubscribe() { await this.subscription?.unsubscribe() delete this.subscription } }