Skip to content

Commit

Permalink
Add standalone json export ✨#259
Browse files Browse the repository at this point in the history
  • Loading branch information
Freymaurer committed Mar 6, 2023
1 parent d7ebdeb commit 45ad00f
Show file tree
Hide file tree
Showing 12 changed files with 214 additions and 75 deletions.
3 changes: 2 additions & 1 deletion src/Client/Client.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@
<Compile Include="Modals\CytoscapeView.fs" />
<Compile Include="Spreadsheet\LocalStorage.fs" />
<Compile Include="Spreadsheet\Types.fs" />
<Compile Include="Spreadsheet\Parser.fs" />
<Compile Include="Spreadsheet\TypeConverter.fs" />
<Compile Include="Spreadsheet\Helper.fs" />
<Compile Include="Spreadsheet\Table.Controller.fs" />
<Compile Include="Spreadsheet\Export.Controller.fs" />
<Compile Include="Spreadsheet\Sidebar.Controller.fs" />
<Compile Include="SharedComponents\QuickAccessButton.fs" />
<Compile Include="MainComponents\NoTablesElement.fs" />
Expand Down
8 changes: 4 additions & 4 deletions src/Client/Pages/JsonExporter/JsonExporter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ let parseTableToISAJsonEle (model:Model) (dispatch:Messages.Msg -> unit) =
Button.a [
Button.Color IsInfo
Button.IsFullWidth
Button.OnClick(fun e ->
JsonExporterMsg ParseTableOfficeInteropRequest |> dispatch
Button.OnClick(fun _ ->
InterfaceMsg SpreadsheetInterface.ExportJsonTable |> dispatch
)
] [
str "Download as isa json"
Expand Down Expand Up @@ -295,8 +295,8 @@ let parseTablesToISAJsonEle (model:Model) (dispatch:Messages.Msg -> unit) =
Button.a [
Button.Color IsInfo
Button.IsFullWidth
Button.OnClick(fun e ->
JsonExporterMsg ParseTablesOfficeInteropRequest |> dispatch
Button.OnClick(fun _ ->
InterfaceMsg SpreadsheetInterface.ExportJsonTables |> dispatch
)
] [
str "Download as isa json"
Expand Down
2 changes: 1 addition & 1 deletion src/Client/SidebarComponents/Navbar.fs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ let NavbarComponent (model : Model) (dispatch : Msg -> unit) (sidebarsize: Model
Style [Width "100px"; Cursor "pointer"; Padding "0 0.4rem"]
]
] [
let path = if model.PageState.CurrentPage.isExpert then "_e" else ""
let path = if model.PageState.IsExpert then "_e" else ""
Image.image [] [ img [
Style [MaxHeight "100%"]
Props.Src @$"assets\Swate_logo_for_excel{path}.svg"
Expand Down
29 changes: 29 additions & 0 deletions src/Client/Spreadsheet/Export.Controller.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Spreadsheet.Export.Controller

open Shared.TermTypes
open Shared.OfficeInteropTypes
open Spreadsheet
open Spreadsheet.Table
open TypeConverter
open Types
open Helper

///<summary> Return active table.</summary>
let getTable (state: Spreadsheet.Model) =
let name = state.Tables.[state.ActiveTableIndex].Name
let swate_bbs = SwateBuildingBlock.ofTableMap state.ActiveTable
let bbs = swate_bbs |> Array.map (fun x -> x.toBuildingBlock)
name, bbs

///<summary> Returns all tables.</summary>
let getTables (state: Spreadsheet.Model) =
let state = Controller.saveActiveTable state
let tables =
state.Tables.Values
|> Array.ofSeq
|> Array.map (fun t ->
t.Name,
t.BuildingBlocks
|> Array.map (fun bb -> bb.toBuildingBlock)
)
tables
65 changes: 0 additions & 65 deletions src/Client/Spreadsheet/Parser.fs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Client/Spreadsheet/Sidebar.Controller.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ open System.Collections.Generic
open Shared.TermTypes
open Shared.OfficeInteropTypes
open Spreadsheet
open Parser
open TypeConverter
open Types
open Helper

Expand Down
2 changes: 1 addition & 1 deletion src/Client/Spreadsheet/Table.Controller.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ open System.Collections.Generic
open Shared.TermTypes
open Shared.OfficeInteropTypes
open Spreadsheet
open Parser
open TypeConverter
open Types
open Helper

Expand Down
120 changes: 120 additions & 0 deletions src/Client/Spreadsheet/TypeConverter.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
module Spreadsheet.TypeConverter

open Shared
open OfficeInteropTypes
open Spreadsheet

type InsertBuildingBlock with
member this.toSwateBuildingBlock(index:int) : SwateBuildingBlock =
let header = HeaderCell.create(this.ColumnHeader.Type, ?term = this.ColumnTerm, hasUnit = this.HasUnit)
let rows =
match this.HasValues, header.isTermColumn, this.HasUnit with
| _, true, true -> // even if no values exist, we want to add unit to body cells.
if this.Rows.Length = 0 then
Array.init 1 (fun i -> i + 1, SwateCell.create("", ?unit = this.UnitTerm))
else
this.Rows |> Array.mapi (fun i t -> i + 1, SwateCell.create(t.Name, ?unit = this.UnitTerm))
| true, true, false -> this.Rows |> Array.mapi (fun i t -> i + 1, SwateCell.create(t))
| true, false, _ -> this.Rows |> Array.mapi (fun i t -> i + 1, SwateCell.create(t.Name))
| false, _, _ -> [||]
SwateBuildingBlock.create(index, header, rows)

type SwateBuildingBlock with
member this.toBuildingBlock : BuildingBlock =
let mutable nextIndex = this.Index
let rows = this.Rows
let mainColumn =
let h = SwateColumnHeader.create this.Header.DisplayValue
let r = rows |> Array.map (fun (ind,x) ->
match x with
| IsUnit c -> Cell.create ind (Some c.Value) (Some c.Unit)
| IsTerm c -> Cell.create ind (Some c.Term.Name) None
| IsFreetext c -> Cell.create ind (Some c.Value) None
| IsHeader _ -> failwith "Body cell conversion should not happen on header."
)
Column.create nextIndex h r
let unit =
if this.Header.HasUnit then
let h = SwateColumnHeader.create(ColumnCoreNames.Unit.toString)
let r = rows |> Array.map (fun (ind,x) ->
match x with
| IsUnit c -> Cell.create ind (Some c.Unit.Name) None
| IsTerm _ | IsFreetext _ | IsHeader _ -> failwith "TSR conversion should not happen on freetext column or header."
)
nextIndex <- nextIndex + 1
Column.create nextIndex h r |> Some
else
None
let tsr =
if this.Header.isTermColumn then
let h = SwateColumnHeader.create(ColumnCoreNames.TermSourceRef.toString)
let r = rows |> Array.map (fun (ind,x) ->
match x with
| IsUnit c -> Cell.create ind (Some c.Unit.accessionToTSR) None
| IsTerm c -> Cell.create ind (Some c.Term.accessionToTSR) None
| IsFreetext _ | IsHeader _ -> failwith "TSR conversion should not happen on freetext column or header."
)
nextIndex <- nextIndex + 1
Column.create nextIndex h r |> Some
else
None
let tan =
if this.Header.isTermColumn then
let h = SwateColumnHeader.create(ColumnCoreNames.TermAccessionNumber.toString)
let r = rows |> Array.map (fun (ind,x) ->
match x with
| IsUnit c -> Cell.create ind (Some c.Unit.accessionToTAN) None
| IsTerm c -> Cell.create ind (Some c.Term.accessionToTAN) None
| IsFreetext _ | IsHeader _ -> failwith "TSR conversion should not happen on freetext column or header."
)
nextIndex <- nextIndex + 1
Column.create nextIndex h r |> Some
else
None
BuildingBlock.create mainColumn tsr tan unit this.Header.Term

module SwateBuildingBlock =

///<summary> Parse column of index `index` from ActiveTableMap `m` to SwateBuildingBlock. </summary>
let ofTableMap_byIndex (index: int) (m: Map<int*int,SwateCell>) =
let column = Map.filter (fun k _ -> fst k = index ) m
let header = column.[index, 0].Header
let rows = [|
for KeyValue ((_,rk),c) in column do
if rk <> 0 then
yield rk, c
|]
SwateBuildingBlock.create(index, header, rows)

///<summary>Returns a list instead of array.</summary>
let ofTableMap_list (m: Map<int*int,SwateCell>) : SwateBuildingBlock list =
let maxColIndex = m.Keys |> Seq.maxBy fst |> fst
[
for i in 0 .. maxColIndex do
yield ofTableMap_byIndex i m
]

let ofTableMap (m: Map<int*int,SwateCell>) : SwateBuildingBlock [] =
let maxColIndex = m.Keys |> Seq.maxBy fst |> fst
[|
for i in 0 .. maxColIndex do
yield ofTableMap_byIndex i m
|]

let toTableMap (buildingBlocks: seq<SwateBuildingBlock>) : Map<int*int,SwateCell> =
buildingBlocks
|> Seq.collect (fun bb ->
let columnIndex = bb.Index
let header = (columnIndex, 0), IsHeader bb.Header
let rows =
bb.Rows |> Array.map (fun (i,c) ->
(columnIndex, i), c
)
[|
yield header
yield! rows
|]
)
|> Map.ofSeq


4 changes: 4 additions & 0 deletions src/Client/States/Spreadsheet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ type Msg =
| ImportFile of (string*InsertBuildingBlock []) []
| InsertOntologyTerm of TermTypes.TermMinimal
| InsertOntologyTerms of TermTypes.TermMinimal []
/// Starts chain to export active table to isa json
| ExportJsonTable
/// Starts chain to export all tables to isa json
| ExportJsonTables
// <--> Result Messages <-->
/// This message will save `Model` to local storage and to session storage for history
| Success of Model
Expand Down
6 changes: 5 additions & 1 deletion src/Client/States/SpreadsheetInterface.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ type Msg =
| ImportFile of (string*InsertBuildingBlock []) []
/// Inserts TermMinimal to selected fields of one column
| InsertOntologyTerm of TermTypes.TermMinimal
| InsertFileNames of string list
| InsertFileNames of string list
/// Starts chain to export active table to isa json
| ExportJsonTable
/// Starts chain to export all tables to isa json
| ExportJsonTables
19 changes: 19 additions & 0 deletions src/Client/Update/InterfaceUpdate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,23 @@ module Interface =
Spreadsheet.DeleteColumn (distinct.[0]) |> SpreadsheetMsg |> Cmd.ofMsg
model, cmd
| _ -> failwith "not implemented"
| ExportJsonTable ->
match host with
| Swatehost.Excel _ ->
let cmd = JsonExporterMsg JsonExporter.State.ParseTableOfficeInteropRequest |> Cmd.ofMsg
model, cmd
| Swatehost.Browser ->
let cmd = SpreadsheetMsg Spreadsheet.ExportJsonTable |> Cmd.ofMsg
model, cmd
| _ -> failwith "not implemented"
| ExportJsonTables ->
match host with
| Swatehost.Excel _ ->
let cmd = JsonExporterMsg JsonExporter.State.ParseTablesOfficeInteropRequest |> Cmd.ofMsg
model, cmd
| Swatehost.Browser ->
let cmd = SpreadsheetMsg Spreadsheet.ExportJsonTables |> Cmd.ofMsg
model, cmd
| _ -> failwith "not implemented"


29 changes: 28 additions & 1 deletion src/Client/Update/SpreadsheetUpdate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ open Elmish
open Spreadsheet
open Model
open Shared
open Parser
open TypeConverter
open Spreadsheet.Table
open Spreadsheet.Sidebar
open Spreadsheet.Export

module Spreadsheet =

Expand Down Expand Up @@ -135,6 +136,32 @@ module Spreadsheet =
(ImportFile >> Messages.SpreadsheetMsg)
(Messages.curry Messages.GenericError Cmd.none >> Messages.DevMsg)
state, model, cmd
| ExportJsonTable ->
let exportJsonState = {model.JsonExporterModel with Loading = true}
let nextModel = model.updateByJsonExporterModel exportJsonState
let func() = promise {
return Controller.getTable state
}
let cmd =
Cmd.OfPromise.either
func
()
(JsonExporter.State.ParseTableServerRequest >> Messages.JsonExporterMsg)
(Messages.curry Messages.GenericError (JsonExporter.State.UpdateLoading false |> Messages.JsonExporterMsg |> Cmd.ofMsg) >> Messages.DevMsg)
state, nextModel, cmd
| ExportJsonTables ->
let exportJsonState = {model.JsonExporterModel with Loading = true}
let nextModel = model.updateByJsonExporterModel exportJsonState
let func() = promise {
return Controller.getTables state
}
let cmd =
Cmd.OfPromise.either
func
()
(JsonExporter.State.ParseTablesServerRequest >> Messages.JsonExporterMsg)
(Messages.curry Messages.GenericError (JsonExporter.State.UpdateLoading false |> Messages.JsonExporterMsg |> Cmd.ofMsg) >> Messages.DevMsg)
state, nextModel, cmd
| Success nextState ->
Spreadsheet.LocalStorage.tablesToLocalStorage nextState // This will cache the most up to date table state to local storage.
Spreadsheet.LocalStorage.tablesToSessionStorage nextState // this will cache the table state for certain operations in session storage.
Expand Down

0 comments on commit 45ad00f

Please sign in to comment.