From 5e325a6dd5a3934c74652051ab08305e0626935f Mon Sep 17 00:00:00 2001 From: "Daniel A. Bekan" Date: Tue, 5 Sep 2023 15:41:11 +0200 Subject: [PATCH 1/5] WIP: Table view for types --- cli/src/Morphir/Web/DevelopApp.elm | 28 ++ elm.json | 1 + src/Morphir/Visual/Components/TableView.elm | 335 ++++++++++++++++++ .../Visual/Components/TreeViewComponent.elm | 2 +- .../Reference/Model/TestModel/testing.elm | 173 ++++++++- 5 files changed, 520 insertions(+), 19 deletions(-) create mode 100644 src/Morphir/Visual/Components/TableView.elm diff --git a/cli/src/Morphir/Web/DevelopApp.elm b/cli/src/Morphir/Web/DevelopApp.elm index 80521be54..6f000ab29 100644 --- a/cli/src/Morphir/Web/DevelopApp.elm +++ b/cli/src/Morphir/Web/DevelopApp.elm @@ -78,6 +78,7 @@ import Morphir.Visual.Components.InputComponent as InputComponent import Morphir.Visual.Components.ModalComponent exposing (attachModal) import Morphir.Visual.Components.SectionComponent as SectionComponent import Morphir.Visual.Components.SelectableElement as SelectableElement +import Morphir.Visual.Components.TableView as TableView import Morphir.Visual.Components.TabsComponent as TabsComponent import Morphir.Visual.Components.TreeViewComponent as TreeViewComponent import Morphir.Visual.Config exposing (DrillDownFunctions(..), ExpressionTreePath, PopupScreenRecord, addToDrillDown, removeFromDrillDown) @@ -139,6 +140,7 @@ type alias Model = , modalContent : Element Msg , version : String , showSaveTestError : Bool + , tableViewConfig : TableView.Config Msg } @@ -228,6 +230,10 @@ init flags url key = , modalContent = none , version = flags.version , showSaveTestError = False + , tableViewConfig = + { state = TableView.init + , onStateChange = TableViewChanged + } } in ( toRoute url initModel @@ -268,6 +274,7 @@ type Msg | Insight InsightMsg | Testing TestingMsg | Decoration DecorationMsg + | TableViewChanged TableView.State | DoNothing @@ -731,6 +738,14 @@ update msg model = DoNothing -> ( model, Cmd.none ) + TableViewChanged newTableViewState -> + let + tableViewConfig : TableView.Config Msg + tableViewConfig = + model.tableViewConfig + in + ( { model | tableViewConfig = { tableViewConfig | state = newTableViewState } }, Cmd.none ) + -- SUBSCRIPTIONS @@ -1435,6 +1450,19 @@ viewHome model packageName packageDef = in col decorationTabContent } + , { name = "Type Table" + , content = + col + [ TableView.viewTypeTable + model.theme + model.tableViewConfig + packageName + packageDef + (model.homeState.selectedModule |> Maybe.map Tuple.second) + model.allDecorationConfigAndData + + ] + } ] } in diff --git a/elm.json b/elm.json index 536d21fd5..99e6d6729 100644 --- a/elm.json +++ b/elm.json @@ -78,6 +78,7 @@ "fabhof/elm-ui-datepicker": "5.0.0 <= v < 6.0.0", "justinmimbs/date": "3.2.1 <= v < 4.0.0", "lattyware/elm-fontawesome": "6.0.0 <= v < 7.0.0", + "matthewsj/elm-ordering": "2.0.0 <= v < 3.0.0", "mdgriffith/elm-ui": "1.1.8 <= v < 2.0.0", "pzp1997/assoc-list": "1.0.0 <= v < 2.0.0", "rtfeldman/elm-iso8601-date-strings": "1.1.4 <= v < 2.0.0", diff --git a/src/Morphir/Visual/Components/TableView.elm b/src/Morphir/Visual/Components/TableView.elm new file mode 100644 index 000000000..0923dc415 --- /dev/null +++ b/src/Morphir/Visual/Components/TableView.elm @@ -0,0 +1,335 @@ +module Morphir.Visual.Components.TableView exposing (..) + +import Dict exposing (Dict) +import Element exposing (Element, el, fill, fillPortion, height, padding, paddingXY, pointer, scrollbars, spacing, spacingXY, text, width) +import Element.Background +import Element.Border +import Element.Events exposing (onClick) +import Element.Font as Font +import Element.Input +import Morphir.Elm.ParsedModule exposing (documentation) +import Morphir.IR.Decoration exposing (AllDecorationConfigAndData, DecorationConfigAndData, DecorationID) +import Morphir.IR.Documented exposing (Documented) +import Morphir.IR.Name as Name exposing (Name) +import Morphir.IR.NodeId exposing (NodeID(..)) +import Morphir.IR.Package as Package exposing (PackageName) +import Morphir.IR.Path as Path exposing (Path) +import Morphir.IR.Type as Type +import Morphir.IR.Value as Value exposing (RawValue) +import Morphir.SDK.Dict as SDKDict +import Morphir.Visual.Common exposing (nameToTitleText, tooltip) +import Morphir.Visual.Components.InputComponent as InputComponent +import Morphir.Visual.Theme as Theme exposing (Theme) +import Ordering exposing (Ordering) + + +type alias State = + { orderByColumnIndex : Int + , ordering : Ordering Row + , orderDirection : OrderDirection + , searchTerms : SearchTerms + } + + +type alias Config msg = + { state : State + , onStateChange : State -> msg + } + + +type alias Column msg = + { columnName : String + , ordering : Ordering Row + , view : Row -> Element msg + , filtering : String -> Row -> Bool + } + + +type alias Row = + { typeName : Name + , morphirModule : Path + , baseType : Type.Definition () + , documentation : String + , decorations : Dict DecorationID (Maybe RawValue) + } + + +type alias SearchTerms = + Dict Int String + + +type Msg + = SetOrdering Int (Ordering Row) + | Search Int String + + +type OrderDirection + = Asc + | Desc + + +init : State +init = + { orderByColumnIndex = 0 + , ordering = Ordering.byField .typeName + , orderDirection = Desc + , searchTerms = Dict.empty + } + + +update : Msg -> State -> State +update msg state = + case msg of + SetOrdering index ordering -> + let + reverseDirection dir = + if dir == Asc then + Desc + + else + Asc + in + if index == state.orderByColumnIndex then + { state + | ordering = Ordering.reverse state.ordering + , orderDirection = reverseDirection state.orderDirection + } + + else + { state + | ordering = ordering + , orderByColumnIndex = index + , orderDirection = Desc + } + + Search index term -> + { state | searchTerms = Dict.insert index term state.searchTerms } + + +viewTypeTable : Theme -> Config msg -> PackageName -> Package.Definition () va -> Maybe Path -> AllDecorationConfigAndData -> Element msg +viewTypeTable theme config packageName package moduleName allDecorationsConfigAndData = + let + typeDefToString : Type.Definition () -> String + typeDefToString tpe = + case tpe of + Type.CustomTypeDefinition _ accessControlledCtors -> + "Enum" + + Type.TypeAliasDefinition _ baseType -> + let + typeToString : Type.Type a -> String + typeToString t = + case t of + Type.Variable _ name -> + Name.toCamelCase name + + Type.Reference _ ( _, mn, ln ) args -> + let + referenceName : String + referenceName = + String.join "." + [ Path.toString Name.toTitleCase "." mn + , Name.toTitleCase ln + ] + in + referenceName + :: List.map typeToString args + |> String.join " " + + Type.Tuple _ elems -> + String.concat + [ "(", List.map typeToString elems |> String.join ", ", ")" ] + + Type.Record _ fields -> + "Record" + + Type.ExtensibleRecord _ varName fields -> + "Extensible Record" + + Type.Function _ ((Type.Function _ _ _) as argType) returnType -> + String.concat [ "(", typeToString argType, ") -> ", typeToString returnType ] + + Type.Function _ argType returnType -> + String.concat [ typeToString argType, " -> ", typeToString returnType ] + + Type.Unit _ -> + "()" + in + typeToString baseType + + decorations : List ( DecorationID, DecorationConfigAndData ) + decorations = + allDecorationsConfigAndData |> Dict.toList + + types : List Row + types = + let + typeListToRows moduleN accessControlledModuleDef = + let + toRow : Name -> Path -> Type.Definition () -> String -> Row + toRow name modulePath baseType documentation = + let + nodeId = + TypeID ( packageName, modulePath, name ) [] + in + { typeName = name + , morphirModule = modulePath + , baseType = baseType + , documentation = documentation + , decorations = decorations |> List.map (\( decorationId, configAndData ) -> ( decorationId, SDKDict.get nodeId configAndData.data )) |> Dict.fromList + } + in + accessControlledModuleDef.value.types + |> Dict.toList + |> List.map + (\( name, accessControlledDocumentedType ) -> toRow name moduleN accessControlledDocumentedType.value.value accessControlledDocumentedType.value.doc) + + everyTypeWithPath = + package.modules |> Dict.toList + in + case moduleName of + Nothing -> + everyTypeWithPath + |> List.concatMap + (\( mn, accessControlledModuleDef ) -> + typeListToRows mn accessControlledModuleDef + ) + + Just selectedMn -> + everyTypeWithPath + |> List.filter (\( currentMn, _ ) -> Path.isPrefixOf currentMn selectedMn) + |> List.concatMap + (\( mn, accessControlledModuleDef ) -> + typeListToRows mn accessControlledModuleDef + ) + + rowElem : Element msg -> Element msg + rowElem = + el [ Theme.borderBottom 1, Element.Border.color theme.colors.lightGray, paddingXY 2 1 ] + + searchIn : String -> String -> Bool + searchIn string term = + String.contains (String.toUpper term) (String.toUpper string) + + searchFunction : Row -> Bool + searchFunction row = + columns + |> List.indexedMap (\index col -> col.filtering (Dict.get index config.state.searchTerms |> Maybe.withDefault "")) + |> List.all (\predicate -> predicate row) + + decorationColumns : List (Column msg) + decorationColumns = + decorations + |> List.map + (\( id, configAndData ) -> + { columnName = configAndData.displayName + , ordering = + \a b -> + case ( Dict.get id a.decorations, Dict.get id b.decorations ) of + ( Just (Just aVal), Just (Just bVal) ) -> + Basics.compare (Value.toString aVal) (Value.toString bVal) + + ( Just Nothing, Just (Just _) ) -> + GT + + _ -> + LT + , view = + \row -> + case Dict.get id row.decorations of + Just (Just val) -> + rowElem <| Theme.ellipseText <| Value.toString val + + _ -> + rowElem <| text "-" + , filtering = + \term row -> + case Dict.get id row.decorations of + Just (Just val) -> + searchIn (Value.toString val) term + + _ -> + String.isEmpty term + } + ) + + columns : List (Column msg) + columns = + [ { columnName = "Name" + , ordering = Ordering.byField .typeName + , view = + \row -> + rowElem <| + el + [ tooltip Element.below + (el + [ Element.Background.color theme.colors.lightest + , theme |> Theme.borderRounded + , Element.Border.shadow + { offset = ( 0, 3 ), blur = 6, size = 0, color = Element.rgba 0 0 0 0.32 } + ] + (text row.documentation) + ) + ] + (text (nameToTitleText row.typeName)) + , filtering = \term row -> searchIn (row.typeName |> nameToTitleText) term + } + , { columnName = "Module" + , ordering = Ordering.byField .morphirModule + , view = \row -> rowElem <| text (Path.toString nameToTitleText " > " row.morphirModule) + , filtering = \term row -> searchIn (Path.toString nameToTitleText " > " row.morphirModule) term + } + , { columnName = "Base Type" + , ordering = \a b -> Basics.compare (typeDefToString a.baseType) (typeDefToString b.baseType) + , view = \row -> rowElem <| text <| typeDefToString row.baseType + , filtering = \term row -> searchIn (typeDefToString row.baseType) term + } + ] + ++ decorationColumns + + header : String -> Int -> Ordering Row -> Element msg + header title index ordering = + Element.row [ spacing <| Theme.smallSpacing theme, Element.paddingEach { right = Theme.mediumPadding theme, left = 0, bottom = 0, top = 0 } ] + [ Element.row + [ paddingXY 2 (Theme.largePadding theme) + , Font.color theme.colors.mediumGray + , onClick <| config.onStateChange (update (SetOrdering index ordering) config.state) + , Element.Background.color theme.colors.lightest + , pointer + , width (fillPortion 1) + ] + [ text title + , if index == config.state.orderByColumnIndex then + el [ Font.color theme.colors.brandPrimary, Font.size (Theme.scaled 4 theme), Font.bold ] + (case config.state.orderDirection of + Desc -> + text " ⇩" + + _ -> + text " ⇧" + ) + + else + Element.none + ] + , InputComponent.searchInput theme + [ width (Element.px 180) ] + { onChange = \term -> config.onStateChange (update (Search index term) config.state) + , text = Dict.get index config.state.searchTerms |> Maybe.withDefault "" + , placeholder = Just <| Element.Input.placeholder [] (text "search . . .") + , label = Element.Input.labelHidden "" + } + ] + in + Element.table + [ width fill + , height fill + , Element.clipY + , scrollbars + , padding (Theme.mediumPadding theme) + , spacingXY 0 (Theme.mediumSpacing theme) + ] + { columns = + columns |> List.indexedMap (\index column -> { header = header column.columnName index column.ordering, width = Element.fillPortion 1, view = column.view }) + , data = types |> List.sortWith config.state.ordering |> List.filter searchFunction + } diff --git a/src/Morphir/Visual/Components/TreeViewComponent.elm b/src/Morphir/Visual/Components/TreeViewComponent.elm index ed370bc5a..6e4305ec4 100644 --- a/src/Morphir/Visual/Components/TreeViewComponent.elm +++ b/src/Morphir/Visual/Components/TreeViewComponent.elm @@ -9,7 +9,7 @@ import Element.Events exposing (onClick) import Element.Font as Font exposing (center) import Morphir.Visual.Theme exposing (Theme) import Set exposing (Set) - +import Morphir.Visual.Components.TableView type alias NodePath comparable = List comparable diff --git a/tests-integration/reference-model/src/Morphir/Reference/Model/TestModel/testing.elm b/tests-integration/reference-model/src/Morphir/Reference/Model/TestModel/testing.elm index 8c90e4296..510fd4303 100644 --- a/tests-integration/reference-model/src/Morphir/Reference/Model/TestModel/testing.elm +++ b/tests-integration/reference-model/src/Morphir/Reference/Model/TestModel/testing.elm @@ -1,12 +1,5 @@ module Morphir.Reference.Model.TestModel.Testing exposing (..) -import Morphir.SDK.Decimal as Decimal exposing (Decimal) - - -fo20000o : Decimal -fo20000o = - Decimal.fromFloat 1.0 - type MyType = OneThing @@ -27,9 +20,10 @@ type alias MyList2 = MyList -decimalAddition : Decimal -> Decimal -> Decimal -decimalAddition a b = - Decimal.add a b +type alias Record = + { number : Int + , text : String + } mapping : MyList -> a -> (a -> MyList) -> MyList @@ -66,31 +60,35 @@ test5 : List MyRecord test5 = [ { key1 = OneThing, key2 = OtherThing }, { key1 = OneThing, key2 = OtherThing } ] + test6 : String -> Int -> Maybe String -> Maybe Int -> List MyRecord test6 a b c d = [ { key1 = OneThing, key2 = OtherThing }, { key1 = OneThing, key2 = OtherThing } ] + test7 : Maybe String -> String -> String -test7 maybeString string = +test7 maybeString string = case maybeString of Nothing -> "xxxxx" + _ -> string + test8 : Maybe String -> Maybe String -test8 maybeString = +test8 maybeString = case maybeString of Just s -> Just "just string" - _ -> - Nothing + _ -> + Nothing newTest : String -> Bool -> Int -> Int -> Int -> MyType -newTest a b q w e= - if (add3 q w e) > 6 then +newTest a b q w e = + if add3 q w e > 6 then if b then case a of "a" -> @@ -112,6 +110,7 @@ newTest a b q w e= _ -> OtherThing + else OtherThing @@ -120,6 +119,7 @@ newTest2 : String -> Bool -> MyType newTest2 a b = newTest3 a b 3 4 5 + newTest3 : String -> Bool -> Int -> Int -> Int -> MyType newTest3 a b q w e = case a of @@ -152,6 +152,7 @@ newTest3 a b q w e = _ -> OneThing + example1 : Bool -> Maybe Bool -> String example1 a b = if a then @@ -159,6 +160,7 @@ example1 a b = Just sth -> if sth then "foo" + else "bar" @@ -168,39 +170,174 @@ example1 a b = else "bar" + example2 : Maybe String -> Bool -> String example2 a b = case a of Just set -> if set == "a" && b then "b" + else "" + Nothing -> "" + add2 : Int -> Int -> Int add2 a b = a + b + add3 : Int -> Int -> Int -> Int add3 a b c = c + add2 a b + add4 : Int -> Int -> Int -> Int -> Int add4 a b c d = d + add3 a b c + add7 : Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int add7 a b c d e f g = - (add3 a b c) + (add4 d e f g) + add3 a b c + add4 d e f g powerRecursive : Int -> Int -> Int powerRecursive x n = if n == 0 then 1 + else if n == 1 then x + else - x * (powerRecursive x (n - 1)) \ No newline at end of file + x * powerRecursive x (n - 1) + + +operation1 : Record -> Record +operation1 record = + { record + | number = + if record.number < 5 then + record.number + 1 + + else + record.number + } + + +operation2 : Record -> Record +operation2 record = + { record | text = record.text ++ ("." ++ String.fromInt record.number) } + + +step3 : List Record -> List String +step3 records = + List.map (\r -> r.text) records + + +mapTest : List Record -> List String +mapTest recordList = + recordList + |> List.map operation1 + |> List.map (\r -> { r | number = r.number + 1 }) + |> List.map operation2 + |> List.map (\r -> r.text) + + +filterTest : List Record -> List Record +filterTest recordList = + recordList + |> List.filter (\r -> r.text == "a") + |> List.filter (\r -> r.number < 5) + + +filterMapTest : List Record -> List String +filterMapTest recordList = + recordList + |> List.filterMap + (\r -> + if r.number < 5 then + Just r.text + + else + Nothing + ) + +pipeVisualisationTest : List Record -> List String +pipeVisualisationTest recordList = + recordList + |> List.map operation1 + |> List.map (\r -> { r | number = r.number + 1 }) + |> List.filter (\r -> r.text == "a") + |> List.filterMap + (\r -> + if r.number < 5 then + Just r.text + + else + Nothing + ) + +mapTest2 : Bool -> List Record -> List Record +mapTest2 x recordList = + recordList + |> (if x then + List.map (\r -> { r | number = r.number + 1 }) + + else + List.map operation2 + ) + +concatTest : List Record -> { x | a : List String} +concatTest recordList = + { a = List.concat [recordList + |> List.map operation1 + |> List.map (\r -> { r | number = r.number + 1 }) + |> List.filter (\r -> r.text == "a") + |> List.filterMap + (\r -> + if r.number < 5 then + Just r.text + + else + Nothing + ), mapTest3 recordList]} + +mapTest3 : List Record -> List String +mapTest3 recordList = + let + operation : List Record -> List String + operation = + List.map (\r -> r.text) + in + recordList + |> List.map (\r -> operation1 r) + |> operation + + +letDeftest : Int -> Int +letDeftest x = + let + letDefWithParams : Int -> Int + letDefWithParams y = + y + 1 + + letDefWithoutParams : Int + letDefWithoutParams = + x + 1 + in + letDefWithoutParams |> letDefWithParams + + +asdft : MyType -> List Int -> Float +asdft enum aVeryLongINputListNameIsWrittenHere = + case enum of + OneThing -> + 1.0 + + OtherThing -> + 1.0 \ No newline at end of file From 4c9f6fbccfd041d4589279d61104e7ed867046f9 Mon Sep 17 00:00:00 2001 From: "Daniel A. Bekan" Date: Wed, 13 Sep 2023 15:39:21 +0200 Subject: [PATCH 2/5] show/hide coloumns, + sticky header --- cli/web/index.html | 9 + src/Morphir/Visual/Components/TableView.elm | 320 +++++++++++++++----- src/Morphir/Visual/ValueEditor.elm | 8 +- 3 files changed, 263 insertions(+), 74 deletions(-) diff --git a/cli/web/index.html b/cli/web/index.html index 59a9dcdf0..d89358ecf 100644 --- a/cli/web/index.html +++ b/cli/web/index.html @@ -8,6 +8,15 @@ padding: 0; margin: 0; } + + .sticky-headers { + position: relative; + } + .sticky-headers div[class^="gp grid-pos-1-"] { + position: sticky; + top: 0; + z-index: 9999; + } diff --git a/src/Morphir/Visual/Components/TableView.elm b/src/Morphir/Visual/Components/TableView.elm index 0923dc415..2d9b65ee2 100644 --- a/src/Morphir/Visual/Components/TableView.elm +++ b/src/Morphir/Visual/Components/TableView.elm @@ -1,26 +1,30 @@ module Morphir.Visual.Components.TableView exposing (..) import Dict exposing (Dict) -import Element exposing (Element, el, fill, fillPortion, height, padding, paddingXY, pointer, scrollbars, spacing, spacingXY, text, width) +import Element exposing (Element, el, fill, fillPortion, height, padding, paddingXY, pointer, scrollbars, shrink, spacing, spacingXY, text, width) import Element.Background import Element.Border import Element.Events exposing (onClick) import Element.Font as Font import Element.Input +import Html.Attributes +import List.Extra import Morphir.Elm.ParsedModule exposing (documentation) import Morphir.IR.Decoration exposing (AllDecorationConfigAndData, DecorationConfigAndData, DecorationID) +import Morphir.IR.Distribution as Distribution import Morphir.IR.Documented exposing (Documented) import Morphir.IR.Name as Name exposing (Name) import Morphir.IR.NodeId exposing (NodeID(..)) import Morphir.IR.Package as Package exposing (PackageName) import Morphir.IR.Path as Path exposing (Path) -import Morphir.IR.Type as Type +import Morphir.IR.Type as Type exposing (Specification(..), Type(..)) import Morphir.IR.Value as Value exposing (RawValue) import Morphir.SDK.Dict as SDKDict import Morphir.Visual.Common exposing (nameToTitleText, tooltip) import Morphir.Visual.Components.InputComponent as InputComponent import Morphir.Visual.Theme as Theme exposing (Theme) import Ordering exposing (Ordering) +import Set exposing (Set) type alias State = @@ -28,6 +32,7 @@ type alias State = , ordering : Ordering Row , orderDirection : OrderDirection , searchTerms : SearchTerms + , hiddenColumns : Set Int } @@ -61,6 +66,9 @@ type alias SearchTerms = type Msg = SetOrdering Int (Ordering Row) | Search Int String + | ClearSearch + | ToggleDisplayColumn Int + | ShowAllColumns type OrderDirection @@ -74,6 +82,7 @@ init = , ordering = Ordering.byField .typeName , orderDirection = Desc , searchTerms = Dict.empty + , hiddenColumns = Set.empty } @@ -105,6 +114,19 @@ update msg state = Search index term -> { state | searchTerms = Dict.insert index term state.searchTerms } + ClearSearch -> + { state | searchTerms = Dict.empty } + + ToggleDisplayColumn index -> + if Set.member index state.hiddenColumns then + { state | hiddenColumns = Set.remove index state.hiddenColumns } + + else + { state | hiddenColumns = Set.insert index state.hiddenColumns } + + ShowAllColumns -> + { state | hiddenColumns = Set.empty } + viewTypeTable : Theme -> Config msg -> PackageName -> Package.Definition () va -> Maybe Path -> AllDecorationConfigAndData -> Element msg viewTypeTable theme config packageName package moduleName allDecorationsConfigAndData = @@ -205,7 +227,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn rowElem : Element msg -> Element msg rowElem = - el [ Theme.borderBottom 1, Element.Border.color theme.colors.lightGray, paddingXY 2 1 ] + el [ Theme.borderBottom 1, Element.Border.color theme.colors.lightGray, paddingXY (Theme.smallPadding theme) 1 ] searchIn : String -> String -> Bool searchIn string term = @@ -219,39 +241,100 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn decorationColumns : List (Column msg) decorationColumns = + let + getField : RawValue -> Name -> Maybe RawValue + getField value fieldName = + case value of + Value.Record _ fields -> + Dict.get fieldName fields + + _ -> + Nothing + in decorations |> List.map (\( id, configAndData ) -> - { columnName = configAndData.displayName - , ordering = - \a b -> - case ( Dict.get id a.decorations, Dict.get id b.decorations ) of - ( Just (Just aVal), Just (Just bVal) ) -> - Basics.compare (Value.toString aVal) (Value.toString bVal) - - ( Just Nothing, Just (Just _) ) -> - GT - - _ -> - LT - , view = - \row -> - case Dict.get id row.decorations of - Just (Just val) -> - rowElem <| Theme.ellipseText <| Value.toString val - - _ -> - rowElem <| text "-" - , filtering = - \term row -> - case Dict.get id row.decorations of - Just (Just val) -> - searchIn (Value.toString val) term - - _ -> - String.isEmpty term - } + case Distribution.lookupTypeSpecification configAndData.entryPoint configAndData.iR of + Just (TypeAliasSpecification _ (Record _ fieldList)) -> + let + rec f = + case f.tpe of + --(Record _ innerFieldList) -> + -- innerFieldList + -- |> List.map rec + -- |> List.foldl (++) [] + _ -> + [ { columnName = configAndData.displayName ++ "." ++ (f.name |> nameToTitleText) + , ordering = \a b -> EQ + , view = + \row -> + case Dict.get id row.decorations of + Just (Just val) -> + case getField val f.name of + Just fieldValue -> + fieldValue |> Value.toString |> text |> rowElem + + Nothing -> + rowElem <| text "-" + + _ -> + rowElem <| text "-" + , filtering = + \term row -> + case Dict.get id row.decorations of + Just (Just val) -> + case getField val f.name of + Just fieldValue -> + searchIn (fieldValue |> Value.toString) term + + _ -> + False + + _ -> + String.isEmpty term + } + ] + in + fieldList + |> List.map + (\field -> + rec field + ) + |> List.foldl (++) [] + + _ -> + [ { columnName = configAndData.displayName + , ordering = + \a b -> + case ( Dict.get id a.decorations, Dict.get id b.decorations ) of + ( Just (Just aVal), Just (Just bVal) ) -> + Basics.compare (Value.toString aVal) (Value.toString bVal) + + ( Just Nothing, Just (Just _) ) -> + GT + + _ -> + LT + , view = + \row -> + case Dict.get id row.decorations of + Just (Just val) -> + rowElem <| Theme.ellipseText <| Value.toString val + + _ -> + rowElem <| text "-" + , filtering = + \term row -> + case Dict.get id row.decorations of + Just (Just val) -> + searchIn (Value.toString val) term + + _ -> + String.isEmpty term + } + ] ) + |> List.foldl (++) [] columns : List (Column msg) columns = @@ -289,47 +372,146 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn header : String -> Int -> Ordering Row -> Element msg header title index ordering = - Element.row [ spacing <| Theme.smallSpacing theme, Element.paddingEach { right = Theme.mediumPadding theme, left = 0, bottom = 0, top = 0 } ] - [ Element.row - [ paddingXY 2 (Theme.largePadding theme) - , Font.color theme.colors.mediumGray - , onClick <| config.onStateChange (update (SetOrdering index ordering) config.state) - , Element.Background.color theme.colors.lightest - , pointer - , width (fillPortion 1) + Element.row + [ paddingXY 2 (Theme.largePadding theme) + , Font.color theme.colors.mediumGray + , onClick <| config.onStateChange (update (SetOrdering index ordering) config.state) + , Element.Background.color theme.colors.lightest + , pointer + , width (fillPortion 1) + , Element.paddingEach { right = Theme.mediumPadding theme, left = 0, bottom = 0, top = 0 } + , Element.moveUp <| toFloat (Theme.scaled 2 theme) + , Element.height <| Element.minimum (Theme.scaled 8 theme) fill + ] + [ text title + , if index == config.state.orderByColumnIndex then + el [ Font.color theme.colors.brandPrimary, Font.size (Theme.scaled 4 theme), Font.bold ] + (case config.state.orderDirection of + Desc -> + text " ⇩" + + _ -> + text " ⇧" + ) + + else + Element.none + ] + + selectDisplayedColumns : Element msg + selectDisplayedColumns = + Element.column + [ padding <| Theme.mediumPadding theme + , spacing <| Theme.smallSpacing theme + , height fill + , width <| fillPortion 1 + ] + [ el [ Font.bold, Font.size (Theme.scaled 4 theme) ] (text "Show columns") + , Element.wrappedRow [ width fill, spacing <| Theme.largeSpacing theme, padding <| Theme.smallPadding theme ] <| + List.indexedMap + (\i c -> + let + ifToggledElse : t -> t -> t + ifToggledElse a b = + if Set.member i config.state.hiddenColumns then + a + + else + b + in + Element.row [ Theme.borderRounded theme, Element.Background.color theme.colors.brandPrimaryLight, padding 1, spacing <| Theme.smallSpacing theme ] + [ el [] (text c.columnName) + , el + [ pointer + , padding <| Theme.mediumPadding theme + , Element.Background.color <| ifToggledElse theme.colors.brandPrimaryLight theme.colors.brandPrimary + , Theme.borderRounded theme + , Element.Events.onClick (config.onStateChange (update (ToggleDisplayColumn i) config.state)) + ] + (ifToggledElse (text " ✔ ") (text " ✘ ")) + ] + ) + columns + , Element.Input.button + [ padding 7 + , theme |> Theme.borderRounded + , Element.Background.color theme.colors.darkest + , Font.color theme.colors.lightest + , Font.bold + , Font.size theme.fontSize + , Element.alignRight ] - [ text title - , if index == config.state.orderByColumnIndex then - el [ Font.color theme.colors.brandPrimary, Font.size (Theme.scaled 4 theme), Font.bold ] - (case config.state.orderDirection of - Desc -> - text " ⇩" - - _ -> - text " ⇧" - ) + { onPress = Just <| config.onStateChange <| update ShowAllColumns config.state + , label = text "Show All" + } + ] - else - Element.none + searchPanel : Element msg + searchPanel = + Element.column + [ padding <| Theme.mediumPadding theme + , spacing <| Theme.smallSpacing theme + , width <| fillPortion 1 + ] + [ el [ Font.bold, Font.size (Theme.scaled 4 theme) ] (text "Search") + , Element.indexedTable + [ width shrink + , padding (Theme.smallPadding theme) + , spacingXY 0 (Theme.smallSpacing theme) + ] + { columns = + [ { header = Element.none + , width = shrink + , view = \index c -> el [ paddingXY 2 1, Element.alignBottom ] (text c.columnName) + } + , { header = Element.none + , width = shrink + , view = + \index c -> + InputComponent.searchInput theme + [ spacingXY 0 (Theme.smallSpacing theme) ] + { onChange = \term -> config.onStateChange (update (Search index term) config.state) + , text = Dict.get index config.state.searchTerms |> Maybe.withDefault "" + , placeholder = Just <| Element.Input.placeholder [] (text "...") + , label = Element.Input.labelHidden "" + } + } + ] + , data = columns + } + , Element.Input.button + [ padding 7 + , theme |> Theme.borderRounded + , Element.Background.color theme.colors.darkest + , Font.color theme.colors.lightest + , Font.bold + , Font.size theme.fontSize + , Element.alignRight ] - , InputComponent.searchInput theme - [ width (Element.px 180) ] - { onChange = \term -> config.onStateChange (update (Search index term) config.state) - , text = Dict.get index config.state.searchTerms |> Maybe.withDefault "" - , placeholder = Just <| Element.Input.placeholder [] (text "search . . .") - , label = Element.Input.labelHidden "" + { onPress = Just <| config.onStateChange <| update ClearSearch config.state + , label = text "Clear" } ] in - Element.table - [ width fill - , height fill - , Element.clipY - , scrollbars - , padding (Theme.mediumPadding theme) - , spacingXY 0 (Theme.mediumSpacing theme) + Element.column [ height fill, spacing <| Theme.largeSpacing theme ] + [ Element.row + [ width fill + , Theme.borderRounded theme + , Element.Border.color theme.colors.brandPrimary + , Element.Background.color theme.colors.brandPrimaryLight + ] + [ searchPanel, selectDisplayedColumns, el [ width <| fillPortion 3 ] Element.none ] + , Element.table + [ width fill + , height fill + , Element.clipY + , Element.htmlAttribute (Html.Attributes.class "sticky-headers") + , scrollbars + , padding (Theme.mediumPadding theme) + , spacingXY 0 (Theme.mediumSpacing theme) + ] + { columns = + columns |> List.Extra.removeIfIndex (\i -> Set.member i config.state.hiddenColumns) |> List.indexedMap (\index column -> { header = header column.columnName index column.ordering, width = Element.fillPortion 1, view = column.view }) + , data = types |> List.sortWith config.state.ordering |> List.filter searchFunction + } ] - { columns = - columns |> List.indexedMap (\index column -> { header = header column.columnName index column.ordering, width = Element.fillPortion 1, view = column.view }) - , data = types |> List.sortWith config.state.ordering |> List.filter searchFunction - } diff --git a/src/Morphir/Visual/ValueEditor.elm b/src/Morphir/Visual/ValueEditor.elm index 6cd8d81ed..c3c5bb4f4 100644 --- a/src/Morphir/Visual/ValueEditor.elm +++ b/src/Morphir/Visual/ValueEditor.elm @@ -735,13 +735,12 @@ view theme ir valueType updateEditorState editorState = } , options = [ Input.option True (text "yes"), Input.option False (text "no") ] , selected = isChecked - , label = Input.labelLeft labelStyle (text "bool") + , label = Input.labelHidden "bool" } RecordEditor fieldEditorStates -> row [] <| - [ el [ Font.italic, paddingXY 10 5 ] (text "record") - , el + [ el [ padding <| Theme.largePadding theme , Background.color theme.colors.brandPrimaryLight , Theme.borderRounded theme @@ -1451,8 +1450,7 @@ viewCustomTypeEditor theme labelStyle ir updateEditorState editorState (( packag ) in row [ width fill, height fill, spacing 5 ] - [ el labelStyle (text <| nameToText typeName) - , viewConstructor + [ viewConstructor , row [ width fill , spacing 5 From e3088b8d18ec7422cc91efabe2ff8bd1409f16fd Mon Sep 17 00:00:00 2001 From: "Daniel A. Bekan" Date: Fri, 15 Sep 2023 15:01:05 +0200 Subject: [PATCH 3/5] partial support for editing decorations in table --- cli/src/Morphir/Web/DevelopApp.elm | 28 +++++++++++++++++++++ src/Morphir/Visual/Components/TableView.elm | 21 +++++++--------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/cli/src/Morphir/Web/DevelopApp.elm b/cli/src/Morphir/Web/DevelopApp.elm index 8077d9d81..f9cd8806b 100644 --- a/cli/src/Morphir/Web/DevelopApp.elm +++ b/cli/src/Morphir/Web/DevelopApp.elm @@ -1382,6 +1382,33 @@ viewDecorationValues model node = [ attributeToEditors ] +decorationEditor theme editorStates decorationID decorationDetail node = + let + irValue : Maybe (Value () ()) + irValue = + decorationDetail.data + |> SDKDict.get node + nodeDetail : DecorationNodeID + nodeDetail = + { decorationID = decorationID, nodeID = node } + editorState : ValueEditor.EditorState + editorState = + editorStates + |> SDKDict.get nodeDetail + |> Maybe.withDefault + (ValueEditor.initEditorState + decorationDetail.iR + (Type.Reference () decorationDetail.entryPoint []) + irValue + ) + in + ValueEditor.view + theme + decorationDetail.iR + (Type.Reference () decorationDetail.entryPoint []) + (Decoration << DecorationValueUpdated nodeDetail) + editorState + {-| Display the home UI -} viewHome : Model -> PackageName -> Package.Definition () (Type ()) -> Element Msg @@ -1521,6 +1548,7 @@ viewHome model packageName packageDef = packageDef (model.homeState.selectedModule |> Maybe.map Tuple.second) model.allDecorationConfigAndData + (decorationEditor model.theme model.decorationEditorStates) ] } ] diff --git a/src/Morphir/Visual/Components/TableView.elm b/src/Morphir/Visual/Components/TableView.elm index 2d9b65ee2..9a9567da8 100644 --- a/src/Morphir/Visual/Components/TableView.elm +++ b/src/Morphir/Visual/Components/TableView.elm @@ -128,8 +128,8 @@ update msg state = { state | hiddenColumns = Set.empty } -viewTypeTable : Theme -> Config msg -> PackageName -> Package.Definition () va -> Maybe Path -> AllDecorationConfigAndData -> Element msg -viewTypeTable theme config packageName package moduleName allDecorationsConfigAndData = +viewTypeTable : Theme -> Config msg -> PackageName -> Package.Definition () va -> Maybe Path -> AllDecorationConfigAndData -> (DecorationID -> DecorationConfigAndData -> NodeID -> Element msg) -> Element msg +viewTypeTable theme config packageName package moduleName allDecorationsConfigAndData displayDecorationEditor = let typeDefToString : Type.Definition () -> String typeDefToString tpe = @@ -317,12 +317,8 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn LT , view = \row -> - case Dict.get id row.decorations of - Just (Just val) -> - rowElem <| Theme.ellipseText <| Value.toString val - - _ -> - rowElem <| text "-" + el [ Element.alignTop, Element.moveUp <| toFloat <| Theme.mediumPadding theme ] <| + displayDecorationEditor id configAndData (TypeID ( packageName, row.morphirModule, row.typeName ) []) , filtering = \term row -> case Dict.get id row.decorations of @@ -406,8 +402,8 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn , height fill , width <| fillPortion 1 ] - [ el [ Font.bold, Font.size (Theme.scaled 4 theme) ] (text "Show columns") - , Element.wrappedRow [ width fill, spacing <| Theme.largeSpacing theme, padding <| Theme.smallPadding theme ] <| + [ el [ Font.bold, Font.size (Theme.scaled 4 theme) ] (text "Show / hide columns") + , Element.wrappedRow [ width fill, spacing <| Theme.smallSpacing theme, padding <| Theme.smallPadding theme, height fill ] <| List.indexedMap (\i c -> let @@ -420,7 +416,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn b in Element.row [ Theme.borderRounded theme, Element.Background.color theme.colors.brandPrimaryLight, padding 1, spacing <| Theme.smallSpacing theme ] - [ el [] (text c.columnName) + [ el [ padding <| Theme.smallPadding theme ] (text c.columnName) , el [ pointer , padding <| Theme.mediumPadding theme @@ -452,6 +448,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn [ padding <| Theme.mediumPadding theme , spacing <| Theme.smallSpacing theme , width <| fillPortion 1 + , height fill ] [ el [ Font.bold, Font.size (Theme.scaled 4 theme) ] (text "Search") , Element.indexedTable @@ -493,7 +490,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn } ] in - Element.column [ height fill, spacing <| Theme.largeSpacing theme ] + Element.column [ height fill, spacing <| Theme.largeSpacing theme, width fill ] [ Element.row [ width fill , Theme.borderRounded theme From 32764c1bd85149952366ae1e55ebea79de1e5378 Mon Sep 17 00:00:00 2001 From: "Daniel A. Bekan" Date: Wed, 20 Sep 2023 13:43:10 +0200 Subject: [PATCH 4/5] collapsible search&filter section --- package.json | 4 + src/Morphir/Visual/Components/TableView.elm | 95 +++++++++++++++------ 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index e0dd2ecae..ccd326987 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,10 @@ "description": "Elm bindings for Morphir", "types": "lib/dist/main.d.ts", "main": "lib/dist/main.js", + "engines": { + "npm": "8.5.5", + "node": "v16.14.0" + }, "scripts": { "clean": "gulp clean", "test": "gulp test", diff --git a/src/Morphir/Visual/Components/TableView.elm b/src/Morphir/Visual/Components/TableView.elm index 9a9567da8..e91dbef71 100644 --- a/src/Morphir/Visual/Components/TableView.elm +++ b/src/Morphir/Visual/Components/TableView.elm @@ -1,8 +1,8 @@ module Morphir.Visual.Components.TableView exposing (..) import Dict exposing (Dict) -import Element exposing (Element, el, fill, fillPortion, height, padding, paddingXY, pointer, scrollbars, shrink, spacing, spacingXY, text, width) -import Element.Background +import Element exposing (Element, alignRight, alignTop, centerX, el, fill, fillPortion, height, padding, paddingXY, pointer, scrollbars, shrink, spacing, spacingXY, text, width) +import Element.Background as Background import Element.Border import Element.Events exposing (onClick) import Element.Font as Font @@ -33,6 +33,7 @@ type alias State = , orderDirection : OrderDirection , searchTerms : SearchTerms , hiddenColumns : Set Int + , searchAndFilterSectionOpen : Bool } @@ -69,6 +70,7 @@ type Msg | ClearSearch | ToggleDisplayColumn Int | ShowAllColumns + | ToggleSearchAndFilterSection type OrderDirection @@ -83,6 +85,7 @@ init = , orderDirection = Desc , searchTerms = Dict.empty , hiddenColumns = Set.empty + , searchAndFilterSectionOpen = False } @@ -127,6 +130,9 @@ update msg state = ShowAllColumns -> { state | hiddenColumns = Set.empty } + ToggleSearchAndFilterSection -> + { state | searchAndFilterSectionOpen = not state.searchAndFilterSectionOpen } + viewTypeTable : Theme -> Config msg -> PackageName -> Package.Definition () va -> Maybe Path -> AllDecorationConfigAndData -> (DecorationID -> DecorationConfigAndData -> NodeID -> Element msg) -> Element msg viewTypeTable theme config packageName package moduleName allDecorationsConfigAndData displayDecorationEditor = @@ -265,7 +271,22 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn -- |> List.foldl (++) [] _ -> [ { columnName = configAndData.displayName ++ "." ++ (f.name |> nameToTitleText) - , ordering = \a b -> EQ + , ordering = + \a b -> + case ( Dict.get id a.decorations, Dict.get id b.decorations ) of + ( Just (Just aVal), Just (Just bVal) ) -> + case ( getField aVal f.name, getField bVal f.name ) of + ( Just aFieldVal, Just bFieldVal ) -> + Basics.compare (Value.toString aFieldVal) (Value.toString bFieldVal) + + _ -> + LT + + ( Just Nothing, Just (Just _) ) -> + GT + + _ -> + LT , view = \row -> case Dict.get id row.decorations of @@ -317,8 +338,8 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn LT , view = \row -> - el [ Element.alignTop, Element.moveUp <| toFloat <| Theme.mediumPadding theme ] <| - displayDecorationEditor id configAndData (TypeID ( packageName, row.morphirModule, row.typeName ) []) + el [ alignTop, Element.moveUp <| toFloat <| Theme.mediumPadding theme ] <| + displayDecorationEditor id configAndData (TypeID ( packageName, row.morphirModule, row.typeName ) []) , filtering = \term row -> case Dict.get id row.decorations of @@ -342,7 +363,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn el [ tooltip Element.below (el - [ Element.Background.color theme.colors.lightest + [ Background.color theme.colors.lightest , theme |> Theme.borderRounded , Element.Border.shadow { offset = ( 0, 3 ), blur = 6, size = 0, color = Element.rgba 0 0 0 0.32 } @@ -372,7 +393,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn [ paddingXY 2 (Theme.largePadding theme) , Font.color theme.colors.mediumGray , onClick <| config.onStateChange (update (SetOrdering index ordering) config.state) - , Element.Background.color theme.colors.lightest + , Background.color theme.colors.lightest , pointer , width (fillPortion 1) , Element.paddingEach { right = Theme.mediumPadding theme, left = 0, bottom = 0, top = 0 } @@ -400,7 +421,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn [ padding <| Theme.mediumPadding theme , spacing <| Theme.smallSpacing theme , height fill - , width <| fillPortion 1 + , width <| fillPortion 2 ] [ el [ Font.bold, Font.size (Theme.scaled 4 theme) ] (text "Show / hide columns") , Element.wrappedRow [ width fill, spacing <| Theme.smallSpacing theme, padding <| Theme.smallPadding theme, height fill ] <| @@ -415,12 +436,12 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn else b in - Element.row [ Theme.borderRounded theme, Element.Background.color theme.colors.brandPrimaryLight, padding 1, spacing <| Theme.smallSpacing theme ] + Element.row [ Theme.borderRounded theme, Background.color theme.colors.brandPrimaryLight, padding 1, spacing <| Theme.smallSpacing theme ] [ el [ padding <| Theme.smallPadding theme ] (text c.columnName) , el [ pointer , padding <| Theme.mediumPadding theme - , Element.Background.color <| ifToggledElse theme.colors.brandPrimaryLight theme.colors.brandPrimary + , Background.color <| ifToggledElse theme.colors.brandPrimaryLight theme.colors.brandPrimary , Theme.borderRounded theme , Element.Events.onClick (config.onStateChange (update (ToggleDisplayColumn i) config.state)) ] @@ -431,11 +452,11 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn , Element.Input.button [ padding 7 , theme |> Theme.borderRounded - , Element.Background.color theme.colors.darkest + , Background.color theme.colors.darkest , Font.color theme.colors.lightest , Font.bold , Font.size theme.fontSize - , Element.alignRight + , alignRight ] { onPress = Just <| config.onStateChange <| update ShowAllColumns config.state , label = text "Show All" @@ -447,7 +468,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn Element.column [ padding <| Theme.mediumPadding theme , spacing <| Theme.smallSpacing theme - , width <| fillPortion 1 + , width <| fillPortion 3 , height fill ] [ el [ Font.bold, Font.size (Theme.scaled 4 theme) ] (text "Search") @@ -458,7 +479,7 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn ] { columns = [ { header = Element.none - , width = shrink + , width = fill , view = \index c -> el [ paddingXY 2 1, Element.alignBottom ] (text c.columnName) } , { header = Element.none @@ -479,28 +500,54 @@ viewTypeTable theme config packageName package moduleName allDecorationsConfigAn , Element.Input.button [ padding 7 , theme |> Theme.borderRounded - , Element.Background.color theme.colors.darkest + , Background.color theme.colors.darkest , Font.color theme.colors.lightest , Font.bold , Font.size theme.fontSize - , Element.alignRight + , alignRight ] { onPress = Just <| config.onStateChange <| update ClearSearch config.state , label = text "Clear" } ] + + searchAndFilterSection : Element msg + searchAndFilterSection = + let + openOrCloseSection = + if config.state.searchAndFilterSectionOpen then + el [ Font.size (Theme.scaled 5 theme), alignRight, alignTop, Font.bold, padding <| Theme.largePadding theme, pointer, onClick <| config.onStateChange (update ToggleSearchAndFilterSection config.state) ] + (text "X") + + else + el [ centerX, Font.bold, padding <| Theme.mediumPadding theme, pointer, onClick <| config.onStateChange (update ToggleSearchAndFilterSection config.state) ] + (text "Open Search & Filter") + in + Element.row + [ width fill + , height <| + if config.state.searchAndFilterSectionOpen then + fillPortion 1 + + else + shrink + , Theme.borderRounded theme + , Element.Border.color theme.colors.brandPrimary + , Background.color theme.colors.brandPrimaryLight + , spacing <| Theme.largeSpacing theme + ] + (if config.state.searchAndFilterSectionOpen then + [ searchPanel, selectDisplayedColumns, el [ width <| fillPortion 12 ] Element.none, openOrCloseSection ] + + else + [ openOrCloseSection ] + ) in Element.column [ height fill, spacing <| Theme.largeSpacing theme, width fill ] - [ Element.row - [ width fill - , Theme.borderRounded theme - , Element.Border.color theme.colors.brandPrimary - , Element.Background.color theme.colors.brandPrimaryLight - ] - [ searchPanel, selectDisplayedColumns, el [ width <| fillPortion 3 ] Element.none ] + [ searchAndFilterSection , Element.table [ width fill - , height fill + , height <| fillPortion 5 , Element.clipY , Element.htmlAttribute (Html.Attributes.class "sticky-headers") , scrollbars From 5626bc62826ba26ef325119c3df2aea62ab87b89 Mon Sep 17 00:00:00 2001 From: "Daniel A. Bekan" Date: Wed, 20 Sep 2023 15:17:11 +0200 Subject: [PATCH 5/5] 2.83.1-typetable.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb3903949..b543f2b47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "morphir-elm", - "version": "2.83.0", + "version": "2.83.1-typetable.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "morphir-elm", - "version": "2.83.0", + "version": "2.83.1-typetable.1", "license": "Apache-2.0", "dependencies": { "@morphir/typespec-sdk": "^0.1.0", diff --git a/package.json b/package.json index ccd326987..8229250ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "morphir-elm", - "version": "2.83.0", + "version": "2.83.1-typetable.1", "description": "Elm bindings for Morphir", "types": "lib/dist/main.d.ts", "main": "lib/dist/main.js",