diff options
-rw-r--r-- | data/style.css | 6 | ||||
-rw-r--r-- | elm/ULists/DateEdit.elm | 69 | ||||
-rw-r--r-- | lib/VNWeb/User/Lists.pm | 32 |
3 files changed, 105 insertions, 2 deletions
diff --git a/data/style.css b/data/style.css index 0cd56c7a..40b57259 100644 --- a/data/style.css +++ b/data/style.css @@ -800,6 +800,12 @@ div.votelist td.tc2 { width: 50px; text-align: right; padding-right: 10px } .ulist .tc4 input { width: 55px; text-align: right } .ulist .tc5, .ulist .tc6, .ulist .tc7 { white-space: nowrap; width: 100px } +.ulist .tc6 div, .ulist .tc7 div { height: 1em } +.ulist .tc6 div span, .ulist .tc7 div span { position: absolute; z-index: 0 } +.ulist .tc6 div input, .ulist .tc7 div input { position: absolute; z-index: 900; width: 110px; visibility: hidden } +.ulist .tc6 div:hover input, .ulist .tc7 div:hover input, +.ulist .tc6 div input:focus, .ulist .tc7 div input:focus { visibility: visible } + .labeledit > a { color: $maintext$; display: block; border: none!important } .labeledit > a > span { float: right; width: 16px; text-align: right; display: inline-block } .labeledit > a > span i { visibility: hidden; font-style: normal } diff --git a/elm/ULists/DateEdit.elm b/elm/ULists/DateEdit.elm new file mode 100644 index 00000000..98ccf5d0 --- /dev/null +++ b/elm/ULists/DateEdit.elm @@ -0,0 +1,69 @@ +module ULists.DateEdit exposing (main) + +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (..) +import Task +import Process +import Browser +import Lib.Api as Api +import Gen.Api as GApi +import Gen.DateEdit as GDE + + +main : Program GDE.Send Model Msg +main = Browser.element + { init = \f -> (init f, Cmd.none) + , subscriptions = always Sub.none + , view = view + , update = update + } + +type alias Model = + { state : Api.State + , flags : GDE.Send + , val : String + , debnum : Int -- Debounce for submit + } + +init : GDE.Send -> Model +init f = + { state = Api.Normal + , flags = f + , val = f.date + , debnum = 0 + } + +type Msg + = Val String + | Save Int + | Saved GApi.Response + + +update : Msg -> Model -> (Model, Cmd Msg) +update msg model = + case msg of + Val s -> ({ model | val = s, debnum = model.debnum + 1 }, Task.perform (\_ -> Save (model.debnum+1)) <| Process.sleep 500) + + Save n -> + if n /= model.debnum || model.val == model.flags.date + then (model, Cmd.none) + else ( { model | state = Api.Loading, debnum = model.debnum+1 } + , Api.post "/u/ulist/setdate.json" (GDE.encode { uid = model.flags.uid, vid = model.flags.vid, start = model.flags.start, date = model.val }) Saved ) + + Saved GApi.Success -> + let f = model.flags + nf = { f | date = model.val } + in ({ model | state = Api.Normal, flags = nf }, Cmd.none) + Saved e -> ({ model | state = Api.Error e }, Cmd.none) + + +view : Model -> Html Msg +view model = div [ class "compact" ] <| + case model.state of + Api.Loading -> [ span [ class "spinner" ] [] ] + Api.Error _ -> [ b [ class "standout" ] [ text "error" ] ] -- Argh + Api.Normal -> + [ input ([ type_ "date", class "text", value model.val, onInput Val, onBlur (Save model.debnum), pattern "yyyy-mm-dd" ] ++ GDE.valDate) [] + , span [] [ text model.val ] + ] diff --git a/lib/VNWeb/User/Lists.pm b/lib/VNWeb/User/Lists.pm index 033c3722..7f9ef214 100644 --- a/lib/VNWeb/User/Lists.pm +++ b/lib/VNWeb/User/Lists.pm @@ -41,6 +41,16 @@ my $VNLABELS_IN = form_compile in => $VNLABELS; elm_form 'LabelEdit', $VNLABELS_OUT, $VNLABELS_IN; +my $VNDATE = form_compile any => { + uid => { id => 1 }, + vid => { id => 1 }, + date => { required => 0, default => '', regex => qr/^(?:19[7-9][0-9]|20[0-9][0-9])-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$/ }, # 1970 - 2099 for sanity + start => { anybool => 1 }, # Field selection, started/finished +}; + +elm_form 'DateEdit', undef, $VNDATE; + + # TODO: Filters to find unlabeled VNs or VNs with notes? sub filters_ { my($own, $labels) = @_; @@ -94,6 +104,7 @@ sub filters_ { sub vn_ { my($uid, $own, $n, $v, $labels) = @_; tr_ mkclass(odd => $n % 2 == 0), sub { + # TODO: Public/private indicator td_ class => 'tc1', sub { input_ type => 'checkbox', class => 'checkhidden', name => 'collapse_vid', id => 'collapse_vid'.$v->{id}, value => 'collapsed_vid'.$v->{id}; label_ for => 'collapse_vid'.$v->{id}, sub { @@ -127,8 +138,14 @@ sub vn_ { elm_ 'ULists.VoteEdit' => $VNVOTE, { uid => $uid, vid => $v->{id}, vote => fmtvote($v->{vote}) } if $own; }; td_ class => 'tc5', fmtdate $v->{added}, 'compact'; - td_ class => 'tc6', $v->{started}||''; - td_ class => 'tc7', $v->{finished}||''; + td_ class => 'tc6', sub { + txt_ $v->{started}||'' if !$own; + elm_ 'ULists.DateEdit' => $VNDATE, { uid => $uid, vid => $v->{id}, date => $v->{started}||'', start => 1 } if $own; + }; + td_ class => 'tc7', sub { + txt_ $v->{finished}||'' if !$own; + elm_ 'ULists.DateEdit' => $VNDATE, { uid => $uid, vid => $v->{id}, date => $v->{finished}||'', start => 0 } if $own; + }; }; tr_ mkclass(hidden => 1, 'collapsed_vid'.$v->{id} => 1, odd => $n % 2 == 0), sub { @@ -320,4 +337,15 @@ json_api qr{/u/ulist/setlabel.json}, $VNLABELS_IN, sub { elm_Success }; + +json_api qr{/u/ulist/setdate.json}, $VNDATE, sub { + my($data) = @_; + return elm_Unauth if !auth || auth->uid != $data->{uid}; + tuwf->dbExeci( + 'UPDATE ulists SET lastmod = NOW(), ', $data->{start} ? 'started' : 'finished', '=', \($data->{date}||undef), + 'WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid} + ); + elm_Success +}; + 1; |