-
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
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
-
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
-
172
-
173
-
174
-
175
-
176
-
177
-
178
-
179
-
180
-
181
-
182
-
183
-
184
-
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-- Copyright 2026 Shota FUJI
--
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
--
-- SPDX-License-Identifier: MPL-2.0
module Models.PWS01.QueryHealer exposing (Model, Msg, init, update, view)
import Dict exposing (Dict)
import Dict.Any
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.LivingStandard exposing (..)
import Models.PWS01.Parameters as Parameters
import Models.PWS01.Parameters.Key as Key exposing (Key)
import Models.PWS01.Parameters.Parser as Parser exposing (Error(..))
import Preferences exposing (DictKeyMode(..), Preferences)
import Url exposing (Url)
import Url.SearchParams as SearchParams
-- MODEL
type alias Model =
{ errors : Parser.Errors
, searchParams : Dict String String
, url : Url
, preferences : Preferences
}
init : Url -> Preferences -> Parser.Errors -> Model
init url preferences errors =
{ errors = errors
, searchParams =
url.query
|> Maybe.map SearchParams.parse
|> Maybe.withDefault Dict.empty
, url = url
, preferences = preferences
}
-- UPDATE
type Msg
= NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
-- VIEW
defaults : DictKeyMode -> Dict String String
defaults mode =
Dict.union
(Parameters.toDict mode Parameters.default)
(Parameters.fallbackValues mode)
row : Model -> Key -> Error -> Html Msg
row { searchParams, url, preferences } key error =
let
setLinkText : String -> Html msg
setLinkText value =
text ("Set to \"" ++ value ++ "\". ")
withDefault =
case Parameters.getKey key (defaults preferences.urlKeyMode) of
Just value ->
Dict.insert (Key.toString key) value searchParams
Nothing ->
searchParams
defaultLink =
a
[ slot "action"
, href (Url.toString { url | query = Just (SearchParams.build withDefault) })
]
[ setLinkText (Parameters.getKey key (defaults preferences.urlKeyMode) |> Maybe.withDefault "")
, text "(default value)"
]
in
node "x-query-healer"
[ role "listitem" ]
(span [ slot "key" ] [ text (Key.toLabel key) ]
:: (case error of
MissingValue ->
[ span [ slot "description" ] [ text "Parameter is missing" ]
, defaultLink
]
BelowMin min ->
let
withMin =
Dict.insert (Key.toString key) (String.fromFloat min) searchParams
in
[ span [ slot "description" ] [ text "Value is below the minimum." ]
, defaultLink
, a
[ slot "action"
, href (Url.toString { url | query = Just (SearchParams.build withMin) })
]
[ setLinkText (String.fromFloat min)
, text "(minimum value)"
]
]
AboveMax max ->
let
withMax =
Dict.insert (Key.toString key) (String.fromFloat max) searchParams
in
[ span [ slot "description" ] [ text "Value exceeds the maximum." ]
, defaultLink
, a
[ slot "action"
, href (Url.toString { url | query = Just (SearchParams.build withMax) })
]
[ setLinkText (String.fromFloat max)
, text "(maximum value)"
]
]
NotALength ->
[ span [ slot "description" ] [ text "Value is not a valid length value." ]
, defaultLink
]
NotAnInt ->
[ span [ slot "description" ] [ text "Value is not a valid integer." ]
, defaultLink
]
NonexistentVariant _ ->
[ span [ slot "description" ] [ text "Unrecognizable value." ]
, defaultLink
]
UnsupportedParametersVersion _ ->
[ span [ slot "description" ] [ text "Unsupported version." ]
, defaultLink
, a
[ slot "action"
, href
(Url.toString
{ url
| query = Just (SearchParams.build (Parameters.default |> Parameters.toDict preferences.urlKeyMode))
}
)
]
[ text "Use default parameters" ]
]
)
)
view : Model -> Html Msg
view model =
let
{ url, preferences } =
model
in
node "x-error-page"
[]
[ h1 [ slot "title" ] [ text "Invalid Parameters" ]
, p
[ slot "description" ]
[ text "This URL is not a valid URL for WWSTB."
, text " Fix erroneous parameters or start with "
, a
[ href
(Url.toString
{ url
| query = Just (SearchParams.build (Parameters.default |> Parameters.toDict preferences.urlKeyMode))
}
)
]
[ text "default parameters" ]
, text "."
]
, node "x-query-healer-items"
[ role "list" ]
(model.errors
|> Dict.Any.toList
|> List.map (\( key, error ) -> row model key error)
)
]