summaryrefslogtreecommitdiff
path: root/elm/AdvSearch/RDate.elm
blob: a5eeed25b42eef9fa001d3ba97cc8d38e669a616 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
module AdvSearch.RDate exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)
import Lib.Html exposing (..)
import Lib.RDate as R
import AdvSearch.Query exposing (..)


type alias Model =
  { op    : Op
  , fuzzy : Bool
  , date  : R.RDate
  }


type Msg
  = MOp Op Bool
  | Fuzzy Bool
  | Date R.RDate


update : Msg -> Model -> Model
update msg model =
  case msg of
    MOp o _ -> { model | op = o }
    Fuzzy f -> { model | fuzzy = f }
    Date d  -> { model | date = d }


init : Data -> (Data, Model)
init dat = (dat,
  { op    = Le
  , fuzzy = True
  , date  = 1
  })


toQuery : Model -> Maybe Query
toQuery model = Just <|
  let f o date = QInt 7 o date
      e = R.expand model.date
      ystart = R.compact { y=e.y, m=  1, d= 1 }
      mstart = R.compact { y=e.y, m=e.m, d= 1 }
  in
  if not model.fuzzy || e.y == 0 || e.y == 9999 then f model.op model.date else
  case (model.op, e.m, e.d) of
    -- Fuzzy (in)equality turns into a date range
    (Eq, 99, 99) -> QAnd [ f Ge ystart, f Le model.date ]
    (Eq,  _, 99) -> QAnd [ f Ge mstart, f Le model.date ]
    (Ne, 99, 99) -> QOr  [ f Lt ystart, f Gt model.date ]
    (Ne,  _, 99) -> QOr  [ f Lt mstart, f Gt model.date ]
    -- Fuzzy Ge and Lt just need the date adjusted to the correct boundary
    (Ge, 99, 99) -> f Ge ystart
    (Ge,  _, 99) -> f Ge mstart
    (Lt, 99, 99) -> f Lt ystart
    (Lt,  _, 99) -> f Lt mstart
    _ -> f model.op model.date


fromQuery : Data -> Query -> Maybe (Data, Model)
fromQuery dat q =
  let m op fuzzy date = Just (dat, { op = op, fuzzy = fuzzy, date = date })
      fuzzyNeq op start end =
        let se = R.expand start
            ee = R.expand end
        in  if se.y == ee.y && (ee.m < 99 || se.m == 1) && se.d == 1 && ee.d == 99 then m op True end else Nothing
      canFuzzy o e = e.y == 0 || e.y == 9999 || e.d /= 99 || o == Gt || o == Le
  in
  case q of
    QAnd [QInt 7 Ge start, QInt 7 Le end] -> fuzzyNeq Eq start end
    QOr  [QInt 7 Lt start, QInt 7 Gt end] -> fuzzyNeq Ne start end
    QInt 7 o v -> m o (canFuzzy o (R.expand v)) v
    _ -> Nothing


view : Model -> (Html Msg, () -> List (Html Msg))
view model =
  ( text <| showOp model.op ++ " " ++ R.format (R.expand model.date)
  , \() ->
    [ div [ class "advheader", style "width" "290px" ]
      [ h3 [] [ text "Release date" ]
      , div [ class "opts" ]
        [ div [ class "opselect" ] <|
          List.map (\op ->
            if model.op == op then b [] [ text (showOp op) ] else a [ href "#", onClickD (MOp op True) ] [ text (showOp op) ]
          ) [Eq, Ne, Ge, Gt, Le, Lt]
        , if (R.expand model.date).d /= 99 then text "" else
          linkRadio model.fuzzy Fuzzy [ span [ title
            <| "Without fuzzy matching, partial dates will always match after the last date of the chosen time period, "
            ++ "e.g. \"< 2010-10\" would also match anything released in 2010-10 and \"= 2010-10\" would only match releases for which we don't know the exact date."
            ++ "\n\nFuzzy match will adjust the query to do what you mean."
          ] [ text "fuzzy" ] ]
        ]
      ]
    , R.view model.date True True Date
    ]
  )