import * as aws from "@pulumi/aws" ; import * as pulumi from "@pulumi/pulumi" ; import { Widget } from "./widget" ; import { WidgetJson } from "./widgets_json" ; interface WidgetRelativePosition { /** x-position of this widget, relative to the x-position of its container. */ relativeX : number ; /** y-position of this widget, relative to the y-position of its container. */ relativeY : number ; } /**
 * A sequence of widgets flowing either horizontally or vertically.  Widgets flowing horizontally
 * must wrap after 24 grid columns.  There is no effective vertical limit on widgets flowing
 * vertically.
 */ export abstract class FlowWidget implements Widget { protected readonly widgets : Widget [ ] = [ ] ; constructor ( ... widgets ) { for ( const widget of widgets ) { this . addWidget ( widget ) ; } } public addWidget ( widget ) { this . widgets . push ( widget ) ; } /**
     * Determines the relative positions of all the child widgets in this [FlowWidget]. 'Relative
     * Position' tells us where the widget should be placed relative to the upper-left point of this
     * FlowWidget.
     */ protected abstract getWidgetRelativePositions ( ) ; public width ( ) { let width = 0 ; const positions = this . getWidgetRelativePositions ( ) ; for ( const [ widget , dimension ] of positions ) { width = Math . max ( width , dimension . relativeX + widget . width ( ) ) ; } return width ; } public height ( ) { let height = 0 ; const positions = this . getWidgetRelativePositions ( ) ; for ( const [ widget , dimension ] of positions ) { height = Math . max ( height , dimension . relativeY + widget . height ( ) ) ; } return height ; } /** For internal use only. */ public addWidgetJson ( widgetJsons , xOffset , yOffset , region ) { for ( const [ widget , dimension ] of this . getWidgetRelativePositions ( ) ) { widget . addWidgetJson ( widgetJsons , xOffset + dimension . relativeX , yOffset + dimension . relativeY , region ) ; } } } /**
 * Represents a vertical sequence of [Widget]s in the [Dashboard].  There is no limit on how long
 * this sequence will be.
 *
 * The final width of this widget will be the width of the largest item in the column. The final
 * height of this widget will be the sum of all the heights of all the widgets in the column.
 */ export class ColumnWidget extends FlowWidget { constructor ( ... widgets ) { super ( ... widgets ) ; } protected getWidgetRelativePositions ( ) { const result = new Map < Widget , WidgetRelativePosition > ( ) ; const relativeX = 0 ; let relativeY = 0 ; for ( const widget of this . widgets ) { const widgetHeight = widget . height ( ) ; result . set ( widget , { relativeX , relativeY } ) ; relativeY += widgetHeight ; } return result ; } } /**
 * Represents a horizontal sequence of [Widget]s in the [Dashboard].  Widgets are laid out
 * horizontally in the grid until it would go past the max width of 24 columns.  When that happens,
 * the widgets will wrap to the next available grid row.
 *
 * Rows must start in the leftmost grid column.
 *
 * The final width of this widget will be the furthest column that a widget is placed at prior to
 * wrapping. The final height of this widget will be the bottommost row that a widget is placed at.
 */ export class RowWidget extends FlowWidget { constructor ( ... widgets ) { super ( ... widgets ) ; } protected getWidgetRelativePositions ( ) { const result = new Map < Widget , WidgetRelativePosition > ( ) ; const maxWidth = 24 ; let height = 0 ; let relativeX = 0 ; let relativeY = 0 ; for ( const widget of this . widgets ) { const widgetHeight = widget . height ( ) ; const widgetWidth = widget . width ( ) ; if ( widgetWidth > maxWidth ) { throw new Error ( `Widget width cannot be greater than ${ maxWidth }.` ) ; } if ( relativeX + widgetWidth > maxWidth ) { relativeX = 0 ; relativeY = height ; } height = Math . max ( height , relativeY + widgetHeight ) ; result . set ( widget , { relativeX , relativeY } ) ; relativeX += widgetWidth ; } return result ; } /** For internal use only. */ public addWidgetJson ( widgetJsons , xOffset , yOffset , region ) { if ( xOffset !== 0 ) { throw new Error ( `A RowWidget must be placed in the leftmost grid column: ${ xOffset }` ) ; } return super . addWidgetJson ( widgetJsons , xOffset , yOffset , region ) ; } }