diff --git a/README.md b/README.md index 6fd6e0c0..320ffac6 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,9 @@ An [Obsidian](https://obsidian.md/) plugin to make working with tasks a pleasure - Tag based (uses `#tags` to define your boards). ## New +- Collapseable columns. To make this work nicely, columns are now set to a fixed width. + See the [Scaling Board Text and Column Sizes section](#scaling-board-text-and-column-sizes) + to customize this if you don't like the width I have chosen. - Supports all valid CommonMark unordered list markers (`-`, `+`, `*`) -> @MattiasMartens. - Option to choose whether to apply tag filters to top level tasks, sub-tasks, or both. @@ -22,7 +25,6 @@ An [Obsidian](https://obsidian.md/) plugin to make working with tasks a pleasure from boards when marked as complete, or the information on a card changing depending which column it was displayed in. If you are used to the way things used to work you may well notice a change (hopefully for the best). -- Sub-task tags now shown inline rather than at the top of the card. ![date based board screenshot](/images/dateBoard.png?raw=true) @@ -319,23 +321,21 @@ To get the correct behavior for recurring tasks, click the edit icon on the card to go to the file where the task is written, and then use the *"Tasks: Toggle Done"* command or click the checkbox from there. -## Scaling Board Size -You can scale the size of the board relative to the size of stuff in Obsidian using -a css snippet: +## Scaling Board Text and Column Sizes +Use the following css snippet to customize these: ```css .card-board-view { font-size: 1em; } -.card-board-view .card-board-columns { - grid-auto-columns: minmax(20em, 1fr); +.card-board-view .card-board-column { + width: 20em; } ``` -You can change the font-size to alter the general size of the contents of the cards. -If you change the value of the first parameter of the minmax function you can change -the minimum width of the cards. +You can alter the general size of the contents of the cards by changng the font-size, +and/or set the width of the columns by changing the width setting. ## Limitations diff --git a/configExamples/data.0.9.0.json b/configExamples/data.0.9.0.json new file mode 100644 index 00000000..4072c646 --- /dev/null +++ b/configExamples/data.0.9.0.json @@ -0,0 +1,221 @@ +{ + "version": "0.9.0", + "data": { + "boardConfigs": [ + { + "tag": "dateBoardConfig", + "data": { + "completedCount": 5, + "filters": [ + { + "tag": "tagFilter", + "data": "people/" + }, + { + "tag": "tagFilter", + "data": "home/" + } + ], + "filterPolarity": "Deny", + "filterScope": "TopLevelOnly", + "showFilteredTags": false, + "includeUndated": true, + "title": "Dated", + "collapsedColumns": [ + 0, + 2, + 3 + ] + } + }, + { + "tag": "tagBoardConfig", + "data": { + "columns": [ + { + "tag": "home/", + "displayTitle": "Home/" + }, + { + "tag": "home", + "displayTitle": "Home" + }, + { + "tag": "wellbeing", + "displayTitle": "Wellbeing" + }, + { + "tag": "town", + "displayTitle": "Town" + } + ], + "showColumnTags": false, + "completedCount": 10, + "filters": [], + "filterPolarity": "Allow", + "filterScope": "SubTasksOnly", + "showFilteredTags": false, + "includeOthers": true, + "includeUntagged": true, + "title": "Tagged", + "collapsedColumns": [ + 0, + 1, + 5 + ] + } + }, + { + "tag": "tagBoardConfig", + "data": { + "columns": [ + { + "tag": "status/backlog", + "displayTitle": "Backlog" + }, + { + "tag": "status/triaged", + "displayTitle": "Triaged" + }, + { + "tag": "status/blocked", + "displayTitle": "Blocked" + }, + { + "tag": "status/doing", + "displayTitle": "Doing" + } + ], + "showColumnTags": false, + "completedCount": 10, + "filters": [ + { + "tag": "tagFilter", + "data": "projects/project1" + } + ], + "filterPolarity": "Allow", + "filterScope": "Both", + "showFilteredTags": false, + "includeOthers": true, + "includeUntagged": false, + "title": "Project 1", + "collapsedColumns": [ + 0, + 2, + 3 + ] + } + }, + { + "tag": "tagBoardConfig", + "data": { + "columns": [ + { + "tag": "home/kitchen", + "displayTitle": "Kitchen" + }, + { + "tag": "home/outside", + "displayTitle": "Outside" + } + ], + "showColumnTags": true, + "completedCount": 10, + "filters": [ + { + "tag": "tagFilter", + "data": "home" + }, + { + "tag": "tagFilter", + "data": "home/" + } + ], + "filterPolarity": "Allow", + "filterScope": "Both", + "showFilteredTags": true, + "includeOthers": false, + "includeUntagged": false, + "title": "Home", + "collapsedColumns": [] + } + }, + { + "tag": "tagBoardConfig", + "data": { + "columns": [ + { + "tag": "خانه", + "displayTitle": "خانه" + }, + { + "tag": "خانه/", + "displayTitle": "خانه/" + } + ], + "showColumnTags": true, + "completedCount": 10, + "filters": [], + "filterPolarity": "Allow", + "filterScope": "Both", + "showFilteredTags": true, + "includeOthers": false, + "includeUntagged": false, + "title": "خانه", + "collapsedColumns": [] + } + }, + { + "tag": "tagBoardConfig", + "data": { + "columns": [ + { + "tag": "people/fred", + "displayTitle": "Fred" + }, + { + "tag": "people/wilma", + "displayTitle": "Wilma" + }, + { + "tag": "people/barney", + "displayTitle": "Barney" + } + ], + "showColumnTags": true, + "completedCount": 10, + "filters": [ + { + "tag": "tagFilter", + "data": "people/" + } + ], + "filterPolarity": "Allow", + "filterScope": "Both", + "showFilteredTags": true, + "includeOthers": true, + "includeUntagged": false, + "title": "People", + "collapsedColumns": [ + 0, + 1, + 3 + ] + } + } + ], + "globalSettings": { + "taskCompletionFormat": "ObsidianCardBoard", + "columnNames": { + "today": "", + "tomorrow": "", + "future": "", + "undated": "", + "others": "", + "untagged": "", + "completed": "" + } + } + } +} \ No newline at end of file diff --git a/images/dateBoard.png b/images/dateBoard.png index bc1e774b..a5df2455 100644 Binary files a/images/dateBoard.png and b/images/dateBoard.png differ diff --git a/src/Board.elm b/src/Board.elm index 34da6da4..8f3712e2 100644 --- a/src/Board.elm +++ b/src/Board.elm @@ -6,6 +6,7 @@ module Board exposing import BoardConfig exposing (BoardConfig) import Card exposing (Card) +import CollapsedColumns exposing (CollapsedColumns) import Column exposing (Column) import ColumnNames exposing (ColumnNames) import DateBoardColumns exposing (DateBoardColumns) @@ -51,6 +52,7 @@ columns timeWithZone boardIndex (Board columnNames config taskList) = |> TaskList.foldl DateBoardColumns.addTaskItem emptyDateBoardColumns |> DateBoardColumns.columns |> convertToCards boardIndex + |> collapseColumns config BoardConfig.TagBoardConfig tagBoardConfig -> let @@ -63,12 +65,31 @@ columns timeWithZone boardIndex (Board columnNames config taskList) = |> TaskList.foldl TagBoardColumns.addTaskItem emptyTagBoardColumns |> TagBoardColumns.columns |> convertToCards boardIndex + |> collapseColumns config -- PRIVATE +collapseColumns : BoardConfig -> List (Column Card) -> List (Column Card) +collapseColumns config cols = + let + collapsedColumns : CollapsedColumns + collapsedColumns = + BoardConfig.collapsedColumns config + + performCollapse : Int -> Column Card -> Column Card + performCollapse index col = + if CollapsedColumns.columnIsCollapsed index collapsedColumns then + Column.collapseState True col + + else + Column.collapseState False col + in + List.indexedMap performCollapse cols + + filterTaskList : BoardConfig -> TaskList -> TaskList filterTaskList config taskList = let diff --git a/src/BoardConfig.elm b/src/BoardConfig.elm index 347d5000..97cf2f57 100644 --- a/src/BoardConfig.elm +++ b/src/BoardConfig.elm @@ -1,11 +1,14 @@ module BoardConfig exposing ( BoardConfig(..) + , collapseColumn + , collapsedColumns , decoder_v_0_1_0 , decoder_v_0_2_0 , decoder_v_0_3_0 , decoder_v_0_4_0 , decoder_v_0_5_0 , decoder_v_0_6_0 + , decoder_v_0_9_0 , default , encoder , filterPolarity @@ -30,6 +33,7 @@ module BoardConfig exposing , updateTitle ) +import CollapsedColumns exposing (CollapsedColumns) import DateBoardConfig exposing (DateBoardConfig) import DecodeHelpers import Filter exposing (Filter, Polarity, Scope) @@ -81,6 +85,16 @@ fromBoardType boardType title_ = -- UTILITIES +collapsedColumns : BoardConfig -> CollapsedColumns +collapsedColumns config = + case config of + DateBoardConfig c -> + c.collapsedColumns + + TagBoardConfig c -> + c.collapsedColumns + + isForDateBoard : BoardConfig -> Bool isForDateBoard config = case config of @@ -161,6 +175,14 @@ encoder = |> TsEncode.buildUnion +decoder_v_0_9_0 : TsDecode.Decoder BoardConfig +decoder_v_0_9_0 = + TsDecode.oneOf + [ DecodeHelpers.toElmVariant "dateBoardConfig" DateBoardConfig DateBoardConfig.decoder_v_0_9_0 + , DecodeHelpers.toElmVariant "tagBoardConfig" TagBoardConfig TagBoardConfig.decoder_v_0_9_0 + ] + + decoder_v_0_6_0 : TsDecode.Decoder BoardConfig decoder_v_0_6_0 = TsDecode.oneOf @@ -220,6 +242,18 @@ mapFilters fn config = TagBoardConfig { boardConfig | filters = List.map fn boardConfig.filters } +collapseColumn : Int -> Bool -> BoardConfig -> BoardConfig +collapseColumn columnIndex isCollapsed config = + case config of + DateBoardConfig boardConfig -> + DateBoardConfig <| + { boardConfig | collapsedColumns = CollapsedColumns.collapseColumn columnIndex isCollapsed boardConfig.collapsedColumns } + + TagBoardConfig boardConfig -> + TagBoardConfig <| + { boardConfig | collapsedColumns = CollapsedColumns.collapseColumn columnIndex isCollapsed boardConfig.collapsedColumns } + + toggleIncludeOthers : BoardConfig -> BoardConfig toggleIncludeOthers config = case config of diff --git a/src/CollapsedColumns.elm b/src/CollapsedColumns.elm new file mode 100644 index 00000000..19a70715 --- /dev/null +++ b/src/CollapsedColumns.elm @@ -0,0 +1,74 @@ +module CollapsedColumns exposing + ( CollapsedColumns + , collapseColumn + , columnIsCollapsed + , decoder + , encoder + , init + ) + +import Set exposing (Set) +import TsJson.Decode as TsDecode +import TsJson.Encode as TsEncode + + + +-- TYPES + + +type CollapsedColumns + = CollapsedColumns (Set Int) + + +init : CollapsedColumns +init = + CollapsedColumns Set.empty + + + +-- SERIALIZATION + + +decoder : TsDecode.Decoder CollapsedColumns +decoder = + TsDecode.list TsDecode.int + |> TsDecode.map Set.fromList + |> TsDecode.map CollapsedColumns + + +encoder : TsEncode.Encoder CollapsedColumns +encoder = + TsEncode.list TsEncode.int + |> TsEncode.map Set.toList + |> TsEncode.map indicies + + + +-- INFO + + +columnIsCollapsed : Int -> CollapsedColumns -> Bool +columnIsCollapsed column collapsedColumns = + Set.member column (indicies collapsedColumns) + + + +-- MODIFY + + +collapseColumn : Int -> Bool -> CollapsedColumns -> CollapsedColumns +collapseColumn column state collapsedColumns = + if state then + CollapsedColumns <| Set.insert column (indicies collapsedColumns) + + else + CollapsedColumns <| Set.remove column (indicies collapsedColumns) + + + +-- PRIVATE + + +indicies : CollapsedColumns -> Set Int +indicies (CollapsedColumns s) = + s diff --git a/src/Column.elm b/src/Column.elm index f448b42c..f70d2af6 100644 --- a/src/Column.elm +++ b/src/Column.elm @@ -1,8 +1,10 @@ module Column exposing ( Column , PlacementResult(..) + , collapseState , hasName , init + , isCollapsed , isEmpty , isEnabled , items @@ -13,7 +15,15 @@ module Column exposing type Column a - = Column Bool String (List a) + = Column (Config a) + + +type alias Config a = + { enabled : Bool + , name : String + , items : List a + , collapsed : Bool + } type PlacementResult @@ -28,7 +38,12 @@ type PlacementResult init : Bool -> String -> List a -> Column a init enabled_ name_ items_ = - Column enabled_ name_ items_ + Column + { enabled = enabled_ + , name = name_ + , items = items_ + , collapsed = False + } @@ -36,8 +51,13 @@ init enabled_ name_ items_ = hasName : String -> Column a -> Bool -hasName n (Column _ name_ _) = - n == name_ +hasName n = + (==) n << name + + +isCollapsed : Column a -> Bool +isCollapsed = + .collapsed << config isEmpty : Column a -> Bool @@ -46,15 +66,33 @@ isEmpty = isEnabled : Column a -> Bool -isEnabled (Column e _ _) = - e +isEnabled = + .enabled << config items : Column a -> List a -items (Column _ _ items_) = - items_ +items = + .items << config name : Column a -> String -name (Column _ name_ _) = - name_ +name = + .name << config + + + +-- MODIFICATION + + +collapseState : Bool -> Column a -> Column a +collapseState collapsed (Column c) = + Column { c | collapsed = collapsed } + + + +-- PRIVATE + + +config : Column a -> Config a +config (Column c) = + c diff --git a/src/DateBoardConfig.elm b/src/DateBoardConfig.elm index 5c696ef5..c6651a25 100644 --- a/src/DateBoardConfig.elm +++ b/src/DateBoardConfig.elm @@ -5,10 +5,12 @@ module DateBoardConfig exposing , decoder_v_0_3_0 , decoder_v_0_4_0 , decoder_v_0_5_0 + , decoder_v_0_9_0 , default , encoder ) +import CollapsedColumns exposing (CollapsedColumns) import Filter exposing (Filter, Polarity, Scope) import TsJson.Decode as TsDecode import TsJson.Encode as TsEncode @@ -26,6 +28,7 @@ type alias DateBoardConfig = , showFilteredTags : Bool , includeUndated : Bool , title : String + , collapsedColumns : CollapsedColumns } @@ -38,6 +41,7 @@ default = , showFilteredTags = True , includeUndated = True , title = "" + , collapsedColumns = CollapsedColumns.init } @@ -55,9 +59,23 @@ encoder = , TsEncode.required "showFilteredTags" .showFilteredTags TsEncode.bool , TsEncode.required "includeUndated" .includeUndated TsEncode.bool , TsEncode.required "title" .title TsEncode.string + , TsEncode.required "collapsedColumns" .collapsedColumns CollapsedColumns.encoder ] +decoder_v_0_9_0 : TsDecode.Decoder DateBoardConfig +decoder_v_0_9_0 = + TsDecode.succeed DateBoardConfig + |> TsDecode.andMap (TsDecode.field "completedCount" TsDecode.int) + |> TsDecode.andMap (TsDecode.field "filters" <| TsDecode.list Filter.decoder) + |> TsDecode.andMap (TsDecode.field "filterPolarity" <| Filter.polarityDecoder) + |> TsDecode.andMap (TsDecode.field "filterScope" <| Filter.scopeDecoder) + |> TsDecode.andMap (TsDecode.field "showFilteredTags" TsDecode.bool) + |> TsDecode.andMap (TsDecode.field "includeUndated" TsDecode.bool) + |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.field "collapsedColumns" CollapsedColumns.decoder) + + decoder_v_0_5_0 : TsDecode.Decoder DateBoardConfig decoder_v_0_5_0 = TsDecode.succeed DateBoardConfig @@ -68,6 +86,7 @@ decoder_v_0_5_0 = |> TsDecode.andMap (TsDecode.field "showFilteredTags" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "includeUndated" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_4_0 : TsDecode.Decoder DateBoardConfig @@ -80,6 +99,7 @@ decoder_v_0_4_0 = |> TsDecode.andMap (TsDecode.field "showFilteredTags" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "includeUndated" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_3_0 : TsDecode.Decoder DateBoardConfig @@ -92,6 +112,7 @@ decoder_v_0_3_0 = |> TsDecode.andMap (TsDecode.succeed True) |> TsDecode.andMap (TsDecode.field "includeUndated" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_2_0 : TsDecode.Decoder DateBoardConfig @@ -104,6 +125,7 @@ decoder_v_0_2_0 = |> TsDecode.andMap (TsDecode.succeed True) |> TsDecode.andMap (TsDecode.field "includeUndated" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_1_0 : TsDecode.Decoder DateBoardConfig @@ -116,3 +138,4 @@ decoder_v_0_1_0 = |> TsDecode.andMap (TsDecode.succeed True) |> TsDecode.andMap (TsDecode.field "includeUndated" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) diff --git a/src/GlobalSettings.elm b/src/GlobalSettings.elm index 76ec5514..3c52eb07 100644 --- a/src/GlobalSettings.elm +++ b/src/GlobalSettings.elm @@ -8,6 +8,7 @@ module GlobalSettings exposing , v_0_5_0_decoder , v_0_6_0_decoder , v_0_7_0_decoder + , v_0_9_0_decoder ) import ColumnNames exposing (ColumnNames) @@ -66,6 +67,11 @@ encoder = ] +v_0_9_0_decoder : TsDecode.Decoder GlobalSettings +v_0_9_0_decoder = + v_0_7_0_decoder + + v_0_7_0_decoder : TsDecode.Decoder GlobalSettings v_0_7_0_decoder = TsDecode.succeed GlobalSettings diff --git a/src/Page/Board.elm b/src/Page/Board.elm index 8e235882..084ac6bc 100644 --- a/src/Page/Board.elm +++ b/src/Page/Board.elm @@ -34,6 +34,7 @@ type Msg | TaskItemEditClicked String | TaskItemDeleteClicked String | TaskItemToggled String + | ToggleColumnCollapse Int Bool update : Msg -> Session -> ( Session, Cmd Msg, Session.Msg ) @@ -90,6 +91,17 @@ update msg session = , Session.NoOp ) + ToggleColumnCollapse columnIndex newState -> + let + newSession : Session + newSession = + Session.updateColumnCollapse columnIndex newState session + in + ( newSession + , InteropPorts.updateSettings <| Session.settings newSession + , Session.NoOp + ) + cmdIfHasTask : String -> Session -> (TaskItemFields -> Cmd b) -> Cmd b cmdIfHasTask id session cmd = @@ -120,8 +132,8 @@ view session = Session.globalSettings session |> .columnNames - currentIndex : Maybe Int - currentIndex = + currentBoardIndex : Maybe Int + currentBoardIndex = Boards.currentIndex boards timeWithZone : TimeWithZone @@ -130,7 +142,7 @@ view session = in Html.div [ attribute "dir" (TextDirection.toString <| Session.textDirection session) ] [ Html.ul [ class "card-board-tab-list" ] - (tabHeaders currentIndex boards) + (tabHeaders currentBoardIndex boards) , Html.div [ class "card-board-boards" ] (Boards.boardZipper boards |> SafeZipper.indexedMapSelectedAndRest (selectedBoardView timeWithZone) (boardView timeWithZone) @@ -140,11 +152,11 @@ view session = tabHeaders : Maybe Int -> Boards -> List (Html Msg) -tabHeaders currentIndex boards = +tabHeaders currentBoardIndex boards = let beforeHeaderClass : String beforeHeaderClass = - tabHeaderClass currentIndex -1 + tabHeaderClass currentBoardIndex -1 beforeFirst : Html Msg beforeFirst = @@ -162,7 +174,7 @@ tabHeaders currentIndex boards = afterHeaderClass : String afterHeaderClass = - tabHeaderClass currentIndex (Boards.length boards) + tabHeaderClass currentBoardIndex (Boards.length boards) afterLast : Html Msg afterLast = @@ -174,7 +186,7 @@ tabHeaders currentIndex boards = tabs : List (Html Msg) tabs = Boards.titles boards - |> SafeZipper.indexedMapSelectedAndRest selectedTabHeader (tabHeader currentIndex) + |> SafeZipper.indexedMapSelectedAndRest selectedTabHeader (tabHeader currentBoardIndex) |> SafeZipper.toList in beforeFirst :: List.append tabs [ afterLast ] @@ -189,11 +201,11 @@ selectedTabHeader _ title = tabHeader : Maybe Int -> Int -> String -> Html Msg -tabHeader currentIndex index title = +tabHeader currentBoardIndex index title = let headerClass : String headerClass = - tabHeaderClass currentIndex index + tabHeaderClass currentBoardIndex index in Html.li [ class ("card-board-tab-title" ++ headerClass) @@ -205,8 +217,8 @@ tabHeader currentIndex index title = tabHeaderClass : Maybe Int -> Int -> String -tabHeaderClass currentIndex index = - case currentIndex of +tabHeaderClass currentBoardIndex index = + case currentBoardIndex of Just i -> if index == i - 1 then " is-before-active" @@ -222,35 +234,69 @@ tabHeaderClass currentIndex index = boardView : TimeWithZone -> Int -> Board -> Html Msg -boardView timeWithZone index board = +boardView timeWithZone boardIndex board = Html.div [ class "card-board-board" , hidden True ] [ Html.div [ class "card-board-columns" ] (board - |> Board.columns timeWithZone index - |> List.map (\column -> columnView timeWithZone column) + |> Board.columns timeWithZone boardIndex + |> List.indexedMap (\index column -> columnView index timeWithZone column) ) ] selectedBoardView : TimeWithZone -> Int -> Board -> Html Msg -selectedBoardView timeWithZone index board = +selectedBoardView timeWithZone boardIndex board = Html.div [ class "card-board-board" ] [ Html.div [ class "card-board-columns" ] (board - |> Board.columns timeWithZone index - |> List.map (\column -> columnView timeWithZone column) + |> Board.columns timeWithZone boardIndex + |> List.indexedMap (\index column -> columnView index timeWithZone column) ) ] -columnView : TimeWithZone -> Column Card -> Html Msg -columnView timeWithZone column = - Html.div [ class "card-board-column" ] +columnView : Int -> TimeWithZone -> Column Card -> Html Msg +columnView columnIndex timeWithZone column = + let + columnCollapsedArrow : String + columnCollapsedArrow = + if Column.isCollapsed column then + "arrow-down" + + else + "arrow-right" + + columnCollapsedClass : String + columnCollapsedClass = + if Column.isCollapsed column then + " collapsed" + + else + "" + + columnCountString : String + columnCountString = + if Column.isCollapsed column then + "(" ++ (String.fromInt <| List.length <| Column.items column) ++ ")" + + else + "" + in + Html.div [ class <| "card-board-column" ++ columnCollapsedClass ] [ Html.div [ class "card-board-column-header" ] - [ Html.text <| Column.name column ] + [ Html.div + [ class columnCollapsedArrow + , onClick <| ToggleColumnCollapse columnIndex (not <| Column.isCollapsed column) + ] + [] + , Html.span [] + [ Html.text <| Column.name column ] + , Html.span [ class "sub-text" ] + [ Html.text <| columnCountString ] + ] , Html.Keyed.ul [ class "card-board-column-list" ] (List.map (cardView timeWithZone) (Column.items column)) ] diff --git a/src/Session.elm b/src/Session.elm index d8637c00..30e6aaad 100644 --- a/src/Session.elm +++ b/src/Session.elm @@ -23,6 +23,7 @@ module Session exposing , timeIs , timeWIthZoneIs , timeWithZone + , updateColumnCollapse , updatePath , updateSettings , updateTextDirection @@ -284,6 +285,17 @@ replaceTaskItems filePath updatedList ((Session config) as session) = updateTaskListState (State.Loaded (TaskList.replaceForFile filePath updatedList currentList)) session +updateColumnCollapse : Int -> Bool -> Session -> Session +updateColumnCollapse columnIndex isCollapsed (Session config) = + Session + { config + | settings = + Settings.updateCurrentBoard + (BoardConfig.collapseColumn columnIndex isCollapsed) + config.settings + } + + updatePath : String -> String -> Session -> Session updatePath oldPath newPath (Session config) = let diff --git a/src/Settings.elm b/src/Settings.elm index d48e408c..f83639cb 100644 --- a/src/Settings.elm +++ b/src/Settings.elm @@ -55,7 +55,7 @@ boardConfigs = currentVersion : Semver.Version currentVersion = - Semver.version 0 8 0 [] [] + Semver.version 0 9 0 [] [] globalSettings : Settings -> GlobalSettings @@ -151,8 +151,11 @@ semverEncoder = versionedSettingsDecoder : TsDecode.AndThenContinuation (String -> TsDecode.Decoder Settings) versionedSettingsDecoder = TsDecode.andThenInit - (\v_0_8_0 v_0_7_0 v_0_6_0 v_0_5_0 v_0_4_0 v_0_3_0 v_0_2_0 v_0_1_0 unsupportedVersion version_ -> + (\v_0_9_0 v_0_8_0 v_0_7_0 v_0_6_0 v_0_5_0 v_0_4_0 v_0_3_0 v_0_2_0 v_0_1_0 unsupportedVersion version_ -> case version_ of + "0.9.0" -> + v_0_9_0 + "0.8.0" -> v_0_8_0 @@ -180,6 +183,7 @@ versionedSettingsDecoder = _ -> unsupportedVersion ) + |> TsDecode.andThenDecoder (TsDecode.field "data" v_0_9_0_Decoder) |> TsDecode.andThenDecoder (TsDecode.field "data" v_0_8_0_Decoder) |> TsDecode.andThenDecoder (TsDecode.field "data" v_0_7_0_Decoder) |> TsDecode.andThenDecoder (TsDecode.field "data" v_0_6_0_Decoder) @@ -191,6 +195,14 @@ versionedSettingsDecoder = |> TsDecode.andThenDecoder (TsDecode.field "data" unsupportedVersionDecoder) +v_0_9_0_Decoder : TsDecode.Decoder Settings +v_0_9_0_Decoder = + TsDecode.succeed Settings + |> TsDecode.andMap (TsDecode.field "boardConfigs" (TsDecode.map SafeZipper.fromList (TsDecode.list BoardConfig.decoder_v_0_9_0))) + |> TsDecode.andMap (TsDecode.field "globalSettings" GlobalSettings.v_0_9_0_decoder) + |> TsDecode.andMap (TsDecode.succeed currentVersion) + + v_0_8_0_Decoder : TsDecode.Decoder Settings v_0_8_0_Decoder = TsDecode.succeed Settings diff --git a/src/TagBoardConfig.elm b/src/TagBoardConfig.elm index db44dbd2..fd3bc46c 100644 --- a/src/TagBoardConfig.elm +++ b/src/TagBoardConfig.elm @@ -7,10 +7,12 @@ module TagBoardConfig exposing , decoder_v_0_3_0 , decoder_v_0_4_0 , decoder_v_0_5_0 + , decoder_v_0_9_0 , default , encoder ) +import CollapsedColumns exposing (CollapsedColumns) import Filter exposing (Filter, Polarity, Scope) import Parser as P exposing ((|.), (|=), Parser) import ParserHelper @@ -34,6 +36,7 @@ type alias TagBoardConfig = , includeOthers : Bool , includeUntagged : Bool , title : String + , collapsedColumns : CollapsedColumns } @@ -55,6 +58,7 @@ default = , includeOthers = False , includeUntagged = False , title = "" + , collapsedColumns = CollapsedColumns.init } @@ -75,6 +79,7 @@ encoder = , TsEncode.required "includeOthers" .includeOthers TsEncode.bool , TsEncode.required "includeUntagged" .includeUntagged TsEncode.bool , TsEncode.required "title" .title TsEncode.string + , TsEncode.required "collapsedColumns" .collapsedColumns CollapsedColumns.encoder ] @@ -86,6 +91,22 @@ columnConfigEncoder = ] +decoder_v_0_9_0 : TsDecode.Decoder TagBoardConfig +decoder_v_0_9_0 = + TsDecode.succeed TagBoardConfig + |> TsDecode.andMap (TsDecode.field "columns" (TsDecode.list columnConfigDecoder)) + |> TsDecode.andMap (TsDecode.field "showColumnTags" TsDecode.bool) + |> TsDecode.andMap (TsDecode.field "completedCount" TsDecode.int) + |> TsDecode.andMap (TsDecode.field "filters" <| TsDecode.list Filter.decoder) + |> TsDecode.andMap (TsDecode.field "filterPolarity" <| Filter.polarityDecoder) + |> TsDecode.andMap (TsDecode.field "filterScope" <| Filter.scopeDecoder) + |> TsDecode.andMap (TsDecode.field "showFilteredTags" TsDecode.bool) + |> TsDecode.andMap (TsDecode.field "includeOthers" TsDecode.bool) + |> TsDecode.andMap (TsDecode.field "includeUntagged" TsDecode.bool) + |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.field "collapsedColumns" CollapsedColumns.decoder) + + decoder_v_0_5_0 : TsDecode.Decoder TagBoardConfig decoder_v_0_5_0 = TsDecode.succeed TagBoardConfig @@ -99,6 +120,7 @@ decoder_v_0_5_0 = |> TsDecode.andMap (TsDecode.field "includeOthers" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "includeUntagged" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_4_0 : TsDecode.Decoder TagBoardConfig @@ -114,6 +136,7 @@ decoder_v_0_4_0 = |> TsDecode.andMap (TsDecode.field "includeOthers" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "includeUntagged" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_3_0 : TsDecode.Decoder TagBoardConfig @@ -129,6 +152,7 @@ decoder_v_0_3_0 = |> TsDecode.andMap (TsDecode.field "includeOthers" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "includeUntagged" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_2_0 : TsDecode.Decoder TagBoardConfig @@ -144,6 +168,7 @@ decoder_v_0_2_0 = |> TsDecode.andMap (TsDecode.field "includeOthers" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "includeUntagged" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) decoder_v_0_1_0 : TsDecode.Decoder TagBoardConfig @@ -159,6 +184,7 @@ decoder_v_0_1_0 = |> TsDecode.andMap (TsDecode.field "includeOthers" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "includeUntagged" TsDecode.bool) |> TsDecode.andMap (TsDecode.field "title" TsDecode.string) + |> TsDecode.andMap (TsDecode.succeed CollapsedColumns.init) columnConfigDecoder : TsDecode.Decoder ColumnConfig diff --git a/styles.css b/styles.css index c1d40849..366aea84 100644 --- a/styles.css +++ b/styles.css @@ -107,22 +107,99 @@ li.is-after-active .card-board-tabs-inner { } .card-board-columns { - display: grid; - grid-auto-columns: minmax(20em, 1fr); - grid-auto-flow: column; - grid-gap: 1em; - margin-right: 1em; + display: flex; +} + +.card-board-columns::after { + content: ""; + flex: 0 0 1em; } .card-board-column { - padding: 1em; + flex: 0 0 auto; + padding: 0.6em 1em 1em 1em; + margin-right: 15px; + width: 20em; background-color: var(--background-secondary); border-radius: 3px; border: var(--border-width) solid var(--background-modifier-border); } + +div[dir=rtl] .card-board-column { + margin-left: 15px; + margin-right: 0; +} + +.card-board-column.collapsed { + width: 2em; + min-width: 2em; + flex-grow: 0; + overflow: visible; + margin: 0; + margin-right: 15px; + padding: 0.6em 0 0 0.3em; +} + +div[dir=rtl] .card-board-column.collapsed { + margin-left: 15px; + margin-right: 0; + padding: 0.6em 0.3em 0 0; +} + .card-board-column-header { font-weight: var(--bold-weight); - margin-bottom: 1em; + margin-bottom: 0.6em; + display: flex; + align-items: center; +} + + +div[dir=ltr] .card-board-column.collapsed .card-board-column-header { + writing-mode: vertical-lr; +} + +div[dir=rtl] .card-board-column.collapsed .card-board-column-header { + writing-mode: vertical-rl; +} + +.card-board-column.collapsed .card-board-column-header .sub-text { + font-weight: var(--normal-weight); + margin-top: 0.3em; + margin-bottom: 0.3em; +} + +.arrow-down { + width: 0; + height: 0; + border-left: 0.4em solid transparent; + border-right: 0.4em solid transparent; + border-top: 0.4em solid var(--text-normal); + margin: 0.5em 0 0.5em 0; + cursor: pointer; +} + +div[dir=rtl] .arrow-down { + order: 3; +} + +div[dir=ltr] .arrow-right { + width: 0; + height: 0; + border-top: 0.4em solid transparent; + border-bottom: 0.4em solid transparent; + border-left: 0.4em solid var(--text-normal); + margin: 0 0.4em 0 -0.2em; + cursor: pointer; +} + +div[dir=rtl] .arrow-right { + width: 0; + height: 0; + border-top: 0.4em solid transparent; + border-bottom: 0.4em solid transparent; + border-right: 0.4em solid var(--text-normal); + margin: 0 -0.2em 0 0.4em; + cursor: pointer; } ul.card-board-column-list { @@ -139,6 +216,10 @@ ul.card-board-column-list > li.card-board-card::before { content: ""; } +.card-board-column.collapsed .card-board-card { + display: none; +} + .card-board-card { border-radius: 3px; border: var(--border-width) solid var(--background-modifier-border); diff --git a/tests/BoardConfigTests.elm b/tests/BoardConfigTests.elm index a120ad2b..7e01f573 100644 --- a/tests/BoardConfigTests.elm +++ b/tests/BoardConfigTests.elm @@ -1,6 +1,7 @@ module BoardConfigTests exposing (suite) import BoardConfig exposing (BoardConfig) +import CollapsedColumns import DateBoardConfig exposing (DateBoardConfig) import Expect import Filter @@ -21,6 +22,7 @@ suite = , isForDateBoard , isForTagBoard , mapFilters + , collapseColumn , toggleIncludeOthers , toggleIncludeUndated , toggleIncludeUntagged @@ -141,6 +143,42 @@ mapFilters = ] +collapseColumn : Test +collapseColumn = + describe "collapseColumn" + [ test "collapses a column for a DateBoard config" <| + \() -> + BoardConfig.fromBoardType "dateBoard" "" + |> BoardConfig.collapseColumn 0 True + |> extractDateBoardConfig + |> Maybe.map .collapsedColumns + |> Expect.equal (Just <| (CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 True)) + , test "un-collapses a column for a DateBoard config" <| + \() -> + BoardConfig.fromBoardType "dateBoard" "" + |> BoardConfig.collapseColumn 0 True + |> BoardConfig.collapseColumn 0 False + |> extractDateBoardConfig + |> Maybe.map .collapsedColumns + |> Expect.equal (Just <| (CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 False)) + , test "sets the collapse state for a TagBoard config" <| + \() -> + BoardConfig.fromBoardType "tagBoard" "" + |> BoardConfig.collapseColumn 0 True + |> extractTagBoardConfig + |> Maybe.map .collapsedColumns + |> Expect.equal (Just <| (CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 True)) + , test "unsets the collapse state for a TagBoard config if toggled twice" <| + \() -> + BoardConfig.fromBoardType "tagBoard" "" + |> BoardConfig.collapseColumn 0 True + |> BoardConfig.collapseColumn 0 False + |> extractTagBoardConfig + |> Maybe.map .collapsedColumns + |> Expect.equal (Just <| (CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 False)) + ] + + toggleIncludeOthers : Test toggleIncludeOthers = describe "toggleIncludeOthers" diff --git a/tests/BoardTests.elm b/tests/BoardTests.elm index 4bf0e2c7..9050d21f 100644 --- a/tests/BoardTests.elm +++ b/tests/BoardTests.elm @@ -3,6 +3,8 @@ module BoardTests exposing (suite) import Board import BoardConfig import Card +import CollapsedColumns +import Column import ColumnNames import DateBoardConfig exposing (DateBoardConfig) import Expect @@ -28,471 +30,639 @@ suite = columnsDateBoard : Test columnsDateBoard = describe "columns - dateboard" - [ test "can filter tasks to be from a given file" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = - [ FilterHelpers.fileFilter "gg/xx/yy.md" - ] - , filterPolarity = Filter.Allow - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "an undated incomplete" - , "an undated incomplete with subtask" - , "incomplete with cTag" - , "incomplete with subtask with cTag" - , "untagged incomplete" - ] - , test "can filter tasks to NOT be from a given file" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , completedCount = 20 - , filters = - [ FilterHelpers.fileFilter "gg/xx/yy.md" - , FilterHelpers.fileFilter "x" - , FilterHelpers.fileFilter "b" - , FilterHelpers.fileFilter "c" - , FilterHelpers.fileFilter "d" - ] - , filterPolarity = Filter.Deny - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Completed" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "future complete" - , "yesterday complete" - , "invalid date complete" - ] - , test "can filter tasks to be from a given path" <| - \() -> - TaskListHelpers.taskListFromFile "aa/bb/c.ext" - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = [ FilterHelpers.pathFilter "aa/bb" ] - , filterPolarity = Filter.Allow - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal [ "c1" ] - , test "can filter tasks to NOT be from a given path" <| - \() -> - TaskListHelpers.taskListFromFile "aa/bb/c.ext" - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = [ FilterHelpers.pathFilter "aa/bb" ] - , filterPolarity = Filter.Deny - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal [] - , test "can filter tasks to have a given tag checking both top level and sub tasks" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = [ FilterHelpers.tagFilter "aTag" ] - , filterPolarity = Filter.Allow - , filterScope = Filter.Both - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal [ "invalid date incomplete", "invalid date incomplete with sub-task" ] - , test "can filter tasks to have a given tag checking just top level tasks" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = [ FilterHelpers.tagFilter "aTag" ] - , filterPolarity = Filter.Allow - , filterScope = Filter.TopLevelOnly - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal [ "invalid date incomplete" ] - , test "can filter tasks to have a given tag checking just sub-tasks" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = [ FilterHelpers.tagFilter "aTag" ] - , filterPolarity = Filter.Allow - , filterScope = Filter.SubTasksOnly - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal [ "invalid date incomplete with sub-task" ] - , test "can filter tasks to NOT have a given tag checking both the top level task and its sub-tasks" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = - [ FilterHelpers.tagFilter "aTag" - , FilterHelpers.tagFilter "cTag" - ] - , filterPolarity = Filter.Deny - , filterScope = Filter.Both - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "an undated incomplete" - , "an undated incomplete with subtask" - , "more undated incomplete" - , "untagged incomplete" - ] - , test "can filter tasks to NOT have a given tag checking just the top level task" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = - [ FilterHelpers.tagFilter "aTag" - , FilterHelpers.tagFilter "cTag" - ] - , filterPolarity = Filter.Deny - , filterScope = Filter.TopLevelOnly - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "an undated incomplete" - , "an undated incomplete with subtask" - , "incomplete with subtask with cTag" - , "invalid date incomplete with sub-task" - , "more undated incomplete" - , "untagged incomplete" - ] - , test "can filter tasks to NOT have a given tag checking just the sub tasks" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = - [ FilterHelpers.tagFilter "aTag" - , FilterHelpers.tagFilter "cTag" - ] - , filterPolarity = Filter.Deny - , filterScope = Filter.SubTasksOnly - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "an undated incomplete" - , "an undated incomplete with subtask" - , "incomplete with cTag" - , "invalid date incomplete" - , "more undated incomplete" - , "more undated incomplete with cTag" - , "untagged incomplete" - ] - , test "filters tasks that are either in a file or path AND have one of the given tags" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = - [ FilterHelpers.fileFilter "f" - , FilterHelpers.pathFilter "gg" - , FilterHelpers.tagFilter "aTag" - , FilterHelpers.tagFilter "bTag" - ] - , filterPolarity = Filter.Allow - , filterScope = Filter.Both - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "an undated incomplete" - , "an undated incomplete with subtask" - , "invalid date incomplete" - , "invalid date incomplete with sub-task" - ] - , test "filters tasks that are NOT in the given files and paths AND DO NOT have one of the given tags" <| - \() -> - TaskListHelpers.exampleDateBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.DateBoardConfig - { defaultDateBoardConfig - | includeUndated = True - , filters = - [ FilterHelpers.fileFilter "f" - , FilterHelpers.pathFilter "gg" - , FilterHelpers.tagFilter "aTag" - , FilterHelpers.tagFilter "bTag" - ] - , filterPolarity = Filter.Deny - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Undated" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "more undated incomplete with cTag" ] + [ describe "filtering" + [ test "can filter tasks to be from a given file" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.fileFilter "gg/xx/yy.md" + ] + , filterPolarity = Filter.Allow + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "an undated incomplete" + , "an undated incomplete with subtask" + , "incomplete with cTag" + , "incomplete with subtask with cTag" + , "untagged incomplete" + ] + , test "can filter tasks to NOT be from a given file" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , completedCount = 20 + , filters = + [ FilterHelpers.fileFilter "gg/xx/yy.md" + , FilterHelpers.fileFilter "x" + , FilterHelpers.fileFilter "b" + , FilterHelpers.fileFilter "c" + , FilterHelpers.fileFilter "d" + ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Completed" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "future complete" + , "yesterday complete" + , "invalid date complete" + ] + , test "can filter tasks to be from a given path" <| + \() -> + TaskListHelpers.taskListFromFile "aa/bb/c.ext" + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = [ FilterHelpers.pathFilter "aa/bb" ] + , filterPolarity = Filter.Allow + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal [ "c1" ] + , test "can filter tasks to NOT be from a given path" <| + \() -> + TaskListHelpers.taskListFromFile "aa/bb/c.ext" + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = [ FilterHelpers.pathFilter "aa/bb" ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal [] + , test "can filter tasks to have a given tag checking both top level and sub tasks" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = [ FilterHelpers.tagFilter "aTag" ] + , filterPolarity = Filter.Allow + , filterScope = Filter.Both + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal [ "invalid date incomplete", "invalid date incomplete with sub-task" ] + , test "can filter tasks to have a given tag checking just top level tasks" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = [ FilterHelpers.tagFilter "aTag" ] + , filterPolarity = Filter.Allow + , filterScope = Filter.TopLevelOnly + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal [ "invalid date incomplete" ] + , test "can filter tasks to have a given tag checking just sub-tasks" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = [ FilterHelpers.tagFilter "aTag" ] + , filterPolarity = Filter.Allow + , filterScope = Filter.SubTasksOnly + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal [ "invalid date incomplete with sub-task" ] + , test "can filter tasks to NOT have a given tag checking both the top level task and its sub-tasks" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.tagFilter "aTag" + , FilterHelpers.tagFilter "cTag" + ] + , filterPolarity = Filter.Deny + , filterScope = Filter.Both + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "an undated incomplete" + , "an undated incomplete with subtask" + , "more undated incomplete" + , "untagged incomplete" + ] + , test "can filter tasks to NOT have a given tag checking just the top level task" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.tagFilter "aTag" + , FilterHelpers.tagFilter "cTag" + ] + , filterPolarity = Filter.Deny + , filterScope = Filter.TopLevelOnly + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "an undated incomplete" + , "an undated incomplete with subtask" + , "incomplete with subtask with cTag" + , "invalid date incomplete with sub-task" + , "more undated incomplete" + , "untagged incomplete" + ] + , test "can filter tasks to NOT have a given tag checking just the sub tasks" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.tagFilter "aTag" + , FilterHelpers.tagFilter "cTag" + ] + , filterPolarity = Filter.Deny + , filterScope = Filter.SubTasksOnly + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "an undated incomplete" + , "an undated incomplete with subtask" + , "incomplete with cTag" + , "invalid date incomplete" + , "more undated incomplete" + , "more undated incomplete with cTag" + , "untagged incomplete" + ] + , test "filters tasks that are either in a file or path AND have one of the given tags" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.fileFilter "f" + , FilterHelpers.pathFilter "gg" + , FilterHelpers.tagFilter "aTag" + , FilterHelpers.tagFilter "bTag" + ] + , filterPolarity = Filter.Allow + , filterScope = Filter.Both + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "an undated incomplete" + , "an undated incomplete with subtask" + , "invalid date incomplete" + , "invalid date incomplete with sub-task" + ] + , test "filters tasks that are NOT in the given files and paths AND DO NOT have one of the given tags" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.fileFilter "f" + , FilterHelpers.pathFilter "gg" + , FilterHelpers.tagFilter "aTag" + , FilterHelpers.tagFilter "bTag" + ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Undated" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "more undated incomplete with cTag" ] + ] + , describe "collapsing columns" + [ test "does not collapse an initialized column containing cards" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = [] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Undated" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just False) + , test "does not collapse an initialized column with no cards" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.fileFilter "f" + , FilterHelpers.pathFilter "gg" + , FilterHelpers.tagFilter "aTag" + , FilterHelpers.tagFilter "bTag" + , FilterHelpers.tagFilter "cTag" + ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Undated" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just False) + , test "collapses a column containing cards if is has been set to collapsed" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = [] + , filterPolarity = Filter.Deny + , collapsedColumns = CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 True + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Undated" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just True) + , test "collapses a column with no cards if it has been set as collapsed" <| + \() -> + TaskListHelpers.exampleDateBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.DateBoardConfig + { defaultDateBoardConfig + | includeUndated = True + , filters = + [ FilterHelpers.fileFilter "f" + , FilterHelpers.pathFilter "gg" + , FilterHelpers.tagFilter "aTag" + , FilterHelpers.tagFilter "bTag" + , FilterHelpers.tagFilter "cTag" + ] + , filterPolarity = Filter.Deny + , collapsedColumns = CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 True + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Undated" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just True) + ] ] columnsTagBoard : Test columnsTagBoard = describe "columns - tagboard" - [ test "can filter tasks to be from a given file" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = [ FilterHelpers.fileFilter "a" ] - , filterPolarity = Filter.Allow - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "a.tag1" - , "a.tag2" - , "a.tag3" - ] - , test "can filter tasks to NOT be from a given file" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = [ FilterHelpers.fileFilter "a" ] - , filterPolarity = Filter.Deny - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "b.tag1" - , "b.tag2" - , "b.tag3" - , "c.tag1" - , "c.tag2" - , "c.tag3" - ] - , test "can filter tasks to be from a given path" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = [ FilterHelpers.pathFilter "aa" ] - , filterPolarity = Filter.Allow - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "c.tag1" - , "c.tag2" - , "c.tag3" - ] - , test "can filter tasks to NOT be from a given path" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = [ FilterHelpers.pathFilter "aa" ] - , filterPolarity = Filter.Deny - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "a.tag1" - , "a.tag2" - , "a.tag3" - , "b.tag1" - , "b.tag2" - , "b.tag3" - ] - , test "can filter tasks to have a given tag" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = [ FilterHelpers.tagFilter "tag1" ] - , filterPolarity = Filter.Allow - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "a.tag1" - , "b.tag1" - , "c.tag1" - ] - , test "can filter tasks to NOT have a given tag" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = [ FilterHelpers.tagFilter "tag1" ] - , filterPolarity = Filter.Deny - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "a.tag2" - , "a.tag3" - , "b.tag2" - , "b.tag3" - , "c.tag2" - , "c.tag3" - ] - , test "filters tasks that are either in a file or path AND have one of the given tags" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = - [ FilterHelpers.fileFilter "a" - , FilterHelpers.pathFilter "aa" - , FilterHelpers.tagFilter "tag1" - , FilterHelpers.tagFilter "tag2" - ] - , filterPolarity = Filter.Allow - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal - [ "a.tag1" - , "a.tag2" - , "c.tag1" - , "c.tag2" - ] - , test "filters tasks that are NOT in any of the given file or path AND DO NOT have one of the given tags" <| - \() -> - TaskListHelpers.exampleTagBoardTaskList - |> Board.init - ColumnNames.default - (BoardConfig.TagBoardConfig - { defaultTagBoardConfig - | includeOthers = True - , filters = - [ FilterHelpers.fileFilter "a" - , FilterHelpers.pathFilter "aa" - , FilterHelpers.tagFilter "tag1" - , FilterHelpers.tagFilter "tag2" - ] - , filterPolarity = Filter.Deny - } - ) - |> Board.columns DateTimeHelpers.nowWithZone 0 - |> BoardHelpers.thingsInColumn "Others" - |> List.map Card.taskItem - |> List.map TaskItem.title - |> Expect.equal [ "b.tag3" ] + [ describe "filtering" + [ test "can filter tasks to be from a given file" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = [ FilterHelpers.fileFilter "a" ] + , filterPolarity = Filter.Allow + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "a.tag1" + , "a.tag2" + , "a.tag3" + ] + , test "can filter tasks to NOT be from a given file" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = [ FilterHelpers.fileFilter "a" ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "b.tag1" + , "b.tag2" + , "b.tag3" + , "c.tag1" + , "c.tag2" + , "c.tag3" + ] + , test "can filter tasks to be from a given path" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = [ FilterHelpers.pathFilter "aa" ] + , filterPolarity = Filter.Allow + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "c.tag1" + , "c.tag2" + , "c.tag3" + ] + , test "can filter tasks to NOT be from a given path" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = [ FilterHelpers.pathFilter "aa" ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "a.tag1" + , "a.tag2" + , "a.tag3" + , "b.tag1" + , "b.tag2" + , "b.tag3" + ] + , test "can filter tasks to have a given tag" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = [ FilterHelpers.tagFilter "tag1" ] + , filterPolarity = Filter.Allow + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "a.tag1" + , "b.tag1" + , "c.tag1" + ] + , test "can filter tasks to NOT have a given tag" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = [ FilterHelpers.tagFilter "tag1" ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "a.tag2" + , "a.tag3" + , "b.tag2" + , "b.tag3" + , "c.tag2" + , "c.tag3" + ] + , test "filters tasks that are either in a file or path AND have one of the given tags" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = + [ FilterHelpers.fileFilter "a" + , FilterHelpers.pathFilter "aa" + , FilterHelpers.tagFilter "tag1" + , FilterHelpers.tagFilter "tag2" + ] + , filterPolarity = Filter.Allow + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal + [ "a.tag1" + , "a.tag2" + , "c.tag1" + , "c.tag2" + ] + , test "filters tasks that are NOT in any of the given file or path AND DO NOT have one of the given tags" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeOthers = True + , filters = + [ FilterHelpers.fileFilter "a" + , FilterHelpers.pathFilter "aa" + , FilterHelpers.tagFilter "tag1" + , FilterHelpers.tagFilter "tag2" + ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.thingsInColumn "Others" + |> List.map Card.taskItem + |> List.map TaskItem.title + |> Expect.equal [ "b.tag3" ] + ] + , describe "collapsing columns" + [ test "does not collapse an initialized column containing cards" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeUntagged = False + , includeOthers = True + , filters = [] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Others" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just False) + , test "does not collapse an initialized column with no cards" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeUntagged = False + , includeOthers = True + , filters = + [ FilterHelpers.fileFilter "a" + , FilterHelpers.pathFilter "aa" + , FilterHelpers.tagFilter "tag1" + , FilterHelpers.tagFilter "tag2" + , FilterHelpers.tagFilter "tag3" + ] + , filterPolarity = Filter.Deny + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Others" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just False) + , test "collapses a column containing cards if it has been set to collapsed" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeUntagged = False + , includeOthers = True + , filters = [] + , filterPolarity = Filter.Deny + , collapsedColumns = CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 True + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Others" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just True) + , test "collapses a column with no cards if it has been set to collapsed" <| + \() -> + TaskListHelpers.exampleTagBoardTaskList + |> Board.init + ColumnNames.default + (BoardConfig.TagBoardConfig + { defaultTagBoardConfig + | includeUntagged = False + , includeOthers = True + , filters = + [ FilterHelpers.fileFilter "a" + , FilterHelpers.pathFilter "aa" + , FilterHelpers.tagFilter "tag1" + , FilterHelpers.tagFilter "tag2" + , FilterHelpers.tagFilter "tag3" + ] + , filterPolarity = Filter.Deny + , collapsedColumns = CollapsedColumns.init |> CollapsedColumns.collapseColumn 0 True + } + ) + |> Board.columns DateTimeHelpers.nowWithZone 0 + |> BoardHelpers.columnTitled "Others" + |> Maybe.map Column.isCollapsed + |> Expect.equal (Just True) + ] ] diff --git a/tests/CollapsedColumnsTests.elm b/tests/CollapsedColumnsTests.elm new file mode 100644 index 00000000..59e3ad07 --- /dev/null +++ b/tests/CollapsedColumnsTests.elm @@ -0,0 +1,94 @@ +module CollapsedColumnsTests exposing (suite) + +import CollapsedColumns +import Expect +import Fuzz +import Helpers.DecodeHelpers as DecodeHelpers +import Test exposing (..) +import TsJson.Encode as TsEncode + + +suite : Test +suite = + concat + [ columnIsCollapsed + , decoder + , encoder + ] + + +columnIsCollapsed : Test +columnIsCollapsed = + describe "columnIsCollapsed" + [ fuzz (Fuzz.intRange 0 20) "returns False for any column if it has just been initialized" <| + \fuzzedInt -> + CollapsedColumns.init + |> CollapsedColumns.columnIsCollapsed fuzzedInt + |> Expect.equal False + , fuzz (Fuzz.intRange 0 20) "returns True for any column if it has been set to collapsed" <| + \fuzzedInt -> + CollapsedColumns.init + |> CollapsedColumns.collapseColumn fuzzedInt True + |> CollapsedColumns.columnIsCollapsed fuzzedInt + |> Expect.equal True + , fuzz (Fuzz.intRange 0 20) "returns False for any column if it has been set to not be collapsed" <| + \fuzzedInt -> + CollapsedColumns.init + |> CollapsedColumns.collapseColumn fuzzedInt True + |> CollapsedColumns.collapseColumn fuzzedInt False + |> CollapsedColumns.columnIsCollapsed fuzzedInt + |> Expect.equal False + , fuzz (Fuzz.intRange 1 20) "collapsing a column does not affect other columns" <| + \fuzzedInt -> + CollapsedColumns.init + |> CollapsedColumns.collapseColumn fuzzedInt True + |> CollapsedColumns.columnIsCollapsed 0 + |> Expect.equal False + ] + + +decoder : Test +decoder = + describe "decoder" + [ test "decodes an empty array" <| + \() -> + "[]" + |> DecodeHelpers.runDecoder CollapsedColumns.decoder + |> .decoded + |> Expect.equal (Ok CollapsedColumns.init) + , test "decodes '[1,3,4]'" <| + \() -> + "[1,3,4]" + |> DecodeHelpers.runDecoder CollapsedColumns.decoder + |> .decoded + |> Expect.equal + (Ok + (CollapsedColumns.init + |> CollapsedColumns.collapseColumn 1 True + |> CollapsedColumns.collapseColumn 3 True + |> CollapsedColumns.collapseColumn 4 True + ) + ) + ] + + +encoder : Test +encoder = + describe "encoder" + [ test "encodes an initialized CollapsedColumns" <| + \() -> + CollapsedColumns.init + |> TsEncode.runExample CollapsedColumns.encoder + |> .output + |> Expect.equal "[]" + , test "encodes an CollapsedColumns with some collapsed columns" <| + \() -> + (CollapsedColumns.init + |> CollapsedColumns.collapseColumn 1 True + |> CollapsedColumns.collapseColumn 3 True + |> CollapsedColumns.collapseColumn 4 True + ) + |> TsEncode.runExample CollapsedColumns.encoder + |> .output + |> Expect.equal "[1,3,4]" + ] diff --git a/tests/ColumnTests.elm b/tests/ColumnTests.elm index f02e729c..13f05821 100644 --- a/tests/ColumnTests.elm +++ b/tests/ColumnTests.elm @@ -9,6 +9,7 @@ suite : Test suite = concat [ name + , isCollapsed , isEmpty , isEnabled , items @@ -27,6 +28,48 @@ name = ] +isCollapsed : Test +isCollapsed = + describe "isCollapsed" + [ test "returns False for an initialised empty Column" <| + \() -> + Column.init True "a name" [] + |> Column.isCollapsed + |> Expect.equal False + , test "returns False for an initialised non-empty Column" <| + \() -> + Column.init True "a name" [ 1 ] + |> Column.isCollapsed + |> Expect.equal False + , test "returns True for an empty Column which has been set to collapsed" <| + \() -> + Column.init True "a name" [] + |> Column.collapseState True + |> Column.isCollapsed + |> Expect.equal True + , test "returns False for an empty Column which has been set to not collapsed" <| + \() -> + Column.init True "a name" [] + |> Column.collapseState True + |> Column.collapseState False + |> Column.isCollapsed + |> Expect.equal False + , test "returns True for a non-empty Column which has been set to collapsed" <| + \() -> + Column.init True "a name" [ 1 ] + |> Column.collapseState True + |> Column.isCollapsed + |> Expect.equal True + , test "returns False for a non-empty Column which has been set to not collapsed" <| + \() -> + Column.init True "a name" [ 1 ] + |> Column.collapseState True + |> Column.collapseState False + |> Column.isCollapsed + |> Expect.equal False + ] + + isEmpty : Test isEmpty = describe "isEmpty" diff --git a/tests/Helpers/BoardConfigHelpers.elm b/tests/Helpers/BoardConfigHelpers.elm index 016b12f9..f23d0cb7 100644 --- a/tests/Helpers/BoardConfigHelpers.elm +++ b/tests/Helpers/BoardConfigHelpers.elm @@ -7,6 +7,7 @@ module Helpers.BoardConfigHelpers exposing ) import BoardConfig exposing (BoardConfig) +import CollapsedColumns import DateBoardConfig exposing (DateBoardConfig) import Filter import Helpers.FilterHelpers as FilterHelpers @@ -22,6 +23,7 @@ defaultDateBoardConfig = , showFilteredTags = True , includeUndated = False , title = "Date Board Title" + , collapsedColumns = CollapsedColumns.init } @@ -39,6 +41,7 @@ exampleDateBoardConfig = , showFilteredTags = True , includeUndated = False , title = "Date Board Title" + , collapsedColumns = CollapsedColumns.init } @@ -54,6 +57,7 @@ defaultTagBoardConfig = , includeOthers = False , includeUntagged = False , title = "Tag Board Title" + , collapsedColumns = CollapsedColumns.init } @@ -69,4 +73,5 @@ exampleTagBoardConfig = , includeOthers = False , includeUntagged = True , title = "Tag Board Title" + , collapsedColumns = CollapsedColumns.init } diff --git a/tests/Helpers/BoardHelpers.elm b/tests/Helpers/BoardHelpers.elm index 17e1d56f..8284d725 100644 --- a/tests/Helpers/BoardHelpers.elm +++ b/tests/Helpers/BoardHelpers.elm @@ -1,11 +1,19 @@ module Helpers.BoardHelpers exposing - ( thingsInColumn + ( columnTitled + , thingsInColumn , thingsInColumns ) import Column exposing (Column) +columnTitled : String -> List (Column a) -> Maybe (Column a) +columnTitled columnName cardsInColumns = + cardsInColumns + |> List.filter (\c -> Column.hasName columnName c) + |> List.head + + thingsInColumns : List String -> List (Column a) -> List a thingsInColumns columnNames cardsInColumns = List.concatMap (\columnName -> thingsInColumn columnName cardsInColumns) columnNames diff --git a/tests/InteropDefinitionsTests.elm b/tests/InteropDefinitionsTests.elm index b52bf6d2..037bbe14 100644 --- a/tests/InteropDefinitionsTests.elm +++ b/tests/InteropDefinitionsTests.elm @@ -1,6 +1,7 @@ module InteropDefinitionsTests exposing (suite) import BoardConfig +import CollapsedColumns import ColumnNames import DataviewTaskCompletion import Expect @@ -29,7 +30,61 @@ suite = flagsTests : Test flagsTests = describe "interop.flags (decoding)" - [ test "decodes valid flags for settings version 0.8.0" <| + [ test "decodes valid flags for settings version 0.9.0" <| + \() -> + """{"now":11,"zone":22,"rightToLeft":false,"dataviewTaskCompletion":{"taskCompletionTracking":true,"taskCompletionUseEmojiShorthand":false,"taskCompletionText":"completion"},"settings":{"version":"0.9.0","data":{"globalSettings":{"taskCompletionFormat":"ObsidianTasks","columnNames":{"today":"Do Today","tomorrow":"","future":"The Future","undated":"","others":"The Others","untagged":"","completed":"Done"}},"boardConfigs":[{"tag":"dateBoardConfig","data":{"completedCount":4,"filters":[{"tag":"pathFilter","data":"a/path"},{"tag":"tagFilter","data":"tag1"}],"filterPolarity":"Deny","filterScope":"TopLevelOnly","showFilteredTags":true,"includeUndated":true,"collapsedColumns":[],"title":"date board title"}},{"tag":"tagBoardConfig","data":{"columns":[{"tag":"tag 1","displayTitle":"title 1"}],"showColumnTags":false,"completedCount":5,"filters":[{"tag":"pathFilter","data":"b/path"},{"tag":"tagFilter","data":"tag2"}],"filterPolarity":"Allow","filterScope":"SubTasksOnly","showFilteredTags":false,"includeOthers":false,"includeUntagged":true,"collapsedColumns":[1,4],"title":"tag board title"}}]}}}""" + |> DecodeHelpers.runDecoder interop.flags + |> .decoded + |> Expect.equal + (Ok + { settings = + { version = Semver.version 0 9 0 [] [] + , boardConfigs = + SafeZipper.fromList + [ BoardConfig.DateBoardConfig + { completedCount = 4 + , filters = [ FilterHelpers.pathFilter "a/path", FilterHelpers.tagFilter "tag1" ] + , filterPolarity = Filter.Deny + , filterScope = Filter.TopLevelOnly + , showFilteredTags = True + , includeUndated = True + , collapsedColumns = CollapsedColumns.init + , title = "date board title" + } + , BoardConfig.TagBoardConfig + { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] + , showColumnTags = False + , completedCount = 5 + , filters = [ FilterHelpers.pathFilter "b/path", FilterHelpers.tagFilter "tag2" ] + , filterPolarity = Filter.Allow + , filterScope = Filter.SubTasksOnly + , showFilteredTags = False + , includeOthers = False + , includeUntagged = True + , collapsedColumns = CollapsedColumns.init |> CollapsedColumns.collapseColumn 1 True |> CollapsedColumns.collapseColumn 4 True + , title = "tag board title" + } + ] + , globalSettings = + { taskCompletionFormat = GlobalSettings.ObsidianTasks + , columnNames = + { today = Just "Do Today" + , tomorrow = Nothing + , future = Just "The Future" + , undated = Nothing + , others = Just "The Others" + , untagged = Nothing + , completed = Just "Done" + } + } + } + , dataviewTaskCompletion = DataviewTaskCompletion.Text "completion" + , rightToLeft = False + , now = 11 + , zone = 22 + } + ) + , test "decodes valid flags for settings version 0.8.0" <| \() -> """{"now":11,"zone":22,"rightToLeft":false,"dataviewTaskCompletion":{"taskCompletionTracking":true,"taskCompletionUseEmojiShorthand":false,"taskCompletionText":"completion"},"settings":{"version":"0.8.0","data":{"globalSettings":{"taskCompletionFormat":"ObsidianTasks","columnNames":{"today":"Do Today","tomorrow":"","future":"The Future","undated":"","others":"The Others","untagged":"","completed":"Done"}},"boardConfigs":[{"tag":"dateBoardConfig","data":{"completedCount":4,"filters":[{"tag":"pathFilter","data":"a/path"},{"tag":"tagFilter","data":"tag1"}],"filterPolarity":"Deny","filterScope":"TopLevelOnly","showFilteredTags":true,"includeUndated":true,"title":"date board title"}},{"tag":"tagBoardConfig","data":{"columns":[{"tag":"tag 1","displayTitle":"title 1"}],"showColumnTags":false,"completedCount":5,"filters":[{"tag":"pathFilter","data":"b/path"},{"tag":"tagFilter","data":"tag2"}],"filterPolarity":"Allow","filterScope":"SubTasksOnly","showFilteredTags":false,"includeOthers":false,"includeUntagged":true,"title":"tag board title"}}]}}}""" |> DecodeHelpers.runDecoder interop.flags @@ -37,7 +92,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -48,6 +103,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -60,6 +116,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = @@ -89,7 +146,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -100,6 +157,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -112,6 +170,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = @@ -141,7 +200,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -152,6 +211,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -164,6 +224,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = @@ -185,7 +246,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -196,6 +257,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -208,6 +270,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = @@ -229,7 +292,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -240,6 +303,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -252,6 +316,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = GlobalSettings.default @@ -270,7 +335,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -281,6 +346,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -293,6 +359,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = GlobalSettings.default @@ -311,7 +378,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -322,6 +389,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -334,6 +402,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = GlobalSettings.default @@ -352,7 +421,7 @@ flagsTests = |> Expect.equal (Ok { settings = - { version = Semver.version 0 8 0 [] [] + { version = Semver.version 0 9 0 [] [] , boardConfigs = SafeZipper.fromList [ BoardConfig.DateBoardConfig @@ -363,6 +432,7 @@ flagsTests = , showFilteredTags = True , includeUndated = True , title = "date board title" + , collapsedColumns = CollapsedColumns.init } , BoardConfig.TagBoardConfig { columns = [ { displayTitle = "title 1", tag = "tag 1" } ] @@ -375,6 +445,7 @@ flagsTests = , includeOthers = False , includeUntagged = True , title = "tag board title" + , collapsedColumns = CollapsedColumns.init } ] , globalSettings = GlobalSettings.default @@ -534,49 +605,49 @@ toElmTests = """{"tag":"settingsUpdated","data":{"version":"0.8.0","data":{"boardConfigs":[],"globalSettings":{"taskCompletionFormat":"ObsidianDataview","columnNames":{"today":"","tomorrow":"","future":"","undated":"","others":"","untagged":"","completed":""}}}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = { taskCompletionFormat = GlobalSettings.ObsidianDataview, columnNames = ColumnNames.default } }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = { taskCompletionFormat = GlobalSettings.ObsidianDataview, columnNames = ColumnNames.default } }) , test "decodes version 0.7.0 settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"0.7.0","data":{"boardConfigs":[],"globalSettings":{"taskCompletionFormat":"ObsidianDataview","columnNames":{"today":"","tomorrow":"","future":"","undated":"","others":"","untagged":"","completed":""}}}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = { taskCompletionFormat = GlobalSettings.ObsidianDataview, columnNames = ColumnNames.default } }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = { taskCompletionFormat = GlobalSettings.ObsidianDataview, columnNames = ColumnNames.default } }) , test "decodes version 0.6.0 settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"0.6.0","data":{"boardConfigs":[],"globalSettings":{"taskCompletionFormat":"ObsidianDataview"}}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = { taskCompletionFormat = GlobalSettings.ObsidianDataview, columnNames = ColumnNames.default } }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = { taskCompletionFormat = GlobalSettings.ObsidianDataview, columnNames = ColumnNames.default } }) , test "decodes version 0.5.0 settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"0.5.0","data":{"boardConfigs":[],"globalSettings":{"taskUpdateFormat":"ObsidianCardBoard"}}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) , test "decodes version 0.4.0 settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"0.4.0","data":{"boardConfigs":[]}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) , test "decodes version 0.3.0 settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"0.3.0","data":{"boardConfigs":[]}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) , test "decodes version 0.2.0 settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"0.2.0","data":{"boardConfigs":[],"globalSettings":{"hideCompletedSubtasks":false,"ignorePaths":[],"subTaskDisplayLimit":null}}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) , test "decodes version 0.1.0 settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"0.1.0","data":{"boardConfigs":[]}}}""" |> DecodeHelpers.runDecoder interop.toElm |> .decoded - |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 8 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) + |> Expect.equal (Ok <| InteropDefinitions.SettingsUpdated { version = Semver.version 0 9 0 [] [], boardConfigs = SafeZipper.fromList [], globalSettings = GlobalSettings.default }) , test "fails to decode an unsupported version of settings data" <| \() -> """{"tag":"settingsUpdated","data":{"version":"99999.0.0","data":{"boardConfigs":[]}}}""" diff --git a/tests/SettingsStateTests.elm b/tests/SettingsStateTests.elm index 793a8158..8141240a 100644 --- a/tests/SettingsStateTests.elm +++ b/tests/SettingsStateTests.elm @@ -1,6 +1,7 @@ module SettingsStateTests exposing (suite) import BoardConfig exposing (BoardConfig) +import CollapsedColumns import ColumnNames import DateBoardConfig exposing (DateBoardConfig) import Expect @@ -506,6 +507,7 @@ exampleDateBoardConfig = , showFilteredTags = True , includeUndated = False , title = "Date Board Title" + , collapsedColumns = CollapsedColumns.init } @@ -521,4 +523,5 @@ exampleTagBoardConfig = , includeOthers = False , includeUntagged = True , title = "Tag Board Title" + , collapsedColumns = CollapsedColumns.init } diff --git a/tests/SettingsTests.elm b/tests/SettingsTests.elm index 658b3c3c..2c86195d 100644 --- a/tests/SettingsTests.elm +++ b/tests/SettingsTests.elm @@ -24,11 +24,11 @@ suite = currentVersion : Test currentVersion = describe "currentVersion" - [ test "is 0.8.0" <| + [ test "is 0.9.0" <| \() -> Settings.currentVersion |> Semver.print - |> Expect.equal "0.8.0" + |> Expect.equal "0.9.0" ]