mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-21 09:58:26 +00:00
Initial website
This commit is contained in:
36
website/elm/ExtraAttr.elm
Normal file
36
website/elm/ExtraAttr.elm
Normal file
@ -0,0 +1,36 @@
|
||||
module ExtraAttr exposing (..)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
|
||||
|
||||
ariaExpanded : Bool -> Attribute msg
|
||||
ariaExpanded flag =
|
||||
attribute "aria-expanded"
|
||||
(if flag then
|
||||
"true"
|
||||
|
||||
else
|
||||
"false"
|
||||
)
|
||||
|
||||
|
||||
ariaHidden : Bool -> Attribute msg
|
||||
ariaHidden flag =
|
||||
attribute "aria-hidden"
|
||||
(if flag then
|
||||
"true"
|
||||
|
||||
else
|
||||
"false"
|
||||
)
|
||||
|
||||
|
||||
ariaLabel : String -> Attribute msg
|
||||
ariaLabel name =
|
||||
attribute "aria-label" name
|
||||
|
||||
|
||||
role : String -> Attribute msg
|
||||
role name =
|
||||
attribute "role" name
|
110
website/elm/Feature.elm
Normal file
110
website/elm/Feature.elm
Normal file
@ -0,0 +1,110 @@
|
||||
module Feature exposing (..)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Markdown
|
||||
|
||||
|
||||
type alias Feature =
|
||||
{ image : String
|
||||
, header : String
|
||||
, description : String
|
||||
}
|
||||
|
||||
|
||||
featureBox : Int -> Feature -> Html msg
|
||||
featureBox index f =
|
||||
case isOdd index of
|
||||
False ->
|
||||
div [ class "columns is-vcentered box mb-5" ]
|
||||
[ div [ class "column is-three-quarter" ]
|
||||
[ figure [ class "image is-2by1 feature-image" ]
|
||||
[ img [ src f.image ] []
|
||||
]
|
||||
]
|
||||
, div [ class "column" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text f.header
|
||||
]
|
||||
, Markdown.toHtml []
|
||||
f.description
|
||||
]
|
||||
]
|
||||
|
||||
True ->
|
||||
div [ class "columns is-vcentered box mb-5" ]
|
||||
[ div [ class "column is-three-quarter" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text f.header
|
||||
]
|
||||
, Markdown.toHtml []
|
||||
f.description
|
||||
]
|
||||
, div [ class "column" ]
|
||||
[ figure [ class "image is-2by1 feature-image" ]
|
||||
[ img [ src f.image ] []
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
features : List Feature
|
||||
features =
|
||||
[ { image = "img/user-feature.png"
|
||||
, header = "Multi-User per Account"
|
||||
, description = """
|
||||
Each account (a *collective*) can have multiple users that share the
|
||||
same files. For example, everyone in your family can work with your
|
||||
files while using their own account with their own settings.
|
||||
"""
|
||||
}
|
||||
, { image = "img/ocr-feature.png"
|
||||
, header = "Text Extraction with OCR"
|
||||
, description = """
|
||||
Text is extracted from all files. For scanned documents/images, OCR is used by utilising tesseract. The text is analysed and is available for full-text search.
|
||||
"""
|
||||
}
|
||||
, { image = "img/filetype-feature.svg"
|
||||
, header = "Support for many files"
|
||||
, description = """
|
||||
Docspell can read many file types. ZIP and EML (e-mail file format) files are extracted and their contents imported.
|
||||
"""
|
||||
}
|
||||
, { image = "img/convertpdf-feature.svg"
|
||||
, header = "Conversion to PDF"
|
||||
, description = """
|
||||
All files are converted to PDF. Don't worry about the originals. Original files are stored, too and can be downloaded untouched. When creating PDFs from image data (often returned from scanners), the resulting PDF contains the extracted text and is searchable.
|
||||
"""
|
||||
}
|
||||
, { image = "img/fts-feature.png"
|
||||
, header = "Full-Text Search"
|
||||
, description = """
|
||||
The extracted text of all files and some properties, like names and notes, are available for full-text search. Full-text search can also be used to further constrain the results of the search-menu where you can search by tags, correspondent, etc.
|
||||
"""
|
||||
}
|
||||
, { image = "img/sendmail-feature.png"
|
||||
, header = "Send via E-Mail"
|
||||
, description = """
|
||||
|
||||
Users can define SMTP settings in the app and are then able to send items out via E-Mail. This is often useful to share with other people. There is e-mail-address completion from your address book, of course.
|
||||
|
||||
"""
|
||||
}
|
||||
, { image = "img/scanmailbox-feature.png"
|
||||
, header = "Import Mailboxes"
|
||||
, description = """
|
||||
Users can define IMAP settings so that docspell can import their e-mails. This can be done periodically based on a schedule. Imported mails can be moved away into another folder or deleted.
|
||||
"""
|
||||
}
|
||||
, { image = "img/notify-feature.png"
|
||||
, header = "Notifications"
|
||||
, description = """
|
||||
Users can be notified by e-mail for documents whose due-date comes closer.
|
||||
"""
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
isOdd : Int -> Bool
|
||||
isOdd num =
|
||||
modBy 2 num == 1
|
91
website/elm/GetStarted.elm
Normal file
91
website/elm/GetStarted.elm
Normal file
@ -0,0 +1,91 @@
|
||||
module GetStarted exposing (..)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Icons
|
||||
import Markdown
|
||||
|
||||
|
||||
getStarted : String -> List (Html msg)
|
||||
getStarted version =
|
||||
[ div [ class "content container is-size-5" ]
|
||||
[ Markdown.toHtml []
|
||||
"""Docspell consists of several components. The easiest way to get started is probably to use docker and
|
||||
[docker-compose](https://docs.docker.com/compose/)."""
|
||||
, Markdown.toHtml []
|
||||
("""1. Clone the github repository
|
||||
```bash
|
||||
$ git clone https://github.com/eikek/docspell
|
||||
```
|
||||
Alternatively, [download](https://github.com/eikek/docspell/archive/v"""
|
||||
++ version
|
||||
++ """.zip) the sources and extract the zip file.
|
||||
2. Change into the `docker` directory:
|
||||
```bash
|
||||
$ cd docspell/docker
|
||||
```
|
||||
3. Run `docker-compose up`:
|
||||
|
||||
```bash
|
||||
$ export DOCSPELL_HEADER_VALUE="my-secret-123"
|
||||
$ docker-compose up
|
||||
```
|
||||
|
||||
The environment variable defines a secret that is shared between
|
||||
some containers. You can define whatever you like. Please see the
|
||||
[`consumedir.sh`](doc/tools/consumedir#docker) docs for additional
|
||||
info.
|
||||
4. Goto <http://localhost:7880>, signup and login. When signing up,
|
||||
you can choose the same name for collective and user. Then login
|
||||
with this name and the password.
|
||||
|
||||
5. (Optional) Create a folder `./docs/<collective-name>` (the name you
|
||||
chose for the collective at registration) and place files in there
|
||||
for importing them.
|
||||
|
||||
The directory contains a file `docspell.conf` that you can
|
||||
[modify](docs/configure) as needed.
|
||||
"""
|
||||
)
|
||||
]
|
||||
, div [ class "content container" ]
|
||||
[ div [ class "notification is-info is-light" ]
|
||||
[ text "If you don't use docker, there are other ways that are "
|
||||
, text "described in the relevant "
|
||||
, a [ href "/docs/install" ]
|
||||
[ text "documentation page"
|
||||
]
|
||||
]
|
||||
]
|
||||
, div [ class "content container" ]
|
||||
[ div [ class "notification is-success is-light" ]
|
||||
[ div [ class "content is-medium" ]
|
||||
[ h3 [ class "title" ]
|
||||
[ text "Where to go from here?"
|
||||
]
|
||||
, ul []
|
||||
[ li []
|
||||
[ text "The "
|
||||
, a [ href "/docs/intro" ]
|
||||
[ text "introduction" ]
|
||||
, text " writes about the goals and basic idea."
|
||||
]
|
||||
, li []
|
||||
[ text "There is a comprehensive "
|
||||
, a [ href "/docs" ]
|
||||
[ text "documentation"
|
||||
]
|
||||
, text " available."
|
||||
]
|
||||
, li []
|
||||
[ text "The source code is hosted on "
|
||||
, a [ href "https://github.com/eikek/docspell" ]
|
||||
[ text "github"
|
||||
]
|
||||
, text "."
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
54
website/elm/Icons.elm
Normal file
54
website/elm/Icons.elm
Normal file
@ -0,0 +1,54 @@
|
||||
module Icons exposing (..)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
|
||||
|
||||
copyright : Html msg
|
||||
copyright =
|
||||
img [ src "icons/copyright-40.svg" ] []
|
||||
|
||||
|
||||
infoSquared : Html msg
|
||||
infoSquared =
|
||||
img [ src "icons/info-square-40.svg" ] []
|
||||
|
||||
|
||||
refresh : Html msg
|
||||
refresh =
|
||||
img [ src "icons/refresh-40.svg" ] []
|
||||
|
||||
|
||||
logo : Html msg
|
||||
logo =
|
||||
img [ src "icons/logo-only.svg" ] []
|
||||
|
||||
|
||||
logoMC : Html msg
|
||||
logoMC =
|
||||
img [ src "icons/logo-only-mc.svg" ] []
|
||||
|
||||
|
||||
logoWidth : Int -> Html msg
|
||||
logoWidth w =
|
||||
img [ src "icons/logo-only.svg", width w ] []
|
||||
|
||||
|
||||
home : Html msg
|
||||
home =
|
||||
img [ src "icons/home-40.svg" ] []
|
||||
|
||||
|
||||
docs : Html msg
|
||||
docs =
|
||||
img [ src "icons/notes-40.svg" ] []
|
||||
|
||||
|
||||
github : Html msg
|
||||
github =
|
||||
img [ src "/icons/github-40.svg" ] []
|
||||
|
||||
|
||||
githubGreen : Html msg
|
||||
githubGreen =
|
||||
img [ src "/icons/github-40-green.svg" ] []
|
313
website/elm/Main.elm
Normal file
313
website/elm/Main.elm
Normal file
@ -0,0 +1,313 @@
|
||||
module Main exposing (..)
|
||||
|
||||
import Browser exposing (Document)
|
||||
import Browser.Navigation exposing (Key)
|
||||
import ExtraAttr exposing (..)
|
||||
import Feature exposing (Feature)
|
||||
import GetStarted
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (..)
|
||||
import Icons
|
||||
import Random
|
||||
import Random.List
|
||||
|
||||
|
||||
|
||||
-- MAIN
|
||||
|
||||
|
||||
main : Program Flags Model Msg
|
||||
main =
|
||||
Browser.element
|
||||
{ init = init
|
||||
, view = view
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Model
|
||||
|
||||
|
||||
type alias Flags =
|
||||
{ version : String
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ navbarOpen : Bool
|
||||
, features : List Feature
|
||||
, flags : Flags
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= ToggleNavbarMenu
|
||||
| ShuffleFeatures
|
||||
| ListShuffled (List Feature)
|
||||
|
||||
|
||||
|
||||
--- Init
|
||||
|
||||
|
||||
viewFeatureCount : Int
|
||||
viewFeatureCount =
|
||||
10
|
||||
|
||||
|
||||
init : Flags -> ( Model, Cmd Msg )
|
||||
init flags =
|
||||
( { navbarOpen = False
|
||||
, features = List.take viewFeatureCount Feature.features
|
||||
, flags = flags
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
shuffleFeatures : Cmd Msg
|
||||
shuffleFeatures =
|
||||
Random.List.shuffle Feature.features
|
||||
|> Random.map (List.take viewFeatureCount)
|
||||
|> Random.generate ListShuffled
|
||||
|
||||
|
||||
|
||||
--- Update
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
ToggleNavbarMenu ->
|
||||
( { model | navbarOpen = not model.navbarOpen }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
ShuffleFeatures ->
|
||||
( model, shuffleFeatures )
|
||||
|
||||
ListShuffled lf ->
|
||||
( { model | features = lf }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
|
||||
--- View
|
||||
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
node "body"
|
||||
[]
|
||||
[ mainHero model
|
||||
, featureHero model
|
||||
, section [ class "section" ]
|
||||
[ div [ class "container" ]
|
||||
(List.indexedMap Feature.featureBox model.features
|
||||
++ [ div [ class "columns box" ]
|
||||
[ div [ class "column is-full" ]
|
||||
[ div [ class "content has-text-centered is-medium" ]
|
||||
[ text "A more complete list can be found in "
|
||||
, a [ href "/docs/features" ] [ text "here" ]
|
||||
, text "."
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
, getStartedHero model
|
||||
, div [ class "section" ]
|
||||
(GetStarted.getStarted model.flags.version)
|
||||
, footHero model
|
||||
]
|
||||
|
||||
|
||||
footHero : Model -> Html Msg
|
||||
footHero model =
|
||||
footer
|
||||
[ id "footer"
|
||||
, class "footer"
|
||||
]
|
||||
[ div [ class "has-text-centered" ]
|
||||
[ span []
|
||||
[ text ("Docspell, " ++ model.flags.version)
|
||||
]
|
||||
, span [ class "pr-1 pl-1" ]
|
||||
[ text " • "
|
||||
]
|
||||
, a
|
||||
[ href "https://spdx.org/licenses/GPL-3.0-or-later.html"
|
||||
, target "_blank"
|
||||
]
|
||||
[ text "GPLv3+"
|
||||
]
|
||||
, span [ class "pr-1 pl-1" ]
|
||||
[ text " • "
|
||||
]
|
||||
, a
|
||||
[ href "https://github.com/eikek/docspell"
|
||||
, target "_blank"
|
||||
]
|
||||
[ text "Source Code"
|
||||
]
|
||||
, span [ class "pr-1 pl-1" ]
|
||||
[ text " • "
|
||||
]
|
||||
, span []
|
||||
[ text "© 2020 "
|
||||
]
|
||||
, a
|
||||
[ href "https://github.com/eikek"
|
||||
, target "_blank"
|
||||
]
|
||||
[ text "@eikek"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
getStartedHero : Model -> Html Msg
|
||||
getStartedHero _ =
|
||||
section
|
||||
[ id "get-started"
|
||||
, class "hero is-primary is-bold"
|
||||
]
|
||||
[ div [ class "hero-body" ]
|
||||
[ div [ class "container" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text "Get Started"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
featureHero : Model -> Html Msg
|
||||
featureHero model =
|
||||
section
|
||||
[ id "feature-selection"
|
||||
, class "hero is-info is-bold"
|
||||
]
|
||||
[ div
|
||||
[ class "hero-body"
|
||||
]
|
||||
[ div [ class "container" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text "Feature Selection"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
mainHero : Model -> Html Msg
|
||||
mainHero model =
|
||||
section
|
||||
[ id "hero-main"
|
||||
, class "hero is-fullheight is-primary"
|
||||
]
|
||||
[ div [ class "hero-head" ]
|
||||
[ nav [ class "navbar" ]
|
||||
[ div [ class "navbar-brand" ]
|
||||
[ a
|
||||
[ class "navbar-item"
|
||||
, href "/"
|
||||
]
|
||||
[ span [ class "icon is-large" ]
|
||||
[ Icons.logo
|
||||
]
|
||||
, text "Docspell"
|
||||
]
|
||||
, a
|
||||
[ role "button"
|
||||
, onClick ToggleNavbarMenu
|
||||
, classList
|
||||
[ ( "navbar-burger", True )
|
||||
, ( "is-active", model.navbarOpen )
|
||||
]
|
||||
, ariaLabel "menu"
|
||||
, ariaExpanded False
|
||||
]
|
||||
[ span [ ariaHidden True ] []
|
||||
, span [ ariaHidden True ] []
|
||||
, span [ ariaHidden True ] []
|
||||
]
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "navbar-menu", True )
|
||||
, ( "is-active", model.navbarOpen )
|
||||
]
|
||||
]
|
||||
[ div [ class "navbar-start" ]
|
||||
[ a
|
||||
[ href "docs/"
|
||||
, class "navbar-item"
|
||||
]
|
||||
[ span [ class "icon" ]
|
||||
[ Icons.docs
|
||||
]
|
||||
, span []
|
||||
[ text "Documentation"
|
||||
]
|
||||
]
|
||||
, a
|
||||
[ target "_blank"
|
||||
, href "https://github.com/eikek/docspell"
|
||||
, class "navbar-item"
|
||||
]
|
||||
[ span [ class "icon" ]
|
||||
[ Icons.github
|
||||
]
|
||||
, span []
|
||||
[ text "Github"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
, div [ class "hero-body" ]
|
||||
[ div
|
||||
[ class "container has-text-centered"
|
||||
]
|
||||
[ Icons.logoWidth 112
|
||||
, h1 [ class "title main-title is-2" ]
|
||||
[ text "Docspell"
|
||||
]
|
||||
, h2 [ class "subtitle is-3" ]
|
||||
[ text "Simple document organizer"
|
||||
]
|
||||
, p [ class "content is-medium" ]
|
||||
[ text "Docspell can assist in organizing your piles of "
|
||||
, text "digital documents, resulting from scanners, e-mails "
|
||||
, text "and other sources with miminal effort."
|
||||
]
|
||||
, div [ class " buttons is-centered" ]
|
||||
[ a
|
||||
[ class "button is-primary is-medium"
|
||||
, href "#get-started"
|
||||
]
|
||||
[ text "Get Started"
|
||||
]
|
||||
, a
|
||||
[ class "button is-info is-medium"
|
||||
, href "#feature-selection"
|
||||
]
|
||||
[ text "Features"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
Reference in New Issue
Block a user