github.com/simpleiot/simpleiot@v0.18.3/docs/ref/frontend.md (about)

     1  # Frontend
     2  
     3  ## Elm Reference Implementation
     4  
     5  The reference Simple IoT frontend is implemented in Elm as a Single Page
     6  Application (SPA) and is located in the
     7  [`frontend/`](https://github.com/simpleiot/simpleiot/tree/master/frontend)
     8  directory.
     9  
    10  ### Code Structure
    11  
    12  The frontend is based on [elm-spa](https://www.elm-spa.dev/), and is split into
    13  the following directories:
    14  
    15  - **Api**: contains core data structures and API code to communicate with
    16    backend (currently REST).
    17  - **Pages**: the various pages of the application
    18  - **Components**: each node type has a separate module that is used to render
    19    it. `NodeOptions.elm` contains a struct that is used to pass options into the
    20    component views.
    21  - **UI**: Various UI pieces we used
    22  - **Utils**: Code that does not fit anywhere else (time, etc)
    23  
    24  We'd like to keep the UI
    25  [optimistic](https://blog.meteor.com/optimistic-ui-with-meteor-67b5a78c3fcf) if
    26  possible.
    27  
    28  ### Creating Custom Icons
    29  
    30  SIOT icons are 24x24px pixels (based on feather icon format). One way to create
    31  them is to:
    32  
    33  - create a 24x24px drawing in InkScape, scale=1.0
    34  - draw your icon
    35  - if you use text
    36    - convert text to path: select text, and then menu Path -> Object to Path
    37    - make sure fill is set for path
    38  - save as plain SVG
    39  - set up a new Icon in `frontend/src/UI/Icon.elm` and use an existing custom
    40    icon like `variable` as a template.
    41  - copy the SVG path strings from the SVG file into the new Icon
    42  - you'll likely need to adjust the scaling transform numbers to get the icon to
    43    the right size
    44  
    45  (I've tried using: https://levelteams.com/svg-to-elm, but this has not been real
    46  useful, so I usually end up just copying the path strings into an elm template
    47  and hand edit the rest)
    48  
    49  ### File upload
    50  
    51  The [File node UI](../user/file.md) has the capability to upload files in the
    52  browser and then store them in a node point. The default max payload of NATS is
    53  1MB, so that is currently the file size limit, but NATS
    54  [can be configured](https://docs.nats.io/reference/faq#is-there-a-message-size-limitation-in-nats)
    55  for a payload size up to 64MB. 8MB is recommended.
    56  
    57  Currently the payload is stored in the Point `String` field for simplicity. If
    58  the binary option is selected, the data is base64 encoded. Long term it may make
    59  sense to support Jetstream Object store, local file store, etc.
    60  
    61  The [elm/file](https://package.elm-lang.org/packages/elm/file/latest/) package
    62  is used upload a file into the browser. Once the data is in the browser, it is
    63  sent to the backup as a standard point payload. Because we are currently using a
    64  JSON api, binary data is base64 encoded.
    65  
    66  The process by which a file is uploaded is:
    67  
    68  - The NodeOptions struct, which is passed to all nodes has a onUploadFile field,
    69    which is used to triggers the `UploadFile` message which runs a browser file
    70    select. The result of this select is a `UploadSelected` message.
    71  - This message calls `UploadFile node.node.id` in `Home_.elm`.
    72  - `File.Select.file` is called to select the file, which triggers the
    73    `UploadContents` message.
    74  - `UploadContents` is called with the node id, file name, and file contents,
    75    which then sends the data via points to the backend.
    76  
    77  ## SIOT JavaScript library using NATS over WebSockets
    78  
    79  This is a JavaScript library avaiable in the
    80  [`frontend/lib`](https://github.com/simpleiot/simpleiot/tree/master/frontend/lib)
    81  directory that can be used to interface a frontend with the SIOT backend.
    82  
    83  Usage:
    84  
    85  ```js
    86  import { connect } from "./lib/nats"
    87  
    88  async function connectAndGetNodes() {
    89  	const conn = await connect()
    90  	const [root] = await conn.getNode("root")
    91  	const children = await conn.getNodeChildren(root.id, { recursive: "flat" })
    92  	return [root].concat(children)
    93  }
    94  ```
    95  
    96  This library is also published on NPM (in the near future).
    97  
    98  (see [#357](https://github.com/simpleiot/simpleiot/pull/357))
    99  
   100  (Note, we are not currently using this yet in the SIOT frontend -- we still poll
   101  the backend over REST and fetch the entire node tree, but we are building out
   102  infrastructure so we don't have to do this.)
   103  
   104  ## Custom UIs
   105  
   106  The current SIOT UI is more an engineering type view than something that might
   107  be used by end users. For a custom/company product IoT portal where you want a
   108  custom web UI optimized for your products, there are several options:
   109  
   110  1. modify the existing SIOT frontend.
   111  1. write a new frontend, mobile app, desktop app, etc. The SIOT backend and
   112     frontend are decoupled so that this is possible.
   113  
   114  ### Passing a custom UI to SIOT
   115  
   116  There are ways to use a custom UI with SIOT at the app and package level:
   117  
   118  1. **Application:** pass a directory containing your public web assets to the
   119     app using: `siot serve -customUIDir <your web assets>`
   120  1. **Package:** populate CustomUIFS with a [fs.FS](https://pkg.go.dev/io/fs#FS)
   121     in the SIOT
   122     [Server options](https://pkg.go.dev/github.com/simpleiot/simpleiot/server#Options).
   123  
   124  In both cases, the filesystem should contain a `index.html` in the root
   125  directory. If it does not, you can use the
   126  [fs.Sub](https://pkg.go.dev/io/fs#Sub) function to return a subtree of a fs.FS.