-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor code and add new features (#4)
Added new files and updated package references Fixed DeleteResourceModal isOpen attribute Added logging configuration and service registrations Added TaskListItemError and ITrackListItemService types Refactored deleteModal function in TrackLists view Refactored share.js file Refactored the TrackListItem view
- Loading branch information
1 parent
bb7e663
commit a67bac5
Showing
9 changed files
with
727 additions
and
448 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
namespace Mandadin.Client.Components.TrackListItems | ||
|
||
open System | ||
open Microsoft.AspNetCore.Components | ||
|
||
open Bolero | ||
open Bolero.Html | ||
open Mandadin.Client | ||
|
||
type NewItemForm() = | ||
inherit Component() | ||
let mutable objectName = "" | ||
|
||
[<Parameter>] | ||
member val HideDone: bool = false with get, set | ||
|
||
[<Parameter>] | ||
member val OnSubmit: string -> unit = ignore with get, set | ||
|
||
[<Parameter>] | ||
member val OnHideDoneChange: bool -> unit = ignore with get, set | ||
|
||
override self.Render() = | ||
form { | ||
attr.``class`` "row flex-spaces background-muted border notes-form" | ||
on.submit (fun _ -> self.OnSubmit objectName) | ||
|
||
fieldset { | ||
attr.``class`` "form-group" | ||
|
||
label { | ||
attr.``for`` "current-content" | ||
text "Nombre del objeto..." | ||
} | ||
|
||
textarea { | ||
attr.id "current-content" | ||
attr.placeholder objectName | ||
|
||
bind.input.string objectName (fun name -> objectName <- name) | ||
} | ||
|
||
label { | ||
attr.``for`` "paperCheck1" | ||
attr.``class`` "paper-check" | ||
|
||
input { | ||
attr.id "paperCheck1" | ||
attr.name "paperChecks" | ||
attr.``type`` "checkbox" | ||
|
||
bind.``checked`` self.HideDone (fun hideDone -> | ||
self.OnHideDoneChange hideDone) | ||
} | ||
|
||
span { text "Esconder Terminados" } | ||
} | ||
} | ||
|
||
button { | ||
attr.``type`` "submit" | ||
attr.``class`` "paper-btn btn-small" | ||
attr.disabled (String.IsNullOrWhiteSpace objectName) | ||
Icon.Get Save | ||
} | ||
} | ||
|
||
|
||
[<RequireQualifiedAccess>] | ||
module TrackListItems = | ||
|
||
let Stringify (items: list<TrackListItem>) : string = | ||
let isDoneToX (isDone: bool) = if isDone then 'x' else ' ' | ||
|
||
let stringified = | ||
items | ||
|> List.map (fun item -> | ||
sprintf "[ %c ] %s" (isDoneToX item.IsDone) item.Name) | ||
|
||
System.String.Join('\n', stringified) | ||
|
||
type ToolbarState<'State | ||
when 'State: (member TrackListId: string) | ||
and 'State: (member CanShare: bool) | ||
and 'State: (member Items: list<TrackListItem>)> = 'State | ||
|
||
|
||
type TrackListComponents = | ||
|
||
static member inline Toolbar<'State when ToolbarState<'State>> | ||
( | ||
state: 'State, | ||
share: IShareService, | ||
?onBackRequested: unit -> unit | ||
) = | ||
let onBackRequested = | ||
defaultArg onBackRequested ignore | ||
|
||
div { | ||
attr.``class`` "border" | ||
|
||
section { | ||
attr.``class`` "row flex-center" | ||
h4 { text state.TrackListId } | ||
} | ||
|
||
section { | ||
attr.``class`` "row flex-center" | ||
|
||
button { | ||
attr.``class`` "paper-btn btn-small" | ||
on.click (fun _ -> onBackRequested ()) | ||
Icon.Get Back | ||
} | ||
|
||
cond state.CanShare | ||
<| function | ||
| true -> | ||
button { | ||
attr.``class`` "paper-btn btn-small" | ||
|
||
on.click (fun _ -> | ||
let content = | ||
state.Items |> TrackListItems.Stringify | ||
|
||
share.Share(state.TrackListId, content) |> ignore) | ||
|
||
Icon.Get Share | ||
} | ||
| false -> empty () | ||
|
||
button { | ||
attr.``class`` "paper-btn btn-small" | ||
|
||
on.click (fun _ -> | ||
let content = | ||
state.Items |> TrackListItems.Stringify | ||
|
||
share.ToClipboard content |> ignore) | ||
|
||
Icon.Get Copy | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
namespace Mandadin.Client.Services | ||
|
||
open System | ||
|
||
open Microsoft.JSInterop | ||
open Microsoft.Extensions.Logging | ||
open Microsoft.Extensions.DependencyInjection | ||
|
||
open IcedTasks | ||
open FsToolkit.ErrorHandling | ||
|
||
open Mandadin.Client | ||
|
||
module Share = | ||
let inline factory (services: IServiceProvider) : IShareService = | ||
let jsRuntime = | ||
services.GetService<IJSRuntime>() | ||
|
||
let loggerFactory = | ||
services.GetService<ILoggerFactory>() | ||
|
||
let logger = | ||
loggerFactory.CreateLogger<IShareService>() | ||
|
||
{ new IShareService with | ||
member _.Share | ||
( | ||
listId: string, | ||
content: string | ||
) : Threading.Tasks.ValueTask = | ||
valueTaskUnit { | ||
logger.LogDebug("Sharing list: {listId}", listId) | ||
logger.LogDebug("Content: '{content}'...", content.Substring(0, 20)) | ||
|
||
do! | ||
jsRuntime.InvokeVoidAsync( | ||
"Mandadin.Share.ShareContent", | ||
[| listId :> obj; content |] | ||
) | ||
} | ||
|
||
member _.ToClipboard(content: string) : Threading.Tasks.ValueTask = | ||
valueTaskUnit { | ||
logger.LogDebug( | ||
"Copying content: '{content}'...", | ||
content.Substring(0, 20) | ||
) | ||
|
||
do! | ||
jsRuntime.InvokeVoidAsync( | ||
"Mandadin.Clipboard.CopyTextToClipboard", | ||
[| content :> obj |] | ||
) | ||
} } | ||
|
||
module ListItems = | ||
|
||
|
||
let inline factory (services: IServiceProvider) : ITrackListItemService = | ||
let jsRuntime = | ||
services.GetService<IJSRuntime>() | ||
|
||
let loggerFactory = | ||
services.GetService<ILoggerFactory>() | ||
|
||
let logger = | ||
loggerFactory.CreateLogger<ITrackListItemService>() | ||
|
||
{ new ITrackListItemService with | ||
member _.GetHideDone listId = | ||
valueTask { | ||
|
||
let! hideDone = | ||
jsRuntime.InvokeAsync<bool>( | ||
"Mandadin.Database.GetHideDone", | ||
[| listId :> obj |] | ||
) | ||
|
||
return hideDone | ||
|
||
} | ||
|
||
member _.SetHideDone(listId, hideDone) = | ||
valueTaskUnit { | ||
do! | ||
jsRuntime.InvokeVoidAsync( | ||
"Mandadin.Database.SaveHideDone", | ||
[| listId :> obj; hideDone |] | ||
) | ||
} | ||
|
||
member self.CreateItem(listId, name) = | ||
taskResult { | ||
logger.LogDebug("Creating item: {listId}, {name}", listId, name) | ||
|
||
do! | ||
String.IsNullOrWhiteSpace name | ||
|> Result.requireFalse EmtptyString | ||
|
||
do! | ||
self.ItemExists(listId, name).AsTask() | ||
|> TaskResult.requireFalse (ExistingItem name) | ||
|
||
try | ||
|
||
let! created = | ||
jsRuntime.InvokeAsync<TrackListItem>( | ||
"Mandadin.Database.CreateListItem", | ||
[| listId :> obj; name |] | ||
) | ||
|
||
return created | ||
with exn -> | ||
logger.LogError( | ||
"Failed to create item: {listId}, {name}, error: {exn}", | ||
listId, | ||
name, | ||
exn | ||
) | ||
|
||
return! exn |> CreationFailed |> Error | ||
} | ||
|
||
|
||
member _.DeleteItem item = | ||
valueTaskUnit { | ||
do! | ||
jsRuntime.InvokeVoidAsync( | ||
"Mandadin.Database.DeleteListItem", | ||
[| item.Id :> obj |] | ||
) | ||
} | ||
|
||
|
||
member _.GetItems(listId, ?hideDone) = | ||
valueTask { | ||
let hideDone = defaultArg hideDone false | ||
|
||
try | ||
let! items = | ||
jsRuntime.InvokeAsync<list<TrackListItem>>( | ||
"Mandadin.Database.GetListItems", | ||
[| listId :> obj; hideDone |] | ||
) | ||
|
||
return items | ||
with ex -> | ||
logger.LogError( | ||
"Failed to get items for list: {listId}, error: {ex}", | ||
listId, | ||
ex | ||
) | ||
|
||
return List.empty | ||
} | ||
|
||
member _.ItemExists(listId, name) = | ||
valueTask { | ||
try | ||
let! exists = | ||
jsRuntime.InvokeAsync<bool>( | ||
"Mandadin.Database.ListItemExists", | ||
[| listId :> obj; name |] | ||
) | ||
|
||
return exists | ||
with ex -> | ||
logger.LogError( | ||
"Failed to check if item exists: {listId}, {name}, error: {ex}", | ||
listId, | ||
name, | ||
ex | ||
) | ||
|
||
return false | ||
} | ||
|
||
member _.UpdateItem item = | ||
valueTask { | ||
try | ||
let! updated = | ||
jsRuntime.InvokeAsync<TrackListItem>( | ||
"Mandadin.Database.UpdateListItem", | ||
[| item :> obj |] | ||
) | ||
|
||
return updated | ||
with ex -> | ||
logger.LogError( | ||
"Failed to update item: {item}, error: {ex}", | ||
item, | ||
ex | ||
) | ||
|
||
return item | ||
} } |
Oops, something went wrong.