add table views for all the various things
This commit is contained in:
parent
06b62b5de5
commit
665694bd74
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
.form-container {
|
.form-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-content {
|
.form-content {
|
||||||
@ -81,6 +81,26 @@
|
|||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: 1px solid #dedeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr td {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th {
|
||||||
|
background-color: #dedeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr:nth-child(even) {
|
||||||
|
background-color: #f6f8f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr:nth-child(odd) {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
@ -94,7 +114,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
2
assets/main.min.js
vendored
2
assets/main.min.js
vendored
File diff suppressed because one or more lines are too long
@ -175,6 +175,23 @@ func (q *Queries) AddWatchItem(ctx context.Context, arg AddWatchItemParams) (Wat
|
|||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteIgnore = `-- name: DeleteIgnore :exec
|
||||||
|
delete
|
||||||
|
from pull_request_ignores
|
||||||
|
where id = ?
|
||||||
|
and owner_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
type DeleteIgnoreParams struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
OwnerID int64 `json:"owner_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) DeleteIgnore(ctx context.Context, arg DeleteIgnoreParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, deleteIgnore, arg.ID, arg.OwnerID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const deleteLink = `-- name: DeleteLink :exec
|
const deleteLink = `-- name: DeleteLink :exec
|
||||||
delete
|
delete
|
||||||
from links
|
from links
|
||||||
|
1
elm.json
1
elm.json
@ -6,6 +6,7 @@
|
|||||||
"elm-version": "0.19.1",
|
"elm-version": "0.19.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"direct": {
|
"direct": {
|
||||||
|
"billstclair/elm-sortable-table": "1.2.1",
|
||||||
"elm/browser": "1.0.2",
|
"elm/browser": "1.0.2",
|
||||||
"elm/core": "1.0.5",
|
"elm/core": "1.0.5",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
|
44
handlers.go
44
handlers.go
@ -299,6 +299,50 @@ func linksPOST(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prignoreGET(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
ownerID, ok := ctx.Value(ownerKey).(int64)
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, http.StatusText(http.StatusUnprocessableEntity), http.StatusUnprocessableEntity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prIgnores, err := app.queries.GetAllPullRequestIgnores(app.ctx, ownerID)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prJson, err := json.Marshal(prIgnores)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Content-type", "application/json")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
_, err = w.Write(prJson)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func prignoreDELETE(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
ownerID, ok := ctx.Value(ownerKey).(int64)
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, http.StatusText(http.StatusUnprocessableEntity), http.StatusUnprocessableEntity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ignoreID, err := strconv.Atoi(chi.URLParam(r, "ignoreID"))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
err = app.queries.DeleteIgnore(app.ctx, data.DeleteIgnoreParams{ID: int64(ignoreID), OwnerID: ownerID})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func prignorePOST(w http.ResponseWriter, r *http.Request) {
|
func prignorePOST(w http.ResponseWriter, r *http.Request) {
|
||||||
d := &data.AddPullRequestIgnoreParams{}
|
d := &data.AddPullRequestIgnoreParams{}
|
||||||
if err := render.Decode(r, d); err != nil {
|
if err := render.Decode(r, d); err != nil {
|
||||||
|
2
main.go
2
main.go
@ -156,6 +156,8 @@ func main() {
|
|||||||
r.Route("/prignores", func(r chi.Router) {
|
r.Route("/prignores", func(r chi.Router) {
|
||||||
r.Use(render.SetContentType(render.ContentTypeJSON))
|
r.Use(render.SetContentType(render.ContentTypeJSON))
|
||||||
r.Post("/", prignorePOST)
|
r.Post("/", prignorePOST)
|
||||||
|
r.Get("/", prignoreGET)
|
||||||
|
r.Delete("/{ignoreID:[0-9]+}", prignoreDELETE)
|
||||||
})
|
})
|
||||||
r.Route("/icons", func(r chi.Router) {
|
r.Route("/icons", func(r chi.Router) {
|
||||||
r.Use(IconCacher)
|
r.Use(IconCacher)
|
||||||
|
@ -82,6 +82,13 @@ from pull_requests
|
|||||||
where id = ?
|
where id = ?
|
||||||
and owner_id = ?;
|
and owner_id = ?;
|
||||||
|
|
||||||
|
-- name: DeleteIgnore :exec
|
||||||
|
delete
|
||||||
|
from pull_request_ignores
|
||||||
|
where id = ?
|
||||||
|
and owner_id = ?;
|
||||||
|
|
||||||
|
|
||||||
-- name: GetAllPullRequestIgnores :many
|
-- name: GetAllPullRequestIgnores :many
|
||||||
select *
|
select *
|
||||||
from pull_request_ignores
|
from pull_request_ignores
|
||||||
|
39
src/Ignores.elm
Normal file
39
src/Ignores.elm
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
module Ignores exposing (..)
|
||||||
|
|
||||||
|
import Json.Decode
|
||||||
|
exposing
|
||||||
|
( Decoder
|
||||||
|
, field
|
||||||
|
, int
|
||||||
|
, list
|
||||||
|
, map5
|
||||||
|
, string
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type alias Ignores =
|
||||||
|
List Ignore
|
||||||
|
|
||||||
|
|
||||||
|
type alias Ignore =
|
||||||
|
{ id : Int
|
||||||
|
, ownerId : Int
|
||||||
|
, createdAt : String
|
||||||
|
, repo : String
|
||||||
|
, number : Int
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ignoreListDecoder : Decoder Ignores
|
||||||
|
ignoreListDecoder =
|
||||||
|
list ignoreDecoder
|
||||||
|
|
||||||
|
|
||||||
|
ignoreDecoder : Decoder Ignore
|
||||||
|
ignoreDecoder =
|
||||||
|
map5 Ignore
|
||||||
|
(field "id" int)
|
||||||
|
(field "owner_id" int)
|
||||||
|
(field "created_at" string)
|
||||||
|
(field "repo" string)
|
||||||
|
(field "number" int)
|
50
src/Links.elm
Normal file
50
src/Links.elm
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
module Links exposing (..)
|
||||||
|
|
||||||
|
import Json.Decode
|
||||||
|
exposing
|
||||||
|
( Decoder
|
||||||
|
, bool
|
||||||
|
, field
|
||||||
|
, int
|
||||||
|
, list
|
||||||
|
, map6
|
||||||
|
, string
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type alias Links =
|
||||||
|
List Link
|
||||||
|
|
||||||
|
|
||||||
|
type alias NewLink =
|
||||||
|
{ name : String
|
||||||
|
, url : String
|
||||||
|
, shared : Bool
|
||||||
|
, logo_url : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias Link =
|
||||||
|
{ id : Int
|
||||||
|
, createdAt : String
|
||||||
|
, url : String
|
||||||
|
, name : String
|
||||||
|
, logoURL : String
|
||||||
|
, shared : Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
linkListDecoder : Decoder Links
|
||||||
|
linkListDecoder =
|
||||||
|
list linkDecoder
|
||||||
|
|
||||||
|
|
||||||
|
linkDecoder : Decoder Link
|
||||||
|
linkDecoder =
|
||||||
|
map6 Link
|
||||||
|
(field "id" int)
|
||||||
|
(field "created_at" string)
|
||||||
|
(field "url" string)
|
||||||
|
(field "name" string)
|
||||||
|
(field "logo_url" string)
|
||||||
|
(field "shared" bool)
|
405
src/Main.elm
405
src/Main.elm
@ -2,63 +2,25 @@ module Main exposing (..)
|
|||||||
|
|
||||||
import Browser
|
import Browser
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (checked, class, classList, href, name, placeholder, src, type_, value)
|
import Html.Attributes
|
||||||
|
exposing
|
||||||
|
( checked
|
||||||
|
, class
|
||||||
|
, classList
|
||||||
|
, href
|
||||||
|
, name
|
||||||
|
, placeholder
|
||||||
|
, src
|
||||||
|
, type_
|
||||||
|
, value
|
||||||
|
)
|
||||||
import Html.Events exposing (..)
|
import Html.Events exposing (..)
|
||||||
import Http
|
import Http
|
||||||
import Json.Decode as Decode
|
import Ignores
|
||||||
exposing
|
|
||||||
( Decoder
|
|
||||||
, bool
|
|
||||||
, field
|
|
||||||
, int
|
|
||||||
, list
|
|
||||||
, map5
|
|
||||||
, map6
|
|
||||||
, string
|
|
||||||
)
|
|
||||||
import Json.Encode as Encode
|
import Json.Encode as Encode
|
||||||
|
import Links
|
||||||
|
import Table exposing (defaultCustomizations)
|
||||||
type alias Watches =
|
import Watches
|
||||||
List Watch
|
|
||||||
|
|
||||||
|
|
||||||
type alias Links =
|
|
||||||
List Link
|
|
||||||
|
|
||||||
|
|
||||||
type alias Link =
|
|
||||||
{ id : Int
|
|
||||||
, createdAt : String
|
|
||||||
, url : String
|
|
||||||
, name : String
|
|
||||||
, logoURL : String
|
|
||||||
, shared : Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Watch =
|
|
||||||
{ id : Int
|
|
||||||
, ownerId : Int
|
|
||||||
, name : String
|
|
||||||
, repo : String
|
|
||||||
, resultCount : Int
|
|
||||||
, results : List Node
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Node =
|
|
||||||
{ number : Int
|
|
||||||
, createdAt : String
|
|
||||||
, repository : RepoInfo
|
|
||||||
, title : String
|
|
||||||
, url : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias RepoInfo =
|
|
||||||
{ nameWithOwner : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
main : Program () Model Msg
|
||||||
@ -78,49 +40,47 @@ type Msg
|
|||||||
| DeleteLink Int
|
| DeleteLink Int
|
||||||
| DeletedWatch (Result Http.Error ())
|
| DeletedWatch (Result Http.Error ())
|
||||||
| DeleteWatch Int
|
| DeleteWatch Int
|
||||||
| GotLinks (Result Http.Error (List Link))
|
| DeletedIgnore (Result Http.Error ())
|
||||||
| GotNewLink NewLink
|
| DeleteIgnore Int
|
||||||
| GotNewWatch NewWatch
|
| GotLinks (Result Http.Error Links.Links)
|
||||||
| GotWatches (Result Http.Error (List Watch))
|
| GotNewLink Links.NewLink
|
||||||
|
| GotNewWatch Watches.NewWatch
|
||||||
|
| GotWatches (Result Http.Error Watches.Watches)
|
||||||
|
| GotIgnores (Result Http.Error Ignores.Ignores)
|
||||||
| HideWatchedItem Int String
|
| HideWatchedItem Int String
|
||||||
| HidItem (Result Http.Error ())
|
| HidItem (Result Http.Error ())
|
||||||
| Reload
|
| Reload
|
||||||
| ReloadLinks
|
| ReloadLinks
|
||||||
| ReloadWatches
|
| ReloadWatches
|
||||||
|
| ReloadIgnores
|
||||||
| SubmitLink
|
| SubmitLink
|
||||||
| SubmitWatch
|
| SubmitWatch
|
||||||
| FetchIcons
|
| FetchIcons
|
||||||
| LoadIcons (Result Http.Error ())
|
| LoadIcons (Result Http.Error ())
|
||||||
|
| SetLinkTableState Table.State
|
||||||
|
| SetWatchTableState Table.State
|
||||||
|
| SetIgnoreTableState Table.State
|
||||||
|
|
||||||
|
|
||||||
type Status
|
type Status
|
||||||
= Loading
|
= Loading
|
||||||
| LoadedWatches (List Watch)
|
| LoadedWatches Watches.Watches
|
||||||
| LoadedLinks (List Link)
|
| LoadedIgnores Ignores.Ignores
|
||||||
|
| LoadedLinks Links.Links
|
||||||
| Errored String
|
| Errored String
|
||||||
|
|
||||||
|
|
||||||
type alias NewWatch =
|
|
||||||
{ name : String
|
|
||||||
, repo : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias NewLink =
|
|
||||||
{ name : String
|
|
||||||
, url : String
|
|
||||||
, shared : Bool
|
|
||||||
, logo_url : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
{ watches : List Watch
|
{ watches : Watches.Watches
|
||||||
, links : List Link
|
, links : Links.Links
|
||||||
|
, ignores : Ignores.Ignores
|
||||||
, errors : List String
|
, errors : List String
|
||||||
, status : Status
|
, status : Status
|
||||||
, newlink : NewLink
|
, newlink : Links.NewLink
|
||||||
, newwatch : NewWatch
|
, newwatch : Watches.NewWatch
|
||||||
|
, linkTableState : Table.State
|
||||||
|
, watchTableState : Table.State
|
||||||
|
, ignoreTableState : Table.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -128,6 +88,7 @@ initialModel : Model
|
|||||||
initialModel =
|
initialModel =
|
||||||
{ watches = []
|
{ watches = []
|
||||||
, links = []
|
, links = []
|
||||||
|
, ignores = []
|
||||||
, errors = []
|
, errors = []
|
||||||
, status = Loading
|
, status = Loading
|
||||||
, newlink =
|
, newlink =
|
||||||
@ -140,12 +101,15 @@ initialModel =
|
|||||||
{ name = ""
|
{ name = ""
|
||||||
, repo = ""
|
, repo = ""
|
||||||
}
|
}
|
||||||
|
, linkTableState = Table.initialSort "Created"
|
||||||
|
, watchTableState = Table.initialSort "Created"
|
||||||
|
, ignoreTableState = Table.initialSort "Created"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init : () -> ( Model, Cmd Msg )
|
init : () -> ( Model, Cmd Msg )
|
||||||
init _ =
|
init _ =
|
||||||
( initialModel, Cmd.batch [ getLinks, getWatches ] )
|
( initialModel, Cmd.batch [ getLinks, getWatches, getIgnores ] )
|
||||||
|
|
||||||
|
|
||||||
hideWatched : Int -> String -> Cmd Msg
|
hideWatched : Int -> String -> Cmd Msg
|
||||||
@ -222,6 +186,19 @@ deleteLink linkId =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
deleteIgnore : Int -> Cmd Msg
|
||||||
|
deleteIgnore ignoreId =
|
||||||
|
Http.request
|
||||||
|
{ url = "/prignores/" ++ String.fromInt ignoreId
|
||||||
|
, method = "DELETE"
|
||||||
|
, timeout = Nothing
|
||||||
|
, tracker = Nothing
|
||||||
|
, headers = []
|
||||||
|
, body = Http.emptyBody
|
||||||
|
, expect = Http.expectWhatever DeletedIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
deleteWatch : Int -> Cmd Msg
|
deleteWatch : Int -> Cmd Msg
|
||||||
deleteWatch watchId =
|
deleteWatch watchId =
|
||||||
Http.request
|
Http.request
|
||||||
@ -253,6 +230,9 @@ update msg model =
|
|||||||
DeleteWatch watchId ->
|
DeleteWatch watchId ->
|
||||||
( model, deleteWatch watchId )
|
( model, deleteWatch watchId )
|
||||||
|
|
||||||
|
DeleteIgnore ignoreId ->
|
||||||
|
( model, deleteIgnore ignoreId )
|
||||||
|
|
||||||
GotNewWatch newwatch ->
|
GotNewWatch newwatch ->
|
||||||
( { model | newwatch = newwatch }, Cmd.none )
|
( { model | newwatch = newwatch }, Cmd.none )
|
||||||
|
|
||||||
@ -283,6 +263,12 @@ update msg model =
|
|||||||
DeletedWatch (Err _) ->
|
DeletedWatch (Err _) ->
|
||||||
( { model | status = Errored "Server error deleting watch!" }, Cmd.none )
|
( { model | status = Errored "Server error deleting watch!" }, Cmd.none )
|
||||||
|
|
||||||
|
DeletedIgnore (Ok _) ->
|
||||||
|
( model, getIgnores )
|
||||||
|
|
||||||
|
DeletedIgnore (Err _) ->
|
||||||
|
( { model | status = Errored "Server error deleting ignore!" }, Cmd.none )
|
||||||
|
|
||||||
HidItem (Err _) ->
|
HidItem (Err _) ->
|
||||||
( { model | status = Errored "Server error when hiding a watch item!" }, Cmd.none )
|
( { model | status = Errored "Server error when hiding a watch item!" }, Cmd.none )
|
||||||
|
|
||||||
@ -307,12 +293,18 @@ update msg model =
|
|||||||
ReloadLinks ->
|
ReloadLinks ->
|
||||||
( model, getLinks )
|
( model, getLinks )
|
||||||
|
|
||||||
|
ReloadIgnores ->
|
||||||
|
( model, getIgnores )
|
||||||
|
|
||||||
GotWatches (Err _) ->
|
GotWatches (Err _) ->
|
||||||
( { model | status = Errored "Server error when fetching watches!" }, Cmd.none )
|
( { model | status = Errored "Server error when fetching watches!" }, Cmd.none )
|
||||||
|
|
||||||
GotLinks (Err _) ->
|
GotLinks (Err _) ->
|
||||||
( { model | status = Errored "Server error when fetching links!" }, Cmd.none )
|
( { model | status = Errored "Server error when fetching links!" }, Cmd.none )
|
||||||
|
|
||||||
|
GotIgnores (Err _) ->
|
||||||
|
( { model | status = Errored "Server error when fetching ignores!" }, Cmd.none )
|
||||||
|
|
||||||
GotWatches (Ok watches) ->
|
GotWatches (Ok watches) ->
|
||||||
case watches of
|
case watches of
|
||||||
_ :: _ ->
|
_ :: _ ->
|
||||||
@ -340,6 +332,28 @@ update msg model =
|
|||||||
[] ->
|
[] ->
|
||||||
( { model | status = Errored "No Links found" }, Cmd.none )
|
( { model | status = Errored "No Links found" }, Cmd.none )
|
||||||
|
|
||||||
|
GotIgnores (Ok ignores) ->
|
||||||
|
case ignores of
|
||||||
|
_ :: _ ->
|
||||||
|
( { model
|
||||||
|
| ignores = ignores
|
||||||
|
, status = LoadedIgnores ignores
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
|
[] ->
|
||||||
|
( { model | status = Errored "No Watches found" }, Cmd.none )
|
||||||
|
|
||||||
|
SetLinkTableState newState ->
|
||||||
|
( { model | linkTableState = newState }, Cmd.none )
|
||||||
|
|
||||||
|
SetWatchTableState newState ->
|
||||||
|
( { model | watchTableState = newState }, Cmd.none )
|
||||||
|
|
||||||
|
SetIgnoreTableState newState ->
|
||||||
|
( { model | ignoreTableState = newState }, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions _ =
|
subscriptions _ =
|
||||||
@ -381,18 +395,181 @@ view model =
|
|||||||
, footer []
|
, footer []
|
||||||
[ details []
|
[ details []
|
||||||
[ summary []
|
[ summary []
|
||||||
[ b [] [ text "Maintenence" ] ]
|
[ b [] [ text "Maintenence" ]
|
||||||
, button [ onClick FetchIcons ] [ text "Update Icons" ]
|
]
|
||||||
|
, div []
|
||||||
|
[ button [ onClick FetchIcons ] [ text "Update Icons" ]
|
||||||
|
]
|
||||||
|
, div []
|
||||||
|
[ h3 [] [ text "Links" ]
|
||||||
|
, Table.view linkTableConfig model.linkTableState model.links
|
||||||
|
]
|
||||||
|
, div []
|
||||||
|
[ h3 [] [ text "Watched Items" ]
|
||||||
|
, Table.view watchTableConfig model.watchTableState model.watches
|
||||||
|
]
|
||||||
|
, div []
|
||||||
|
[ h3
|
||||||
|
[]
|
||||||
|
[ text "Watched Items Ignores" ]
|
||||||
|
, Table.view ignoreTableConfig model.ignoreTableState model.ignores
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
shareTxt : Links.Link -> Table.HtmlDetails Msg
|
||||||
|
shareTxt link =
|
||||||
|
if link.shared then
|
||||||
|
Table.HtmlDetails []
|
||||||
|
[ text "Yes" ]
|
||||||
|
|
||||||
|
else
|
||||||
|
Table.HtmlDetails []
|
||||||
|
[ text "No" ]
|
||||||
|
|
||||||
|
|
||||||
|
shareColumn : Table.Column Links.Link Msg
|
||||||
|
shareColumn =
|
||||||
|
Table.veryCustomColumn
|
||||||
|
{ name = "Shared"
|
||||||
|
, viewData = \data -> shareTxt data
|
||||||
|
, sorter = Table.unsortable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
linkTimeColumn : Table.Column Links.Link Msg
|
||||||
|
linkTimeColumn =
|
||||||
|
Table.customColumn
|
||||||
|
{ name = "Created"
|
||||||
|
, viewData = .createdAt
|
||||||
|
, sorter = Table.decreasingOrIncreasingBy .createdAt
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
deleteLinkColumn : Table.Column Links.Link Msg
|
||||||
|
deleteLinkColumn =
|
||||||
|
Table.veryCustomColumn
|
||||||
|
{ name = "Action"
|
||||||
|
, viewData = linkDeleteView
|
||||||
|
, sorter = Table.unsortable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
linkTableConfig : Table.Config Links.Link Msg
|
||||||
|
linkTableConfig =
|
||||||
|
Table.customConfig
|
||||||
|
{ toId = .name
|
||||||
|
, toMsg = SetLinkTableState
|
||||||
|
, columns =
|
||||||
|
[ Table.stringColumn "Name" .name
|
||||||
|
, Table.stringColumn "URL" .url
|
||||||
|
, shareColumn
|
||||||
|
, Table.stringColumn "Logo URL" .logoURL
|
||||||
|
, linkTimeColumn
|
||||||
|
, deleteLinkColumn
|
||||||
|
]
|
||||||
|
, customizations = defaultCustomizations
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
linkDeleteView : Links.Link -> Table.HtmlDetails Msg
|
||||||
|
linkDeleteView { id } =
|
||||||
|
Table.HtmlDetails []
|
||||||
|
[ button
|
||||||
|
[ onClick (DeleteLink id) ]
|
||||||
|
[ text "Delete" ]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
watchTableConfig : Table.Config Watches.Watch Msg
|
||||||
|
watchTableConfig =
|
||||||
|
Table.config
|
||||||
|
{ toId = .name
|
||||||
|
, toMsg = SetWatchTableState
|
||||||
|
, columns =
|
||||||
|
[ Table.stringColumn "Name" .name
|
||||||
|
, Table.stringColumn "Repo" .repo
|
||||||
|
, deleteWatchColumn
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
deleteWatchColumn : Table.Column Watches.Watch Msg
|
||||||
|
deleteWatchColumn =
|
||||||
|
Table.veryCustomColumn
|
||||||
|
{ name = "Action"
|
||||||
|
, viewData = watchDeleteView
|
||||||
|
, sorter = Table.unsortable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
watchDeleteView : Watches.Watch -> Table.HtmlDetails Msg
|
||||||
|
watchDeleteView { id } =
|
||||||
|
Table.HtmlDetails []
|
||||||
|
[ button
|
||||||
|
[ onClick (DeleteWatch id) ]
|
||||||
|
[ text "Delete" ]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
ignoreTimeColumn : Table.Column Ignores.Ignore Msg
|
||||||
|
ignoreTimeColumn =
|
||||||
|
Table.customColumn
|
||||||
|
{ name = "Created"
|
||||||
|
, viewData = .createdAt
|
||||||
|
, sorter = Table.decreasingOrIncreasingBy .createdAt
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
deleteIgnoreColumn : Table.Column Ignores.Ignore Msg
|
||||||
|
deleteIgnoreColumn =
|
||||||
|
Table.veryCustomColumn
|
||||||
|
{ name = "Action"
|
||||||
|
, viewData = ignoreDeleteView
|
||||||
|
, sorter = Table.unsortable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ignoreDeleteView : Ignores.Ignore -> Table.HtmlDetails Msg
|
||||||
|
ignoreDeleteView { id } =
|
||||||
|
Table.HtmlDetails []
|
||||||
|
[ button
|
||||||
|
[ onClick (DeleteIgnore id) ]
|
||||||
|
[ text "Delete" ]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
ignoreTableConfig : Table.Config Ignores.Ignore Msg
|
||||||
|
ignoreTableConfig =
|
||||||
|
Table.customConfig
|
||||||
|
{ toId = .createdAt
|
||||||
|
, toMsg = SetIgnoreTableState
|
||||||
|
, columns =
|
||||||
|
[ Table.intColumn "ID" .id
|
||||||
|
, Table.stringColumn "Repo" .repo
|
||||||
|
, Table.intColumn "Number" .number
|
||||||
|
, ignoreTimeColumn
|
||||||
|
, deleteIgnoreColumn
|
||||||
|
]
|
||||||
|
, customizations = defaultCustomizations
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getIgnores : Cmd Msg
|
||||||
|
getIgnores =
|
||||||
|
Http.get
|
||||||
|
{ url = "/prignores"
|
||||||
|
, expect = Http.expectJson GotIgnores Ignores.ignoreListDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
getLinks : Cmd Msg
|
getLinks : Cmd Msg
|
||||||
getLinks =
|
getLinks =
|
||||||
Http.get
|
Http.get
|
||||||
{ url = "/links"
|
{ url = "/links"
|
||||||
, expect = Http.expectJson GotLinks linkListDecoder
|
, expect = Http.expectJson GotLinks Links.linkListDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -400,11 +577,11 @@ getWatches : Cmd Msg
|
|||||||
getWatches =
|
getWatches =
|
||||||
Http.get
|
Http.get
|
||||||
{ url = "/watches"
|
{ url = "/watches"
|
||||||
, expect = Http.expectJson GotWatches watchListDecoder
|
, expect = Http.expectJson GotWatches Watches.watchListDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
watchForm : Model -> NewWatch -> Html Msg
|
watchForm : Model -> Watches.NewWatch -> Html Msg
|
||||||
watchForm model newwatch =
|
watchForm model newwatch =
|
||||||
div []
|
div []
|
||||||
[ createForm "Watches"
|
[ createForm "Watches"
|
||||||
@ -418,7 +595,7 @@ watchForm model newwatch =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
linkForm : Model -> NewLink -> Html Msg
|
linkForm : Model -> Links.NewLink -> Html Msg
|
||||||
linkForm model newlink =
|
linkForm model newlink =
|
||||||
div []
|
div []
|
||||||
[ createForm "Links"
|
[ createForm "Links"
|
||||||
@ -514,7 +691,7 @@ viewWatches model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewLink : Link -> Html Msg
|
viewLink : Links.Link -> Html Msg
|
||||||
viewLink link =
|
viewLink link =
|
||||||
div []
|
div []
|
||||||
[ div [ class "icon" ]
|
[ div [ class "icon" ]
|
||||||
@ -532,7 +709,7 @@ viewLink link =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewWatch : Watch -> Html Msg
|
viewWatch : Watches.Watch -> Html Msg
|
||||||
viewWatch watch =
|
viewWatch watch =
|
||||||
case watch.results of
|
case watch.results of
|
||||||
[] ->
|
[] ->
|
||||||
@ -555,7 +732,7 @@ viewWatch watch =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewResult : Node -> Html Msg
|
viewResult : Watches.Node -> Html Msg
|
||||||
viewResult node =
|
viewResult node =
|
||||||
li []
|
li []
|
||||||
[ a [ href node.url ] [ text (String.fromInt node.number) ]
|
[ a [ href node.url ] [ text (String.fromInt node.number) ]
|
||||||
@ -564,55 +741,3 @@ viewResult node =
|
|||||||
, text " :: "
|
, text " :: "
|
||||||
, text node.title
|
, text node.title
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- DECODERS
|
|
||||||
|
|
||||||
|
|
||||||
linkListDecoder : Decoder (List Link)
|
|
||||||
linkListDecoder =
|
|
||||||
list linkDecoder
|
|
||||||
|
|
||||||
|
|
||||||
linkDecoder : Decoder Link
|
|
||||||
linkDecoder =
|
|
||||||
map6 Link
|
|
||||||
(field "id" int)
|
|
||||||
(field "created_at" string)
|
|
||||||
(field "url" string)
|
|
||||||
(field "name" string)
|
|
||||||
(field "logo_url" string)
|
|
||||||
(field "shared" bool)
|
|
||||||
|
|
||||||
|
|
||||||
watchListDecoder : Decoder (List Watch)
|
|
||||||
watchListDecoder =
|
|
||||||
list watchDecoder
|
|
||||||
|
|
||||||
|
|
||||||
watchDecoder : Decoder Watch
|
|
||||||
watchDecoder =
|
|
||||||
map6 Watch
|
|
||||||
(field "id" int)
|
|
||||||
(field "owner_id" int)
|
|
||||||
(field "name" string)
|
|
||||||
(field "repo" string)
|
|
||||||
(field "result_count" int)
|
|
||||||
(field "results" <| list resultsDecoder)
|
|
||||||
|
|
||||||
|
|
||||||
resultsDecoder : Decoder Node
|
|
||||||
resultsDecoder =
|
|
||||||
map5 Node
|
|
||||||
(field "number" int)
|
|
||||||
(field "createdAt" string)
|
|
||||||
(field "repository" repoInfoDecoder)
|
|
||||||
(field "title" string)
|
|
||||||
(field "url" string)
|
|
||||||
|
|
||||||
|
|
||||||
repoInfoDecoder : Decoder RepoInfo
|
|
||||||
repoInfoDecoder =
|
|
||||||
Decode.map RepoInfo
|
|
||||||
(field "nameWithOwner" string)
|
|
||||||
|
78
src/Watches.elm
Normal file
78
src/Watches.elm
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
module Watches exposing (..)
|
||||||
|
|
||||||
|
import Json.Decode as Decode
|
||||||
|
exposing
|
||||||
|
( Decoder
|
||||||
|
, field
|
||||||
|
, int
|
||||||
|
, list
|
||||||
|
, map5
|
||||||
|
, map6
|
||||||
|
, string
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type alias NewWatch =
|
||||||
|
{ name : String
|
||||||
|
, repo : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias Watches =
|
||||||
|
List Watch
|
||||||
|
|
||||||
|
|
||||||
|
type alias Watch =
|
||||||
|
{ id : Int
|
||||||
|
, ownerId : Int
|
||||||
|
, name : String
|
||||||
|
, repo : String
|
||||||
|
, resultCount : Int
|
||||||
|
, results : List Node
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias RepoInfo =
|
||||||
|
{ nameWithOwner : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias Node =
|
||||||
|
{ number : Int
|
||||||
|
, createdAt : String
|
||||||
|
, repository : RepoInfo
|
||||||
|
, title : String
|
||||||
|
, url : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
watchListDecoder : Decoder Watches
|
||||||
|
watchListDecoder =
|
||||||
|
list watchDecoder
|
||||||
|
|
||||||
|
|
||||||
|
watchDecoder : Decoder Watch
|
||||||
|
watchDecoder =
|
||||||
|
map6 Watch
|
||||||
|
(field "id" int)
|
||||||
|
(field "owner_id" int)
|
||||||
|
(field "name" string)
|
||||||
|
(field "repo" string)
|
||||||
|
(field "result_count" int)
|
||||||
|
(field "results" <| list resultsDecoder)
|
||||||
|
|
||||||
|
|
||||||
|
resultsDecoder : Decoder Node
|
||||||
|
resultsDecoder =
|
||||||
|
map5 Node
|
||||||
|
(field "number" int)
|
||||||
|
(field "createdAt" string)
|
||||||
|
(field "repository" repoInfoDecoder)
|
||||||
|
(field "title" string)
|
||||||
|
(field "url" string)
|
||||||
|
|
||||||
|
|
||||||
|
repoInfoDecoder : Decoder RepoInfo
|
||||||
|
repoInfoDecoder =
|
||||||
|
Decode.map RepoInfo
|
||||||
|
(field "nameWithOwner" string)
|
Loading…
Reference in New Issue
Block a user