Website redesign
6
.gitignore
vendored
@ -7,10 +7,14 @@ elm-stuff
|
||||
result
|
||||
_site/
|
||||
*.qcow2
|
||||
/website/site/content/docs/changelog/
|
||||
/website/site/content/docs/install/changelog.md
|
||||
/website/site/public/
|
||||
/website/site/static/openapi/
|
||||
/website/site/static/js/bundle.js
|
||||
/website/site/static/styles.css
|
||||
/website/site/static/syntax-*.css
|
||||
/website/site/static/webfonts/
|
||||
/website/site/static/files/*.woff*
|
||||
/website/site/templates/shortcodes/server.conf
|
||||
/website/site/templates/shortcodes/sample-exim.conf
|
||||
/website/site/templates/shortcodes/joex.conf
|
||||
|
@ -840,19 +840,17 @@ val website = project
|
||||
}.taskValue,
|
||||
Compile / resourceGenerators += Def.task {
|
||||
val changelog = (LocalRootProject / baseDirectory).value / "Changelog.md"
|
||||
val targetDir = baseDirectory.value / "site" / "content" / "docs" / "changelog"
|
||||
val targetDir = baseDirectory.value / "site" / "content" / "docs" / "install"
|
||||
IO.createDirectory(targetDir)
|
||||
val target = targetDir / "_index.md"
|
||||
val target = targetDir / "changelog.md"
|
||||
|
||||
IO.write(
|
||||
target,
|
||||
"""|+++
|
||||
|title = "Changelog"
|
||||
|description = "See what changed between releases."
|
||||
|weight = 10
|
||||
|weight = 10000
|
||||
|insert_anchor_links = "right"
|
||||
|[extra]
|
||||
|maketoc = false
|
||||
|+++
|
||||
|""".stripMargin
|
||||
)
|
||||
|
@ -15,6 +15,7 @@ object Cmd {
|
||||
}
|
||||
|
||||
def run(cmd: Seq[String], wd: File, logger: Logger): Unit = {
|
||||
logger.info(s"Running ${cmd.mkString(" ")}")
|
||||
val res = Cmd.exec(cmd, Some(wd))
|
||||
logger.info(res.out)
|
||||
logger.error(res.err)
|
||||
|
@ -2,6 +2,7 @@ package docspell.build
|
||||
|
||||
import sbt._
|
||||
import sbt.Keys._
|
||||
import sbt.nio.file.FileTreeView
|
||||
import scala.sys.process._
|
||||
|
||||
object ZolaPlugin extends AutoPlugin {
|
||||
@ -74,10 +75,12 @@ object ZolaPlugin extends AutoPlugin {
|
||||
case Some(url) =>
|
||||
Seq("--base-url", url)
|
||||
case None =>
|
||||
runYarnInstall("yarn", inDir.getParentFile, logger)
|
||||
runElmCompile("elm", inDir.getParentFile, inDir, logger)
|
||||
Seq.empty
|
||||
}
|
||||
runYarnInstall("yarn", inDir.getParentFile, logger)
|
||||
runElmCompile("elm", inDir.getParentFile, inDir, logger)
|
||||
runTailwind("npx", inDir.getParentFile, inDir, logger)
|
||||
|
||||
Cmd.run(
|
||||
Seq(zolaCmd, "build", "-o", outDir.absolutePath.toString) ++ baseUrl,
|
||||
inDir,
|
||||
@ -106,4 +109,39 @@ object ZolaPlugin extends AutoPlugin {
|
||||
logger
|
||||
)
|
||||
|
||||
def runTailwind(npx: String, inDir: File, zolaRoot: File, logger: Logger): Unit = {
|
||||
val fontTarget = zolaRoot / "static" / "files"
|
||||
val iconTarget = zolaRoot / "static" / "webfonts"
|
||||
IO.createDirectories(Seq(fontTarget, iconTarget))
|
||||
|
||||
val fontIn = Glob(inDir / "node_modules" / "@fontsource") / * / "files" / *
|
||||
val fontInFiles = FileTreeView.default.list(fontIn).map(_._1.toFile())
|
||||
logger.info(s"Copy ${fontInFiles.size} webfonts from node_modules to ${fontTarget}…")
|
||||
IO.copy(fontInFiles.pair(Path.flat(fontTarget)))
|
||||
|
||||
val iconIn =
|
||||
Glob(inDir / "node_modules" / "@fortawesome" / "fontawesome-free" / "webfonts") / *
|
||||
val iconInFiles = FileTreeView.default.list(iconIn).map(_._1.toFile())
|
||||
logger.info(s"Copy ${iconInFiles.size} icons from node_modules to ${iconTarget}…")
|
||||
IO.copy(iconInFiles.pair(Path.flat(iconTarget)))
|
||||
|
||||
logger.info("Running tailwind…")
|
||||
Cmd.run(
|
||||
Seq(
|
||||
npx,
|
||||
"tailwindcss",
|
||||
"-i",
|
||||
(inDir / "styles" / "input.css").toString,
|
||||
"-o",
|
||||
(zolaRoot / "static" / "styles.css").toString,
|
||||
"--config",
|
||||
(inDir / "tailwind.config.js").toString,
|
||||
"--postcss",
|
||||
(inDir / "postcss.config.js").toString,
|
||||
"--minify"
|
||||
),
|
||||
inDir,
|
||||
logger
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -8,61 +8,61 @@ The website is created using [zola](https://github.com/getzola/zola)
|
||||
static site generator. The (very minimal) dynamic parts are written in
|
||||
Elm.
|
||||
|
||||
The `build.sh` script builds the site.
|
||||
Sbt is used to build the site.
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
Install things by running `yarn install`.
|
||||
|
||||
Open two terminals. In first run:
|
||||
Open terminal for each script below:
|
||||
|
||||
``` shell
|
||||
nix-shell --run ./run-elm.sh
|
||||
```
|
||||
|
||||
and in the second
|
||||
|
||||
``` shell
|
||||
nix-shell --run "cd site && zola serve"
|
||||
```
|
||||
1. Starting the server
|
||||
``` shell
|
||||
nix-shell --run "cd site && zola serve"
|
||||
```
|
||||
2. Building the stylesheet
|
||||
``` shell
|
||||
nix-shell --run ./scripts/run-styles.sh
|
||||
```
|
||||
3. Building some javascript files
|
||||
``` shell
|
||||
nix-shell --run ./scripts/run-elm.sh
|
||||
```
|
||||
|
||||
Open browser at `localhost:1111`.
|
||||
|
||||
|
||||
## Publishing
|
||||
|
||||
The above is great when editing, but doesn't fully reflect what will
|
||||
be finally deployed. To see this, start sbt and change into the
|
||||
website project.
|
||||
|
||||
``` shell
|
||||
nix-shell website/shell.nix --run sbt
|
||||
sbt> project website
|
||||
```
|
||||
|
||||
### Check Links
|
||||
Build everything and check for dead links:
|
||||
|
||||
``` scala
|
||||
sbt> zolaBuild
|
||||
sbt> zolaBuildTest
|
||||
sbt> zolaCheck
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
``` scala
|
||||
sbt> zolaBuildTest
|
||||
sbt> ghpagesSynchLocal
|
||||
```
|
||||
|
||||
Other terminal:
|
||||
The final site is now generated and a simple http server can be used
|
||||
to see how it will look when deployed.
|
||||
|
||||
``` shell
|
||||
cd ~/.sbt/ghpages/<some-hash>/com.github.eikek/docspell-website
|
||||
python -m SimpleHTTPServer 1234
|
||||
python -m http.server 1234
|
||||
```
|
||||
|
||||
Open http://localhost:1234 in a browser.
|
||||
|
||||
### Publish
|
||||
|
||||
``` scala
|
||||
sbt> zolaBuild
|
||||
sbt> ghpagesPushSite
|
||||
```
|
||||
|
@ -14,25 +14,21 @@ type alias Demo =
|
||||
|
||||
demo : Demo -> Html msg
|
||||
demo data =
|
||||
div [ class "columns is-vcentered box mb-5" ]
|
||||
[ div [ class "column" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text data.title
|
||||
]
|
||||
, if data.info == "" then
|
||||
span [] []
|
||||
div [ class "px-4 py-4 mx-2 sm:mx-8 rounded border shadow-lg flex flex-col" ]
|
||||
[ h2 [ class "text-3xl font-bold py-2 font-serif" ]
|
||||
[ text data.title
|
||||
]
|
||||
, if data.info == "" then
|
||||
span [] []
|
||||
|
||||
else
|
||||
p []
|
||||
[ Markdown.toHtml [] data.info
|
||||
]
|
||||
, div [ class "mt-5 columns is-centered" ]
|
||||
[ video
|
||||
[ src data.url
|
||||
, controls True
|
||||
]
|
||||
[]
|
||||
else
|
||||
Markdown.toHtml [ class "text-lg" ] data.info
|
||||
, div [ class "mt-6 self-center" ]
|
||||
[ video
|
||||
[ src data.url
|
||||
, controls True
|
||||
]
|
||||
[]
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -14,38 +14,66 @@ type alias Feature =
|
||||
|
||||
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
|
||||
]
|
||||
]
|
||||
let
|
||||
titleCss =
|
||||
"text-3xl font-bold font-serif mb-3"
|
||||
|
||||
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 ] []
|
||||
boxCss =
|
||||
[ class "flex-col space-y-2"
|
||||
, class "sm:flex-row sm:space-y-0 sm-space-x-4"
|
||||
, class "flex px-8 py-8 border rounded mb-5 shadow-lg mx-2 sm:mx-8"
|
||||
]
|
||||
|
||||
descrCss =
|
||||
"flex flex-col text-xl "
|
||||
in
|
||||
if isOdd index then
|
||||
div boxCss
|
||||
[ div [ class "sm:w-1/2" ]
|
||||
[ figure [ class "block my-auto" ]
|
||||
[ img
|
||||
[ src f.image
|
||||
, class "w-full"
|
||||
, style "min-width" "4rem"
|
||||
]
|
||||
[]
|
||||
]
|
||||
]
|
||||
, div
|
||||
[ class descrCss
|
||||
, class "pl-4 sm:w-1/2"
|
||||
]
|
||||
[ h2 [ class titleCss ]
|
||||
[ text f.header
|
||||
]
|
||||
, Markdown.toHtml []
|
||||
f.description
|
||||
]
|
||||
]
|
||||
|
||||
else
|
||||
div
|
||||
boxCss
|
||||
[ div
|
||||
[ class descrCss
|
||||
, class "pr-4 sm:w-1/2"
|
||||
]
|
||||
[ h2 [ class titleCss ]
|
||||
[ text f.header
|
||||
]
|
||||
, Markdown.toHtml []
|
||||
f.description
|
||||
]
|
||||
, div [ class "sm:w-1/2" ]
|
||||
[ figure [ class "block my-auto " ]
|
||||
[ img
|
||||
[ src f.image
|
||||
, class "w-full"
|
||||
]
|
||||
[]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
features : List Feature
|
||||
@ -105,7 +133,7 @@ Users can define IMAP settings so that docspell can import their e-mails. This c
|
||||
, { image = "img/notify-feature.png"
|
||||
, header = "Notifications"
|
||||
, description = """
|
||||
Users can be notified by e-mail for documents whose due-date comes closer.
|
||||
Users can be notified by e-mail, Matrix or Gotify with documents resulting from a query that is executed periodically. Notifications can also be configured for specific events.
|
||||
"""
|
||||
}
|
||||
]
|
||||
|
@ -2,35 +2,32 @@ 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" ]
|
||||
[ Markdown.toHtml []
|
||||
getStarted : String -> Html msg
|
||||
getStarted _ =
|
||||
div [ class "container max-w-screen-lg mx-auto text-xl px-10 lg:px-0 leading-relaxed min-h-screen" ]
|
||||
[ Markdown.toHtml [ class "my-4 markdown-view" ]
|
||||
"""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 []
|
||||
, Markdown.toHtml [ class "my-4 markdown-view " ]
|
||||
"""1. Clone the github repository
|
||||
```bash
|
||||
$ git clone https://github.com/eikek/docspell
|
||||
```
|
||||
Alternatively, [download](https://github.com/eikek/docspell/archive/master.zip) the sources and extract the zip file.
|
||||
2. Change into the `docker` directory:
|
||||
2. Change into the `docker-compose` directory:
|
||||
```bash
|
||||
$ cd docspell/docker/docker-compose
|
||||
```
|
||||
3. Run `docker-compose up`:
|
||||
|
||||
```bash
|
||||
$ docker-compose up -d
|
||||
```
|
||||
4. Goto <http://localhost:7880>, signup and login. When signing up,
|
||||
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.
|
||||
@ -38,58 +35,51 @@ getStarted version =
|
||||
The `docker-compose.yml` file defines some environment variables to
|
||||
configure docspell. You can [modify](docs/configure) them as needed.
|
||||
"""
|
||||
]
|
||||
, div [ class "content container" ]
|
||||
[ div [ class "notification is-info is-light" ]
|
||||
, div [ class "blue-message" ]
|
||||
[ text "If you don't use docker, there are other ways that are "
|
||||
, text "described in the relevant "
|
||||
, a [ href "/docs/install" ]
|
||||
, a [ href "/docs/install", class "link" ]
|
||||
[ 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?"
|
||||
, div [ class "green-message mt-4 " ]
|
||||
[ h3 [ class "text-4xl font-bold font-serif py-2 mb-2" ]
|
||||
[ text "Where to go from here?"
|
||||
]
|
||||
, ul [ class "list-disc list-inside " ]
|
||||
[ li []
|
||||
[ text "Find out "
|
||||
, a [ href "/docs/feed" ]
|
||||
[ text "how files can get into Docspell."
|
||||
]
|
||||
]
|
||||
, ul []
|
||||
[ li []
|
||||
[ text "Find out "
|
||||
, a [ href "/docs/feed" ]
|
||||
[ text "how files can get into Docspell."
|
||||
]
|
||||
, 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"
|
||||
]
|
||||
, li []
|
||||
[ text "The "
|
||||
, a [ href "/docs/intro" ]
|
||||
[ text "introduction" ]
|
||||
, text " writes about the goals and basic idea."
|
||||
, text " available."
|
||||
]
|
||||
, li []
|
||||
[ text "The source code is hosted on "
|
||||
, a [ href "https://github.com/eikek/docspell" ]
|
||||
[ text "github"
|
||||
]
|
||||
, 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 "."
|
||||
]
|
||||
, li []
|
||||
[ text "Chat on "
|
||||
, a [ href "https://gitter.im/eikek/docspell" ]
|
||||
[ text "Gitter"
|
||||
]
|
||||
, text " for questions and feedback."
|
||||
, text "."
|
||||
]
|
||||
, li []
|
||||
[ text "Chat on "
|
||||
, a [ href "https://gitter.im/eikek/docspell" ]
|
||||
[ text "Gitter"
|
||||
]
|
||||
, text " for questions and feedback."
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ import Html.Attributes exposing (..)
|
||||
|
||||
copyright : Html msg
|
||||
copyright =
|
||||
img [ src "icons/copyright-40.svg" ] []
|
||||
i [ class "fa fa-copyright font-thin" ] []
|
||||
|
||||
|
||||
infoSquared : Html msg
|
||||
@ -36,19 +36,24 @@ logoWidth w =
|
||||
|
||||
home : Html msg
|
||||
home =
|
||||
img [ src "icons/home-40.svg" ] []
|
||||
i [ class "fa fa-home" ] []
|
||||
|
||||
|
||||
docs : Html msg
|
||||
docs =
|
||||
img [ src "icons/notes-40.svg" ] []
|
||||
i [ class "fa fa-book" ] []
|
||||
|
||||
|
||||
github : Html msg
|
||||
github =
|
||||
img [ src "/icons/github-40.svg" ] []
|
||||
i [ class "fab fa-github-alt" ] []
|
||||
|
||||
|
||||
githubGreen : Html msg
|
||||
githubGreen =
|
||||
img [ src "/icons/github-40-green.svg" ] []
|
||||
|
||||
|
||||
blog : Html msg
|
||||
blog =
|
||||
i [ class "fa fa-blog" ] []
|
||||
|
@ -1,7 +1,6 @@
|
||||
module Main exposing (..)
|
||||
|
||||
import Browser exposing (Document)
|
||||
import Browser.Navigation exposing (Key)
|
||||
import Browser
|
||||
import Demo
|
||||
import ExtraAttr exposing (..)
|
||||
import Feature exposing (Feature)
|
||||
@ -109,34 +108,33 @@ subscriptions _ =
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
node "body"
|
||||
[]
|
||||
[ class "text-gray-700" ]
|
||||
[ mainHero model
|
||||
, demoHero
|
||||
, section [ class "section" ]
|
||||
[ div [ class "container" ]
|
||||
, demoHeader
|
||||
, section [ class "container max-w-screen-xl mx-auto mb-2" ]
|
||||
[ div [ class "mt-3 flex flex-col space-y-4" ]
|
||||
[ Demo.demo Demo.processDemo
|
||||
, Demo.demo Demo.navigateDemo
|
||||
]
|
||||
]
|
||||
, 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 "."
|
||||
]
|
||||
]
|
||||
, featureHeader model
|
||||
, section [ class "mx-auto max-w-screen-xl mb-2 mt-4" ]
|
||||
(List.indexedMap Feature.featureBox model.features
|
||||
++ [ div
|
||||
[ class "flex px-8 py-8 border rounded mb-5 shadow-lg text-2xl"
|
||||
, class "sm:flex-row sm:space-y-0 sm-space-x-4"
|
||||
, class "mx-2 sm:mx-8"
|
||||
]
|
||||
[ div [ class "text-center w-full" ]
|
||||
[ text "A more complete list can be found in "
|
||||
, a [ href "/docs/features", class "link" ] [ text "here" ]
|
||||
, text "."
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
, getStartedHero model
|
||||
, div [ class "section" ]
|
||||
(GetStarted.getStarted model.flags.version)
|
||||
]
|
||||
]
|
||||
)
|
||||
, getStartedHeader model
|
||||
, GetStarted.getStarted model.flags.version
|
||||
, footHero model
|
||||
]
|
||||
|
||||
@ -147,7 +145,7 @@ footHero model =
|
||||
[ id "footer"
|
||||
, class "footer"
|
||||
]
|
||||
[ div [ class "has-text-centered" ]
|
||||
[ div [ class "text-center" ]
|
||||
[ span []
|
||||
[ text ("Docspell, " ++ model.flags.version)
|
||||
]
|
||||
@ -157,6 +155,7 @@ footHero model =
|
||||
, a
|
||||
[ href "https://spdx.org/licenses/AGPL-3.0-or-later.html"
|
||||
, target "_blank"
|
||||
, class "link"
|
||||
]
|
||||
[ text "AGPLv3+"
|
||||
]
|
||||
@ -166,6 +165,7 @@ footHero model =
|
||||
, a
|
||||
[ href "https://github.com/eikek/docspell"
|
||||
, target "_blank"
|
||||
, class "link"
|
||||
]
|
||||
[ text "Source Code"
|
||||
]
|
||||
@ -176,6 +176,7 @@ footHero model =
|
||||
[ a
|
||||
[ href "https://gitter.im/eikek/docspell"
|
||||
, target "_blank"
|
||||
, class "link"
|
||||
]
|
||||
[ text "Chat on Gitter"
|
||||
]
|
||||
@ -184,166 +185,142 @@ footHero model =
|
||||
]
|
||||
|
||||
|
||||
getStartedHero : Model -> Html Msg
|
||||
getStartedHero _ =
|
||||
getStartedHeader : Model -> Html Msg
|
||||
getStartedHeader _ =
|
||||
section
|
||||
[ id "get-started"
|
||||
, class "hero is-primary is-bold"
|
||||
, class "hero-header"
|
||||
]
|
||||
[ div [ class "hero-body" ]
|
||||
[ div [ class "container" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text "Get Started"
|
||||
]
|
||||
]
|
||||
]
|
||||
[ text "Get Started"
|
||||
]
|
||||
|
||||
|
||||
demoHero : Html msg
|
||||
demoHero =
|
||||
section
|
||||
[ id "demos"
|
||||
, class "hero is-info is-bold"
|
||||
demoHeader : Html msg
|
||||
demoHeader =
|
||||
h2
|
||||
[ class "hero-header"
|
||||
, id "demos"
|
||||
]
|
||||
[ div
|
||||
[ class "hero-body"
|
||||
]
|
||||
[ div [ class "container" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text "Screencasts"
|
||||
]
|
||||
]
|
||||
]
|
||||
[ text "Screencasts"
|
||||
]
|
||||
|
||||
|
||||
featureHero : Model -> Html Msg
|
||||
featureHero model =
|
||||
section
|
||||
featureHeader : Model -> Html Msg
|
||||
featureHeader _ =
|
||||
h2
|
||||
[ id "feature-selection"
|
||||
, class "hero is-info is-bold"
|
||||
, class "hero-header"
|
||||
]
|
||||
[ div
|
||||
[ class "hero-body"
|
||||
[ text "Feature Selection"
|
||||
]
|
||||
|
||||
|
||||
navBar : String -> Html Msg
|
||||
navBar classes =
|
||||
nav
|
||||
[ id "top-nav"
|
||||
, class "top-0 z-50 w-full flex flex-row justify-start shadow-sm h-14 antialiased "
|
||||
, class classes
|
||||
]
|
||||
[ a
|
||||
[ onClick ToggleNavbarMenu
|
||||
, href "#"
|
||||
, class "font-bold inline-flex items-center px-4 w-10 sm:hidden "
|
||||
]
|
||||
[ div [ class "container" ]
|
||||
[ h2 [ class "title" ]
|
||||
[ text "Feature Selection"
|
||||
]
|
||||
[ i [ class "fa fa-bars" ] []
|
||||
]
|
||||
, a
|
||||
[ class "inline-flex px-4 items-center hover:bg-gray-50 hover:bg-opacity-20"
|
||||
, href "/"
|
||||
]
|
||||
[ div [ class "" ]
|
||||
[ Icons.logo
|
||||
]
|
||||
, span [ class "ml-1 text-2xl font-semibold font-serif" ]
|
||||
[ text "Docspell" ]
|
||||
]
|
||||
, a
|
||||
[ href "docs/"
|
||||
, class "px-4 flex items-center hover:bg-gray-50 hover:bg-opacity-20"
|
||||
, class " text-xl"
|
||||
]
|
||||
[ Icons.docs
|
||||
, span [ class "ml-2 tracking-wide" ]
|
||||
[ text "Documentation"
|
||||
]
|
||||
]
|
||||
, a
|
||||
[ href "blog/"
|
||||
, class "px-4 flex items-center hover:bg-gray-50 hover:bg-opacity-20"
|
||||
, class " text-xl"
|
||||
]
|
||||
[ Icons.blog
|
||||
, span [ class "ml-2 tracking-wide" ]
|
||||
[ text "Blog"
|
||||
]
|
||||
]
|
||||
, a
|
||||
[ target "_blank"
|
||||
, href "https://github.com/eikek/docspell"
|
||||
, class "px-4 flex items-center hover:bg-gray-50 hover:bg-opacity-20"
|
||||
, class " text-xl"
|
||||
]
|
||||
[ Icons.github
|
||||
, span [ class "ml-2 tracking-wide" ]
|
||||
[ text "Github"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
mainHero : Model -> Html Msg
|
||||
mainHero model =
|
||||
mainHero _ =
|
||||
section
|
||||
[ id "hero-main"
|
||||
, class "hero is-fullheight is-primary"
|
||||
, class "min-h-screen text-white flex flex-col items-center main-background"
|
||||
]
|
||||
[ 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 ] []
|
||||
]
|
||||
[ navBar " text-white"
|
||||
, div [ class "flex-grow flex flex-col items-center justify-center w-full" ]
|
||||
[ Icons.logoWidth 112
|
||||
, h1 [ class "text-6xl font-semibold shadow font-serif" ]
|
||||
[ text "Docspell"
|
||||
]
|
||||
, h2 [ class "text-3xl font-madium tracking-wide mt-2 mb-4 " ]
|
||||
[ text "Simple document organizer"
|
||||
]
|
||||
, p [ class "px-2 text-center text-xl font-light shadow max-w-prose font-sans" ]
|
||||
[ text "Docspell assists in organizing your piles of "
|
||||
, text "digital documents, resulting from scanners, e-mails "
|
||||
, text "and other sources with miminal effort."
|
||||
]
|
||||
, div
|
||||
[ class "mt-4 flex flex-col space-y-2 text-2xl"
|
||||
, class "sm:items-center sm:flex-row sm:space-y-0 sm:space-x-4"
|
||||
]
|
||||
[ a
|
||||
[ class "button info"
|
||||
, href "#demos"
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "navbar-menu", True )
|
||||
, ( "is-active", model.navbarOpen )
|
||||
]
|
||||
[ text "Screencasts"
|
||||
]
|
||||
[ 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"
|
||||
]
|
||||
]
|
||||
]
|
||||
, a
|
||||
[ class "button info"
|
||||
, href "#feature-selection"
|
||||
]
|
||||
[ text "Features"
|
||||
]
|
||||
, a
|
||||
[ class "button primary"
|
||||
, href "#get-started"
|
||||
]
|
||||
[ text "Get Started"
|
||||
]
|
||||
]
|
||||
]
|
||||
, 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 narrow-center" ]
|
||||
[ text "Docspell assists 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-info is-medium"
|
||||
, href "#demos"
|
||||
]
|
||||
[ text "Screencasts"
|
||||
]
|
||||
, a
|
||||
[ class "button is-info is-medium"
|
||||
, href "#feature-selection"
|
||||
]
|
||||
[ text "Features"
|
||||
]
|
||||
, a
|
||||
[ class "button is-primary is-medium"
|
||||
, href "#get-started"
|
||||
]
|
||||
[ text "Get Started"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
, div [ class "hero-foot" ]
|
||||
[ span [ class "unsplash-credit" ]
|
||||
[ text "Photo by "
|
||||
, div [ class "text-right w-full" ]
|
||||
[ span [ class "opacity-40 text-xs" ]
|
||||
[ i [ class "fab fa-unsplash mr-1" ] []
|
||||
, text "Photo by "
|
||||
, a
|
||||
[ href "https://unsplash.com/@numericcitizen"
|
||||
, target "_blank"
|
||||
|
@ -1,11 +1,9 @@
|
||||
port module Search exposing (..)
|
||||
|
||||
import Browser exposing (Document)
|
||||
import Browser.Navigation exposing (Key)
|
||||
import Browser
|
||||
import Html as H exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick, onInput, onSubmit)
|
||||
import Json.Decode as D
|
||||
import Markdown
|
||||
|
||||
|
||||
@ -45,14 +43,21 @@ type alias SearchEntry =
|
||||
}
|
||||
|
||||
|
||||
type SearchState
|
||||
= Initial
|
||||
| Found (List SearchEntry)
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ searchInput : String
|
||||
, results : List SearchEntry
|
||||
, results : SearchState
|
||||
, searchVisible : Bool
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= SetSearch String
|
||||
| ToggleBar
|
||||
| SubmitSearch
|
||||
| GetSearchResults (List SearchEntry)
|
||||
|
||||
@ -64,7 +69,8 @@ type Msg
|
||||
init : Flags -> ( Model, Cmd Msg )
|
||||
init flags =
|
||||
( { searchInput = ""
|
||||
, results = []
|
||||
, results = Initial
|
||||
, searchVisible = False
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
@ -77,6 +83,11 @@ init flags =
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
ToggleBar ->
|
||||
( { model | searchVisible = not model.searchVisible }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
SetSearch str ->
|
||||
( { model | searchInput = str }
|
||||
, Cmd.none
|
||||
@ -86,7 +97,7 @@ update msg model =
|
||||
( model, doSearch model.searchInput )
|
||||
|
||||
GetSearchResults list ->
|
||||
( { model | results = List.take 8 list }, Cmd.none )
|
||||
( { model | results = Found <| List.take 20 list }, Cmd.none )
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
@ -100,56 +111,67 @@ subscriptions _ =
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
H.form
|
||||
[ class "form"
|
||||
, onSubmit SubmitSearch
|
||||
div
|
||||
[ class " inline-flex px-4 items-center hover:bg-amber-600 hover:bg-opacity-10 dark:hover:bg-stone-800"
|
||||
]
|
||||
[ div [ class "dropdown field is-active is-fullwidth has-addons" ]
|
||||
[ div [ class "control is-fullwidth" ]
|
||||
[ a
|
||||
[ href "#"
|
||||
, class "h-full w-full inline-flex items-center"
|
||||
, onClick ToggleBar
|
||||
]
|
||||
[ i [ class "fa fa-search" ] []
|
||||
]
|
||||
, div
|
||||
[ class "absolute px-2 mx-2 right-0 max-w-screen-md rounded top-12 w-full border-l border-r border-b bg-white h-12 dark:bg-stone-800 dark:border-stone-700"
|
||||
, classList [ ( "hidden", not model.searchVisible ) ]
|
||||
]
|
||||
[ H.form [ onSubmit SubmitSearch ]
|
||||
[ input
|
||||
[ class "input"
|
||||
, type_ "text"
|
||||
, placeholder "Search docs…"
|
||||
, onInput SetSearch
|
||||
[ type_ "text"
|
||||
, value model.searchInput
|
||||
, autofocus True
|
||||
, placeholder "Search …"
|
||||
, class "w-full block h-8 border-0 border-b border-stone-400 mt-2 focus:ring-0 focus:border-indigo-500 dark:bg-stone-800 dark:focus:border-cyan-400"
|
||||
, onInput SetSearch
|
||||
]
|
||||
[]
|
||||
]
|
||||
, div [ class "control" ]
|
||||
[ button
|
||||
[ class "button is-primary"
|
||||
, href "#"
|
||||
, onClick SubmitSearch
|
||||
]
|
||||
[ img [ src "/icons/search-white-20.svg" ] []
|
||||
]
|
||||
]
|
||||
, viewResults model.results
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
viewResults : List SearchEntry -> Html Msg
|
||||
viewResults entries =
|
||||
div
|
||||
[ classList
|
||||
[ ( "dropdown-menu", True )
|
||||
, ( "is-hidden", entries == [] )
|
||||
]
|
||||
]
|
||||
[ div [ class "dropdown-content" ]
|
||||
(List.intersperse
|
||||
(div [ class "dropdown-divider" ] [])
|
||||
(List.map viewResult entries)
|
||||
)
|
||||
]
|
||||
viewResults : SearchState -> Html Msg
|
||||
viewResults state =
|
||||
case state of
|
||||
Initial ->
|
||||
span [ class "hidden" ] []
|
||||
|
||||
Found [] ->
|
||||
div
|
||||
[ class "bg-white dark:bg-stone-800 mt-2 w-full"
|
||||
]
|
||||
[ div [ class "flex flex-row items-center h-14 justify-center text-xl" ]
|
||||
[ i [ class "fa fa-meh font-thin mr-2" ]
|
||||
[]
|
||||
, text "No results."
|
||||
]
|
||||
]
|
||||
|
||||
Found entries ->
|
||||
div
|
||||
[ class "bg-white dark:bg-stone-800 mt-2 w-screen sm:w-full h-screen-12 md:h-fit md:max-h-96 overflow-auto shadow-lg border-l border-r border-b dark:border-stone-700"
|
||||
]
|
||||
[ div [ class "px-2 pt-2 pb-1 flex flex-col divide-y dark:divide-stone-700 " ]
|
||||
(List.map viewResult entries)
|
||||
]
|
||||
|
||||
|
||||
viewResult : SearchEntry -> Html Msg
|
||||
viewResult result =
|
||||
div [ class "dropdown-item" ]
|
||||
div [ class "py-2 content" ]
|
||||
[ a
|
||||
[ class "is-size-5"
|
||||
[ class "text-lg font-semibold"
|
||||
, href result.ref
|
||||
]
|
||||
[ text result.doc.title
|
||||
@ -158,6 +180,16 @@ viewResult result =
|
||||
]
|
||||
|
||||
|
||||
textInput : String
|
||||
textInput =
|
||||
" placeholder-gray-400 w-full dark:text-slate-200 dark:bg-slate-800 dark:border-slate-500 border-gray-400 rounded " ++ formFocusRing
|
||||
|
||||
|
||||
formFocusRing : String
|
||||
formFocusRing =
|
||||
" focus:ring focus:ring-black focus:ring-opacity-50 focus:ring-offset-0 dark:focus:ring-slate-400 "
|
||||
|
||||
|
||||
|
||||
--- Ports
|
||||
|
||||
|
@ -1,6 +1,17 @@
|
||||
{
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"bulma": "^0.9.0"
|
||||
"@fontsource/montserrat": "^4.5.3",
|
||||
"@fontsource/source-code-pro": "^4.5.2",
|
||||
"@fontsource/spectral": "^4.5.1",
|
||||
"@fortawesome/fontawesome-free": "^5.15",
|
||||
"@tailwindcss/forms": "^0.4.0",
|
||||
"autoprefixer": "^10.4",
|
||||
"cssnano": "^5.0",
|
||||
"postcss": "^8.4.5",
|
||||
"postcss-cli": "^9.1.0",
|
||||
"postcss-import": "^14.0.2",
|
||||
"postcss-purgecss": "^2.0.3",
|
||||
"tailwindcss": "^3.0"
|
||||
}
|
||||
}
|
||||
|
10
website/postcss.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
//postcss.config.js
|
||||
|
||||
module.exports = (ctx) => ({
|
||||
plugins: [
|
||||
require('postcss-import'),
|
||||
require('tailwindcss'),
|
||||
require('autoprefixer'),
|
||||
require('cssnano'),
|
||||
]
|
||||
})
|
@ -3,6 +3,7 @@
|
||||
set -e
|
||||
|
||||
yarn install
|
||||
npx tailwindcss -i ./styles/input.css -o ./site/public/styles.css --config ./tailwind.config.js --postcss ./postcss.config.js
|
||||
elm make --output site/static/js/bundle.js --optimize elm/Main.elm
|
||||
cd site && zola build
|
||||
cd ..
|
11
website/scripts/run-styles.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mkdir -p ./site/public/files
|
||||
mkdir -p ./site/public/webfonts
|
||||
|
||||
echo "Copy webfonts…"
|
||||
cp node_modules/@fontsource/*/files/* ./site/public/files/
|
||||
cp node_modules/@fortawesome/fontawesome-free/webfonts/* ./site/public/webfonts/
|
||||
|
||||
echo "Running tailwind…"
|
||||
npx tailwindcss -i ./styles/input.css -o ./site/public/styles.css --config ./tailwind.config.js --postcss ./postcss.config.js "$1"
|
74
website/scripts/screenshot.sh
Executable file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Little tool to help with doing screenshots.
|
||||
#
|
||||
# Run: ./screenshot.sh output.png
|
||||
#
|
||||
# Then select a window. It will create a screenshot from that window,
|
||||
# cut (optionally) some pixels (removes the browser bar) and then
|
||||
# resizes it to some maximum width.
|
||||
|
||||
set -e
|
||||
|
||||
# input file
|
||||
file=/tmp/screenshot.png
|
||||
|
||||
# final output file
|
||||
out=/tmp/screenshot-out.png
|
||||
|
||||
# image dimension ratio w:h
|
||||
ratio=${RATIO:-"16:9"}
|
||||
# cut that much from the top to remove browser bar (my firefox settings)
|
||||
top_cut=${TOP_CUT:-85}
|
||||
# maximum width of final image
|
||||
maxw=${MAXW:-1200}
|
||||
# time to wait in secs
|
||||
waitsec=${WAIT_SEC:-3}
|
||||
|
||||
|
||||
#### Main ############
|
||||
work=/tmp/screenshot-work.png
|
||||
|
||||
debug() {
|
||||
(1>&2 echo "$@")
|
||||
}
|
||||
|
||||
scrot -s -c -d $waitsec "$file" 1>&2
|
||||
cp "$file" "$work"
|
||||
|
||||
|
||||
read -r w h < <(identify -verbose $file |\
|
||||
grep "Geometry:" | \
|
||||
cut -d':' -f2 | \
|
||||
cut -d'+' -f1 | \
|
||||
tr 'x' ' ' | xargs)
|
||||
debug "Original size: ${w}x${h}"
|
||||
|
||||
read nw nh < <(echo $ratio | tr ':' ' ')
|
||||
|
||||
# remove browser bar from top
|
||||
((h=$h - $top_cut))
|
||||
|
||||
# create height to match ratio
|
||||
((newH=($w * $nh) / $nw))
|
||||
|
||||
if [ $newH -gt $h ]; then
|
||||
debug "Cropping to $w x $h"
|
||||
debug "Cannot crop to ratio without reducing width"
|
||||
convert -crop ${w}x${h}+0+${top_cut} "$work" "$out"
|
||||
else
|
||||
debug "Cropping to $w x $h"
|
||||
convert -crop ${w}x${newH}+0+${top_cut} "$work" "$out"
|
||||
fi
|
||||
cp "$out" "$work"
|
||||
|
||||
debug "Resize to max width $maxw"
|
||||
convert -resize $maxw "$work" "$out"
|
||||
rm -f "$work" "$file"
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "$out"
|
||||
else
|
||||
mv "$out" "$1"
|
||||
echo "$1"
|
||||
fi
|
40
website/scripts/screenshot2.sh
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Uses the `screenshot.sh` script to create one screenshot per theme.
|
||||
#
|
||||
# First sets light theme and takes a screenshot, then sets dark theme
|
||||
# and calls screenshot.sh again
|
||||
#
|
||||
# Might need to fiddle with the xdotool command
|
||||
|
||||
|
||||
docspell_url=http://localhost:7880
|
||||
docspell_user=demo
|
||||
docspell_pass=test
|
||||
|
||||
screenshot="$(dirname $0)/screenshot.sh"
|
||||
|
||||
out_base="$1"
|
||||
|
||||
work_dir=$(mktemp -dt screenshot2-script.XXXXXX)
|
||||
export HOME=$work_dir
|
||||
export RATIO="16:9"
|
||||
export WAIT_SEC=4
|
||||
#export TOP_CUT=400
|
||||
|
||||
dsc write-default-config
|
||||
sed -i "s,http://localhost:7880,$docspell_url,g" $HOME/.config/dsc/config.toml
|
||||
|
||||
set_theme() {
|
||||
dsc login -u $docspell_user --password $docspell_pass 2>&1 > /dev/null
|
||||
local token=$(cat $HOME/.config/dsc/dsc-token.json | jq -r '.token')
|
||||
data=$(curl -sSL -H "X-Docspell-Auth: $token" $docspell_url/api/v1/sec/clientSettings/webClient | jq ".uiTheme=\"$1\"")
|
||||
|
||||
curl -sSL -H "X-Docspell-Auth: $token" -XPUT --data "$data" $docspell_url/api/v1/sec/clientSettings/user/webClient
|
||||
xdotool search --name "Mozilla Firefox" | xargs xdotool windowactivate && xdotool key F5
|
||||
}
|
||||
|
||||
set_theme "Light"
|
||||
$screenshot "${out_base}.png"
|
||||
set_theme "dark"
|
||||
$screenshot "${out_base}_dark.png"
|
@ -1,7 +1,8 @@
|
||||
let
|
||||
nixpkgs = builtins.fetchTarball {
|
||||
#url = "channel:nixos-21.05";
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/e6badb26fc0d238fda2432c45b7dd4e782eb8200.tar.gz";
|
||||
#url = "channel:nixos-21.11";
|
||||
#url = "https://github.com/NixOS/nixpkgs/archive/e6badb26fc0d238fda2432c45b7dd4e782eb8200.tar.gz";
|
||||
url = "https://github.com/NixOs/nixpkgs/archive/0f316e4d72daed659233817ffe52bf08e081b5de.tar.gz"; #21.11
|
||||
};
|
||||
pkgs = import nixpkgs { };
|
||||
in
|
||||
@ -11,6 +12,9 @@ with pkgs;
|
||||
buildInputs = [
|
||||
zola
|
||||
yarn
|
||||
sbt
|
||||
elmPackages.elm
|
||||
nodejs
|
||||
inotifyTools
|
||||
];
|
||||
}
|
||||
|
@ -11,7 +11,13 @@ default_language = "en"
|
||||
|
||||
[markdown]
|
||||
highlight_code = true
|
||||
highlight_theme = "gruvbox-dark"
|
||||
#light: ayu-light, OneHalfLight, base16-ocean-light
|
||||
highlight_theme = "css"
|
||||
|
||||
highlight_themes_css = [
|
||||
{ theme = "gruvbox-dark", filename = "syntax-dark.css" },
|
||||
{ theme = "base16-ocean-light", filename = "syntax-light.css" }
|
||||
]
|
||||
|
||||
[link_checker]
|
||||
skip_prefixes = [
|
||||
|
@ -0,0 +1,24 @@
|
||||
+++
|
||||
title = "Preproces Scans before upload"
|
||||
[extra]
|
||||
author = "@eresturo"
|
||||
authorLink = "https://github.com/eresturo"
|
||||
+++
|
||||
|
||||
# Preproces Scans before upload
|
||||
|
||||
This script scans from the ADF (Automatic Document Feeder),
|
||||
preprocesses it and uploads it to Docspell:
|
||||
[scanadf2docspell](https://github.com/eresturo/scanadf2docspell)
|
||||
|
||||
<!-- more -->
|
||||
<figure>
|
||||
<img src="https://github.com/eresturo/scanadf2docspell/raw/main/overview.png">
|
||||
</figure>
|
||||
|
||||
I don't know if this is helpful to other Docspell users, but feel free
|
||||
to link to it in the Docspell documentation.
|
||||
|
||||
Any suggestions or missing features?
|
||||
|
||||
Sheers eresturo
|
@ -0,0 +1,51 @@
|
||||
+++
|
||||
title = "Upload directly from the browser or email client"
|
||||
[extra]
|
||||
author = "gandy92"
|
||||
+++
|
||||
|
||||
# Uploading from browser or email client
|
||||
|
||||
An alternative approach came to mind to directly upload from a browser
|
||||
or email client that at least works on a Linux system. In case this is
|
||||
interesting for others, I'd like to share it here.
|
||||
|
||||
<!-- more -->
|
||||
1. Create and activate a source in your collective (in this example
|
||||
MYCOLL); note that path to the file upload (the one with
|
||||
`/api/v1/open/upload/item/`)
|
||||
2. Create a file `docspell-upload-MYCOLL` with the following content (replace `UPLOAD_PATH` with the actual path):
|
||||
```
|
||||
#!/bin/bash
|
||||
logger -t docspell_upload -- Docspell upload to MYCOLL: "$*" $(
|
||||
curl -s -XPOST -F file=@"$1" UPLOAD_PATH
|
||||
)
|
||||
```
|
||||
3. Make it executable: `chmod 755 docspell-upload-MYCOLL`
|
||||
4. Create a file named `docspell-MYCOLL.desktop` with the following
|
||||
content (note that you need the full path to
|
||||
`docspell-upload-MYCOLL`):
|
||||
|
||||
```
|
||||
[Desktop Entry]
|
||||
Exec=PATH_TO_docspell-upload-MYCOLL %F
|
||||
MimeType=application/pdf;application/x-zip;application/x-zip-compressed;application/zip
|
||||
Name=Docspell Upload (MYCOLL)
|
||||
NoDisplay=true
|
||||
Type=Application
|
||||
```
|
||||
5. Place the file `docspell-MYCOLL.desktop` in
|
||||
`$HOME/.local/share/applications/`
|
||||
6. Configure your browser or mail-reader actions for pdf and zip: They
|
||||
should always ask what to do rather than opening a link or
|
||||
attachment with the standard application or save it to disk by
|
||||
default. Actually, always opening a pdf in the browser is fine, if
|
||||
this allows to later save the viewed file.
|
||||
|
||||
Now, when clicking on a file link or attachment, the browser or email
|
||||
client should ask what to do. You then should be able to choose
|
||||
"Docspell Upload (MYCOLL)" from the list, which will upload the file
|
||||
to your collection.
|
||||
|
||||
If anything goes wrong, you can monitor the server response with the
|
||||
command `journalctl -f -t docspell_upload`
|
249
website/site/content/blog/2022-01-31_create_post.md
Normal file
@ -0,0 +1,249 @@
|
||||
+++
|
||||
title = "Create a new post"
|
||||
[extra]
|
||||
author = "eikek"
|
||||
+++
|
||||
|
||||
# Create a new post
|
||||
|
||||
Sharing ideas and tips is very much welcome, if you like you can
|
||||
create a small (or large) post here. You'll need `git` and potentially
|
||||
a `github` account to make this convenient.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
The contents of this website is maintained in the [<i class="fab fa-github ml-1"></i> git
|
||||
repository](https://github.com/eikek/docspell) in the `website/site`
|
||||
folder. It is build by the static site generator
|
||||
[zola](https://getzola.org) from a set of
|
||||
[markdown](https://www.markdownguide.org/basic-syntax) files.
|
||||
|
||||
It is not necessary to know how everything is connected, you only need
|
||||
to edit or create markdown files at some specific location. Here are
|
||||
some proposals how to add or edit pages and getting them published to
|
||||
docspell.org.
|
||||
|
||||
## Where to create the files
|
||||
|
||||
The contents of the published website is in the branch `current-docs`.
|
||||
You should base your changes on this branch.
|
||||
|
||||
All blog pages go into this directory: `website/site/content/blog/`.
|
||||
In this directory each post is a markdown file named by this pattern:
|
||||
|
||||
```
|
||||
<year>-<month>-<day>_title_with_underscores.md
|
||||
```
|
||||
|
||||
For example, this page here is named `2022-01-31_create_post.md`.
|
||||
|
||||
## Write on Github
|
||||
|
||||
A very convenient way is to edit and create posts directly on github
|
||||
in the browser. All pages contain a small `Edit` link at the bottom
|
||||
that takes you directly into edit model of the corresponding file on
|
||||
github.
|
||||
|
||||
To create a new file on github, you can use this link:
|
||||
|
||||
<https://github.com/eikek/docspell/new/current-docs/website/site/content/blog>
|
||||
|
||||
It will present a form that lets you create a new file with content.
|
||||
Once you commit this change, the project will be forked into your
|
||||
account and the change is applied to this new fork. Then you can
|
||||
create a pull request into this repository in order to publish it.
|
||||
|
||||
Plase see [below](#content) for how to start writing content.
|
||||
|
||||
## Writing locally
|
||||
|
||||
The preferred approach is to explicitely fork the repository and clone
|
||||
it to your machine to do the modification. The big advantage is, that
|
||||
you can look at the results while writing.
|
||||
|
||||
If you want to see a live view of the page while editing, some tools
|
||||
are required. The easiest way to get these is to install
|
||||
[nix](https://nixos.org/) and run `nix-shell website/shell.nix` to get
|
||||
an environment with all these tools installed. Otherwise install the
|
||||
programs mentioned in `website/shell.nix`, which are:
|
||||
[yarn](https://yarnpkg.com/), [zola](https://getzola.org),
|
||||
[elm](https://elm-lang.org) and [sbt](https://scala-sbt.org).
|
||||
|
||||
Then clone the sources to your machine and build the complete site
|
||||
once, so that all assets and required stuff is present:
|
||||
|
||||
```
|
||||
sbt website/zolaBuildTest
|
||||
```
|
||||
|
||||
Now you can use zola to start the page and watch for changes. The
|
||||
changes are visible immediately without reloading the page in the
|
||||
browser.
|
||||
|
||||
```
|
||||
cd website/site && zola serve
|
||||
```
|
||||
|
||||
This starts a web server on some port (usually `1111`); point your
|
||||
browser to it and navigate to your new page. Whenever changes are
|
||||
saved to the markdown file, the page refreshes automatically.
|
||||
|
||||
If styling is changed (in the css files or also sometimes when adding
|
||||
new classes to HTML elements), a rebuild of the site css is necessary.
|
||||
This can be done by running `scripts/run-styles.sh`. Via
|
||||
`scripts/run-styles.sh --watch` it is possible to watch for these
|
||||
changes as well. But it shouldn't be necessary to do large edits to
|
||||
the css.
|
||||
|
||||
# Content
|
||||
|
||||
## Front matter
|
||||
|
||||
The very beginning of such a markdown file contains some metadata.
|
||||
Start each page with these lines:
|
||||
|
||||
```markdown
|
||||
+++
|
||||
title = "Title of the post"
|
||||
[extra]
|
||||
author = "<your name>"
|
||||
authorLink = "https://some-url"
|
||||
+++
|
||||
|
||||
# First heading…
|
||||
```
|
||||
|
||||
The front matter is the first part enclosed in `+++`. See
|
||||
[zola](https://www.getzola.org/documentation/content/page/)
|
||||
documentation for more details.
|
||||
|
||||
The `author` and `authorLink` setting is optional. You can leave out
|
||||
the complete `[extra]` section. If `authorLink`is defined, the author
|
||||
is rendered as a link to that URL. If `author` is missing, it defaults
|
||||
to "_Unknown_".
|
||||
|
||||
## Elements
|
||||
|
||||
The content is styled automatically and the post is added to the list
|
||||
on the main blog page. Additional to the standard markdown formatting,
|
||||
there are some more usefull elements.
|
||||
|
||||
### Linking
|
||||
|
||||
If you want to link to an internal page, use markdown links where the
|
||||
path is formatted like this:
|
||||
|
||||
```markdown
|
||||
[link title](@/path/to/markdown_file.md)
|
||||
```
|
||||
|
||||
Using the `@/path` style, zola generates the correct final link (and
|
||||
checks for dead links).
|
||||
|
||||
### Info and warning boxes
|
||||
|
||||
There are small templates available to format a basic info or warning
|
||||
box message.
|
||||
|
||||
```markdown
|
||||
{%/* infobubble(title="My Title") */%}
|
||||
Your content here ….
|
||||
{%/* end */%}
|
||||
```
|
||||
|
||||
For a box more styled like a warning, replace `info` with `warning`.
|
||||
|
||||
```markdown
|
||||
{%/* warningbubble(title="My Title") */%}
|
||||
Your content here ….
|
||||
{%/* end */%}
|
||||
```
|
||||
|
||||
This will render into:
|
||||
|
||||
{% infobubble(title="My Title") %}
|
||||
Your content here ….
|
||||
{% end %}
|
||||
|
||||
{% warningbubble(title="My Title") %}
|
||||
Your content here ….
|
||||
{% end %}
|
||||
|
||||
### Summary
|
||||
|
||||
In order to get a decent summary in the list of posts, you need to set
|
||||
a marker in your file. Place a line containing only
|
||||
|
||||
```
|
||||
<!-- more -->
|
||||
```
|
||||
|
||||
into your file and everything before it will be rendered as a summary
|
||||
on the blog listing.
|
||||
|
||||
|
||||
### Buttons
|
||||
|
||||
Styled buttons can be created using HTML inside the markdown file:
|
||||
|
||||
```markdown
|
||||
<a class="no-default button1" href="#">Click!</a>
|
||||
```
|
||||
|
||||
Turns into:
|
||||
|
||||
<a class="no-default button1" href="#">Click!</a>
|
||||
|
||||
|
||||
### Images
|
||||
|
||||
In image to appear on the whole page, use HTML with a `figure` tag:
|
||||
|
||||
```
|
||||
<figure>
|
||||
<img src="image-url.jpg">
|
||||
</figure>
|
||||
```
|
||||
|
||||
<figure>
|
||||
<img src="/img/jesse-gardner-EqdpXeemf58-unsplash.jpg" >
|
||||
</figure>
|
||||
|
||||
The site has a light and dark mode and sometimes it's nice to provide
|
||||
images for both variants. You can use HTML for this and a specific
|
||||
class per theme:
|
||||
|
||||
```html
|
||||
<figure class="dark-block">
|
||||
<img src="dark-image.jpg" >
|
||||
</figure>
|
||||
<figure class="light-block">
|
||||
<img src="light-image.jpg" >
|
||||
</figure>
|
||||
```
|
||||
|
||||
See the effect when changing the theme:
|
||||
|
||||
<figure class="dark-block">
|
||||
<img src="/img/tersius-van-rhyn-xcQWMPm9fG8-unsplash.jpg" >
|
||||
</figure>
|
||||
<figure class="light-block">
|
||||
<img src="/img/cassie-boca-x-tbVqkfQCU-unsplash.jpg" >
|
||||
</figure>
|
||||
|
||||
This can be done via a template if the file is next to the markdown
|
||||
file in the same directory:
|
||||
|
||||
```markdown
|
||||
{{/* figure2(light="light-image.jpg", dark="dark-image.jpg") */}}
|
||||
```
|
||||
|
||||
<div class="text-sm text-right opacity-80">
|
||||
Pictures are from <a href="https://unsplash.com" target="_blank">Unsplash</a>.
|
||||
</div>
|
||||
|
||||
# Publish
|
||||
|
||||
Open a pull request against the `current-docs` branch. When the pull
|
||||
request is merged, the publishing process starts automatically and the
|
||||
content is available minutes after.
|
15
website/site/content/blog/_index.md
Normal file
@ -0,0 +1,15 @@
|
||||
+++
|
||||
title = "Main"
|
||||
description = "Random collection of stuff around Docspell"
|
||||
template = "blog.html"
|
||||
page_template = "blog_page.html"
|
||||
sort_by = "date"
|
||||
insert_anchor_links = "right"
|
||||
+++
|
||||
|
||||
# Blog
|
||||
|
||||
This is a place to collect random tips and knowledge around Docspell.
|
||||
This is organized as a log, where entries can be added by whoever
|
||||
likes to share something. Check [this
|
||||
page](@/blog/2022-01-31_create_post.md) for creating content here.
|
@ -1,3 +0,0 @@
|
||||
+++
|
||||
redirect_to = "/docs"
|
||||
+++
|
@ -1,9 +1,150 @@
|
||||
+++
|
||||
title = "Overview"
|
||||
template = "overview.html"
|
||||
title = "Documentation"
|
||||
template = "docs.html"
|
||||
page_template = "docs.html"
|
||||
insert_anchor_links = "right"
|
||||
+++
|
||||
|
||||
# Note
|
||||
|
||||
This content is not rendered. Everything is in the template.
|
||||
# Introduction
|
||||
|
||||
Docspell aims to be a simple yet effective document organizer that
|
||||
makes stowing documents away very quick and finding them later
|
||||
reliable (and also fast). It is a bit opinionated and more targeted
|
||||
for home use and small/medium organizations.
|
||||
|
||||
In contrast to many DMS, the main focus is not so much to provide all
|
||||
kinds of features to manually create organizational structures, like
|
||||
folder hierarchies, where you place the documents yourself. The
|
||||
approach is to leave it as a big pile of documents, but extract and
|
||||
attach metadata from each document. These are mainly properties that
|
||||
emerge from the document itself. The reason is that this is possible
|
||||
to automate. This makes it very simple to *add* documents, because
|
||||
there is no time spent to think about where to put it. And it is
|
||||
possible to apply different structures on top later, like show first
|
||||
all documents of a specific correspondent, then all with tag
|
||||
'invoice', etc. If these properties are attached to all documents, it
|
||||
is really easy to find a document. It even can be combined with
|
||||
fulltext search for the, hopefully rare, desperate cases.
|
||||
|
||||
Of course, it is also possible to add custom properties and arbitrary
|
||||
tags.
|
||||
|
||||
Docspell analyzes the text to find metadata automatically. It can
|
||||
learn from existing data and can apply
|
||||
[NLP](https://en.wikipedia.org/wiki/Natural_language_processing)
|
||||
techniques to support this. This metadata must be maintained manually
|
||||
in the application. Docspell looks for candidates for:
|
||||
|
||||
- Correspondents
|
||||
- Concerned person or things
|
||||
- A date and due date
|
||||
- Tags
|
||||
|
||||
For tags, it sets all that it thinks do apply. For the others, it will
|
||||
propose a few candidates and sets the most likely one to your item.
|
||||
|
||||
This might be wrong, so it is recommended to curate the results.
|
||||
However, very often the correct one is either set or within the
|
||||
proposals where you fix it by a single click.
|
||||
|
||||
Besides these properties, there are more metadata you can use to
|
||||
organize your files, for example custom fields, folders and notes.
|
||||
|
||||
Docspell is also for programmers. Everything is available via a REST
|
||||
or HTTP api and can be easily used within your own scripts and tools,
|
||||
for example using `curl`. There are also features for "advanced use"
|
||||
and many configuration options.
|
||||
|
||||
|
||||
# Components
|
||||
|
||||
Docspell consists of multiple components that run in separate
|
||||
processes:
|
||||
|
||||
- REST server
|
||||
- JOEX, short for *job executor*
|
||||
- Fulltext Search Index (optional, currently Apache SOLR)
|
||||
|
||||
The REST server provides the Api and the web application. The web
|
||||
application is a
|
||||
[SPA](https://en.wikipedia.org/wiki/Single-page_application) written
|
||||
in [Elm](https://elm-lang.org) and is a client to the REST api. All
|
||||
features are available via a http/rest api.
|
||||
|
||||
The *joex* is the component that does the “heavy work”, executing
|
||||
long-running tasks, like processing files or importing your mails
|
||||
periodically. While the joex component also exposes a small REST api
|
||||
for controlling it, the main user interface is all inside the rest
|
||||
server api.
|
||||
|
||||
The rest server and the job executor can be started multiple times in
|
||||
order to scale out. It must be ensured, that all connect to the same
|
||||
database. And it is also recommended (though not strictly required),
|
||||
that all components can reach each other.
|
||||
|
||||
The fulltext search index is another separate component, where
|
||||
currently only [SOLR](https://solr.apache.org) is supported.
|
||||
Fulltext search is optional, so the SOLR component is not required if
|
||||
docspell is run without fulltext search support.
|
||||
|
||||
|
||||
# Terms
|
||||
|
||||
In order to better understand the following pages, some terms are
|
||||
explained.
|
||||
|
||||
## Item
|
||||
|
||||
An *item* is roughly your document, only that an item may span
|
||||
multiple files, which are called *attachments*. An item has *meta
|
||||
data* associated:
|
||||
|
||||
- a *correspondent*: the other side of the communication. It can be
|
||||
an organization or a person.
|
||||
- a *concerning person* or *equipment*: a person or thing that
|
||||
this item is about. Maybe it is an insurance contract about your
|
||||
car.
|
||||
- *tag*: an item can be tagged with one or more tags (or labels). A
|
||||
tag can have a *category*. This is intended for grouping tags, for
|
||||
example a category `doctype` could be used to group tags like
|
||||
`bill`, `contract`, `receipt` etc. Usually an item is not tagged
|
||||
with more than one tag of a category.
|
||||
- a *folder*: a folder is similiar to a tag, but an item can only be
|
||||
in exactly one folder (or none). Furthermore folders allow to
|
||||
associate users, so that items are only visible to the users who are
|
||||
members of a folder.
|
||||
- an *item date*: this is the date of the document – if this is not
|
||||
set, the created date of the item is used.
|
||||
- a *due date*: an optional date indicating that something has to be
|
||||
done (e.g. paying a bill, submitting it) about this item until this
|
||||
date
|
||||
- a *direction*: one of "incoming" or "outgoing"
|
||||
- a *name*: some item name, defaults to the file name of the
|
||||
attachments
|
||||
- some *notes*: arbitrary descriptive text. You can use markdown
|
||||
here, which is properly formatted in the web application.
|
||||
|
||||
## Collective
|
||||
|
||||
The users of the application are part of a *collective*. A
|
||||
*collective* is a group of users that share access to the same
|
||||
items. The account name is therefore comprised of a *collective name*
|
||||
and a *user name*.
|
||||
|
||||
All users of a collective are equal; they have same permissions to
|
||||
access all items. The items don't belong to a user, but to the
|
||||
collective.
|
||||
|
||||
That means, to identify yourself when signing in, you have to give the
|
||||
collective name and your user name. By default it is separated by a
|
||||
slash `/`, for example `smith/john`. If your user name is the same as
|
||||
the collective name, you can omit one; so `smith/smith` can be
|
||||
abbreviated to just `smith`.
|
||||
|
||||
By default, all users can see all items of their collective. A
|
||||
*folder* can be used to implement other visibilities: Every user can
|
||||
create a folder and associate members. It is possible to put items in
|
||||
these folders and docspell shows only items that are either in no
|
||||
specific folder or in a folder where the current user is owner or
|
||||
member.
|
||||
|
@ -3,9 +3,6 @@ title = "Api"
|
||||
description = "Contains documentation about the REST API."
|
||||
weight = 70
|
||||
insert_anchor_links = "right"
|
||||
template = "pages.html"
|
||||
template = "docs.html"
|
||||
sort_by = "weight"
|
||||
redirect_to = "docs/api/intro"
|
||||
+++
|
||||
|
||||
No Content
|
||||
|
@ -3,10 +3,10 @@ title = "Api Introduction"
|
||||
description = "Api Basics"
|
||||
weight = 10
|
||||
insert_anchor_links = "right"
|
||||
[extra]
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# Api
|
||||
|
||||
Docspell is designed as a REST server that uses JSON to exchange
|
||||
data. The REST api can be used to integrate docspell into your
|
||||
workflow.
|
||||
|
@ -3,10 +3,10 @@ title = "Upload Request"
|
||||
description = "Describes the upload request"
|
||||
weight = 20
|
||||
insert_anchor_links = "right"
|
||||
[extra]
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# Upload Request
|
||||
|
||||
Uploads of files to docspell are always processed the same way, no
|
||||
matter if coming from a source, the integration endpoint or from the
|
||||
webapp.
|
||||
|
@ -3,10 +3,11 @@ title = "Configuration"
|
||||
insert_anchor_links = "right"
|
||||
description = "Describes the configuration file and shows all default settings."
|
||||
weight = 40
|
||||
[extra]
|
||||
mktoc = true
|
||||
template = "docs.html"
|
||||
+++
|
||||
|
||||
# Configuration
|
||||
|
||||
Docspell's executables (restserver and joex) can take one argument – a
|
||||
configuration file. If that is not given, the defaults are used,
|
||||
overriden by environment variables. A config file overrides default
|
||||
|
@ -4,11 +4,14 @@ description = "Contains some ADRs, which are internal notes on decisions made."
|
||||
weight = 300
|
||||
sort_by = "weight"
|
||||
insert_anchor_links = "right"
|
||||
template = "pages.html"
|
||||
template = "docs.html"
|
||||
page_template = "docs.html"
|
||||
[extra]
|
||||
mktoc = true
|
||||
page_list = true
|
||||
+++
|
||||
|
||||
# ADR
|
||||
|
||||
This contains a list of ADRs, most of them are from very early. It
|
||||
often just contains notes that could go nowhere else, but still should
|
||||
be captured.
|
||||
|
@ -3,6 +3,7 @@ title = "Building Docspell"
|
||||
weight = 0
|
||||
+++
|
||||
|
||||
# Building
|
||||
|
||||
You must install [sbt](https://scala-sbt.org),
|
||||
[nodejs](https://www.npmjs.com/get-npm) (for the `npm` command) and
|
||||
|
@ -3,7 +3,9 @@ title = "Tips & Setup"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
# Starting Servers with `reStart`
|
||||
# Setup / Tips
|
||||
|
||||
## Starting Servers with `reStart`
|
||||
|
||||
When developing, it's very convenient to use the [revolver sbt
|
||||
plugin](https://github.com/spray/sbt-revolver). Start the sbt console
|
||||
@ -29,7 +31,7 @@ sbt:docspell-root> reStart
|
||||
```
|
||||
|
||||
|
||||
# Custom config file
|
||||
## Custom config file
|
||||
|
||||
The sbt build is setup such that a file `dev.conf` in the directory
|
||||
`local` (at root of the source tree) is picked up as config file, if
|
||||
|
@ -3,6 +3,7 @@ title = "Translating Web-UI"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
# UI Translation
|
||||
|
||||
Help with translating the web-ui is greatly appreciated. I can only
|
||||
provide translations for English and German, and these may be wrong -
|
||||
@ -16,7 +17,7 @@ messages.
|
||||
|
||||
This guide assumes no knowledge about Elm at all.
|
||||
|
||||
# TL;DR
|
||||
## TL;DR
|
||||
|
||||
If you are already familiar with Elm, here is the TL;DR:
|
||||
|
||||
@ -92,7 +93,7 @@ sbt:docspell-root> make
|
||||
This will take a while, you need to wait until this is finished.
|
||||
|
||||
|
||||
## Start the application
|
||||
### Start the application
|
||||
|
||||
If sbt is not started, start sbt from within the source root. Also
|
||||
export the `DOCSPELL_ENV` variable *before* starting sbt:
|
||||
|
@ -3,8 +3,8 @@ title = "FAQ"
|
||||
weight = 100
|
||||
description = "Frequently asked questions."
|
||||
insert_anchor_links = "right"
|
||||
template = "docs.html"
|
||||
[extra]
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# FAQ
|
||||
|
@ -1,8 +1,9 @@
|
||||
+++
|
||||
title = "Features and Limitations"
|
||||
weight = 10
|
||||
weight = 9
|
||||
insert_anchor_links = "right"
|
||||
description = "A list of features and limitations."
|
||||
template = "docs.html"
|
||||
+++
|
||||
|
||||
# Features
|
||||
@ -20,7 +21,7 @@ description = "A list of features and limitations."
|
||||
- A powerful [query language](@/docs/query/_index.md) to find
|
||||
documents
|
||||
- use [bookmarks](@/docs/webapp/bookmarks.md) to save more complex queries
|
||||
- customizable [dashboads](@/docs/webapp/dashboards.md) as the main page
|
||||
- customizable [dashboards](@/docs/webapp/dashboards.md) as the main page
|
||||
- Non-destructive: all your uploaded files are never modified and can
|
||||
always be downloaded untouched
|
||||
- Organize files using tags, folders, [Custom
|
||||
@ -80,8 +81,6 @@ description = "A list of features and limitations."
|
||||
files, watch folders and many more!
|
||||
- [Android App](@/docs/tools/android.md) to quickly upload files
|
||||
from your android devices
|
||||
- [Firefox plugin](@/docs/tools/browserext.md): right click on a
|
||||
link and send the file to docspell
|
||||
- [SMTP Gateway](@/docs/tools/smtpgateway.md): Setup a SMTP server
|
||||
that delivers mails directly to docspell.
|
||||
- License: AGPLv3
|
||||
|
@ -1,12 +1,15 @@
|
||||
+++
|
||||
title = "Feed Data into Docspell"
|
||||
weight = 5
|
||||
weight = 8
|
||||
description = "Shows several ways for getting data into Docspell."
|
||||
insert_anchor_links = "right"
|
||||
template = "docs.html"
|
||||
[extra]
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# Documents → Docspell
|
||||
|
||||
One of the main goals is to stow documents away quickly.
|
||||
|
||||
Docspell makes no assumptions about where your documents are. It
|
||||
@ -20,19 +23,19 @@ So the idea is to have most flexibility – that is, it is up to you how
|
||||
documents arrive. Of course, there is something prepared:
|
||||
|
||||
|
||||
# Upload in Webapp
|
||||
## Upload in Webapp
|
||||
|
||||
This is the simplest way, but also the least flexible. You can just
|
||||
login and go to the upload page to submit files.
|
||||
|
||||
|
||||
{{ figure(file="web-upload.png") }}
|
||||
{{ figure2(light="web-upload.png", dark="web-upload_dark.png") }}
|
||||
|
||||
This requires to login at the webapp. Since this is complicated from
|
||||
other applications, you can create custom hard-to-guess endpoints to
|
||||
use with the following options.
|
||||
|
||||
# Scanners / Watch Directories
|
||||
## Scanners / Watch Directories
|
||||
|
||||
If you have a (document) scanner (or think about getting one), it can
|
||||
usually be configured to place scanned documents as image or PDF files
|
||||
@ -54,10 +57,10 @@ your scanner is connected to your computer. This can create nice pdf
|
||||
files from scanners with ADF, applying corrections and sending them to
|
||||
docspell.
|
||||
|
||||
{{ buttonright(classes="is-primary ", href="/docs/tools/cli#watch-a-directory", text="More") }}
|
||||
{{ buttonright(href="/docs/tools/cli#watch-a-directory", text="More") }}
|
||||
|
||||
|
||||
# Android
|
||||
## Android
|
||||
|
||||
There is an [android
|
||||
client](https://github.com/docspell/android-client) provided that lets
|
||||
@ -71,42 +74,40 @@ into the Share-With menu and uploads the file to Docspell.
|
||||
This is especially useful to quickly upload small things like shopping
|
||||
receipts.
|
||||
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-one-third">
|
||||
<img src="/docs/tools/screenshot-share.jpg">
|
||||
</div>
|
||||
<div class="column is-one-third">
|
||||
<img src="/docs/tools/screenshot-uploading.jpg">
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns is-vcentered is-centered">
|
||||
<div class="column is-one-third">
|
||||
<div class="grid grid-cols-2 gap-8 divide-x ">
|
||||
<div class="flex items-center justify-center">
|
||||
<a href="https://f-droid.org/packages/org.docspell.docspellshare">
|
||||
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||
alt="Get it on F-Droid"/>
|
||||
alt="Get it on F-Droid"
|
||||
class="w-56"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="column is-one-third">
|
||||
Download the APK from <a href="https://github.com/docspell/android-client/releases/latest">here</a>
|
||||
<div class="flex items-center justify-center text-xl">
|
||||
<i class="fa fa-download mr-2"></i>
|
||||
<span>
|
||||
<a href="https://github.com/docspell/android-client/releases/latest">Download the APK</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{ buttonright(classes="is-primary ", href="/docs/tools/android", text="More") }}
|
||||
{{ buttonright(href="/docs/tools/android", text="More") }}
|
||||
|
||||
|
||||
# Poll E-Mails
|
||||
## Poll E-Mails
|
||||
|
||||
Your mailbox can be polled periodically to import mails. For example,
|
||||
create a dedicated folder in your e-mail client and move mails in
|
||||
there that you want to push to Docspell. You can then define a
|
||||
recurring job, that looks into this folders and imports the mails.
|
||||
|
||||
{{ figure(file="scanmailbox.png") }}
|
||||
{{ figure2(light="scanmailbox.png", dark="scanmailbox_dark.png") }}
|
||||
|
||||
{{ buttonright(classes="is-primary ", href="/docs/webapp/scanmailbox", text="More") }}
|
||||
{{ buttonright(href="/docs/webapp/scanmailbox", text="More") }}
|
||||
|
||||
|
||||
# E-Mail Server
|
||||
## E-Mail Server
|
||||
|
||||
This is a little more involved, but can be quite nice. A SMTP server
|
||||
can be setup that simply uploads incoming mails to Docspell (using
|
||||
@ -120,29 +121,18 @@ part in Docspell to upload the files to the correct account.
|
||||
There is a docker container prepared to get started. Click below to
|
||||
read more.
|
||||
|
||||
{{ buttonright(classes="is-primary ", href="/docs/tools/smtpgateway", text="More") }}
|
||||
{{ buttonright(href="/docs/tools/smtpgateway", text="More") }}
|
||||
|
||||
|
||||
# Command-Line
|
||||
## Command-Line
|
||||
|
||||
I like to use the command line, and so there is a cli that can be used
|
||||
for some tasks, for example uploading files. Below is a quick demo, it
|
||||
supports many more options, see the link below for details.
|
||||
|
||||
<div class="columns is-centered is-full-width">
|
||||
<div class="column">
|
||||
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
||||
</div>
|
||||
</div>
|
||||
<figure>
|
||||
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
||||
</figure>
|
||||
|
||||
|
||||
{{ buttonright(classes="is-primary ", href="/docs/tools/cli", text="More") }}
|
||||
|
||||
|
||||
# Browser Extension
|
||||
|
||||
For Firefox, there is a browser extension that creates a context-menu
|
||||
entry if you right-click on a link. It then downloads the file to your
|
||||
disk and uploads it to Docspell.
|
||||
|
||||
{{ buttonright(classes="is-primary ", href="/docs/tools/browserext", text="More") }}
|
||||
{{ buttonright(href="/docs/tools/cli", text="More") }}
|
||||
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 177 KiB |
BIN
website/site/content/docs/feed/scanmailbox_dark.png
Normal file
After Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 190 KiB |
BIN
website/site/content/docs/feed/web-upload_dark.png
Normal file
After Width: | Height: | Size: 188 KiB |
@ -1,9 +1,10 @@
|
||||
+++
|
||||
title = "Installation and Deployment"
|
||||
title = "Installation"
|
||||
description = "There are multiple ways to install Docspell. This section contains detailed instructions."
|
||||
weight = 30
|
||||
weight = 5
|
||||
sort_by = "weight"
|
||||
insert_anchor_links = "right"
|
||||
template = "pages.html"
|
||||
template = "docs.html"
|
||||
page_template = "docs.html"
|
||||
redirect_to = "/docs/install/quickstart"
|
||||
+++
|
||||
|
@ -3,7 +3,7 @@ title = "Docker"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
## Docker Images
|
||||
# Docker Images
|
||||
|
||||
The docker images are at
|
||||
[hub.docker.com](https://hub.docker.com/u/docspell). The `latest` tag
|
||||
@ -29,7 +29,7 @@ release page. The images contain all the necessary
|
||||
is used to watch a directory for uploading files. This runs the `dsc
|
||||
watch` command.
|
||||
|
||||
### Examples
|
||||
## Examples
|
||||
|
||||
These examples use `docker run` to start the restserver and
|
||||
jobexecutor. Both must be connected to the same database. For this
|
||||
@ -127,7 +127,7 @@ fulltext search. For a more sophisticated docker setup, use
|
||||
appropriate tools, for example `docker-compose` which is explained
|
||||
below.
|
||||
|
||||
## Docker Compose
|
||||
# Docker Compose
|
||||
|
||||
There is a [docker-compose](https://docs.docker.com/compose/) setup
|
||||
available in the `/docker/docker-compose` folder. This setup is
|
||||
@ -135,8 +135,8 @@ similiar to the example above, but adding fulltext search and a
|
||||
PostgreSQL database by using just one command. It's only a few steps
|
||||
to get started.
|
||||
|
||||
### Start Docspell
|
||||
#### 1. Get the docker-compose files
|
||||
## Start Docspell
|
||||
### 1. Get the docker-compose files
|
||||
|
||||
There are two options. You can clone the whole repository:
|
||||
|
||||
@ -159,7 +159,7 @@ You can choose any directory instead of
|
||||
make the rest of the guide work for both ways of obtaining the
|
||||
docker-compose file.
|
||||
|
||||
#### 2. Run `docker-compose up`
|
||||
### 2. Run `docker-compose up`
|
||||
|
||||
Change into the new `docker-compose` directory, for example:
|
||||
|
||||
@ -210,7 +210,7 @@ command:
|
||||
to the service definition (or add it to an existing `command:`
|
||||
section).
|
||||
|
||||
### Override this setup
|
||||
## Override this setup
|
||||
|
||||
If you want to change this setup, you can simply use your own compose
|
||||
file or add a `docker-compose.override.yml` that allows to amend
|
||||
@ -251,7 +251,7 @@ volumes:
|
||||
```
|
||||
|
||||
|
||||
### Upgrading
|
||||
## Upgrading
|
||||
|
||||
Since [downgrading](@/docs/install/downgrading.md) is not supported,
|
||||
it is recommended to backup your database before upgrading. Should
|
||||
@ -267,7 +267,7 @@ $ docker-compose pull
|
||||
$ docker-compose up --force-recreate --build -d
|
||||
```
|
||||
|
||||
### Backups
|
||||
## Backups
|
||||
|
||||
When running the docker compose setup, you can use the following to
|
||||
backup the database.
|
||||
|
@ -3,7 +3,9 @@ title = "Downgrading"
|
||||
weight = 37
|
||||
+++
|
||||
|
||||
{% infobubble(mode="info", title="⚠ Please note") %}
|
||||
# Downgrading
|
||||
|
||||
{% warningbubble(title="Note") %}
|
||||
Downgrading is currently not supported!
|
||||
|
||||
It is not safe to install a previous version, because the database
|
||||
|
@ -3,24 +3,23 @@ title = "Download & Run"
|
||||
weight = 22
|
||||
+++
|
||||
|
||||
# Download and Run
|
||||
|
||||
You can install via zip or deb archives. Please see the
|
||||
[prerequisites](@/docs/install/prereq.md) first.
|
||||
|
||||
## Using zip files
|
||||
|
||||
You need to download the two files:
|
||||
|
||||
- [docspell-restserver-{{version()}}.zip](https://github.com/eikek/docspell/releases/download/v{{version()}}/docspell-restserver-{{version()}}.zip)
|
||||
- [docspell-joex-{{version()}}.zip](https://github.com/eikek/docspell/releases/download/v{{version()}}/docspell-joex-{{version()}}.zip)
|
||||
|
||||
|
||||
1. Unzip both files:
|
||||
1. Download the two files:
|
||||
- <a href="https://github.com/eikek/docspell/releases/download/v{{version()}}/docspell-restserver-{{version()}}.zip">docspell-restserver-{{version()}}.zip</a>
|
||||
- <a href="https://github.com/eikek/docspell/releases/download/v{{version()}}/docspell-joex-{{version()}}.zip">docspell-joex-{{version()}}.zip</a>
|
||||
2. Unzip both files:
|
||||
``` bash
|
||||
$ unzip docspell-*.zip
|
||||
```
|
||||
2. Open two terminal windows and navigate to the the directory
|
||||
3. Open two terminal windows and navigate to the the directory
|
||||
containing the zip files.
|
||||
3. Start both components executing:
|
||||
4. Start both components executing:
|
||||
``` bash
|
||||
$ ./docspell-restserver*/bin/docspell-restserver
|
||||
```
|
||||
@ -29,8 +28,8 @@ You need to download the two files:
|
||||
$ ./docspell-joex*/bin/docspell-joex
|
||||
```
|
||||
in the other.
|
||||
4. Point your browser to: <http://localhost:7880/app>
|
||||
5. Register a new account, sign in and try it.
|
||||
5. Point your browser to: <http://localhost:7880/app>
|
||||
6. Register a new account, sign in and try it.
|
||||
|
||||
Note, that this setup doesn't include watching a directory nor
|
||||
fulltext search. Using zip/deb files requires to take care of the
|
||||
@ -64,7 +63,7 @@ extracted and installed manually somewhere in your `$PATH`. There are
|
||||
no deb files provided.
|
||||
|
||||
|
||||
## Running
|
||||
# Running
|
||||
|
||||
Run the start script (in the corresponding `bin/` directory when using
|
||||
the zip files):
|
||||
|
@ -3,6 +3,7 @@ title = "Nix / NixOS"
|
||||
weight = 24
|
||||
+++
|
||||
|
||||
# Nix
|
||||
|
||||
## Install via Nix
|
||||
|
||||
@ -73,7 +74,7 @@ back to the previous version.
|
||||
When using the provided nix setup, the `currentPkg` always points to
|
||||
the latest release. Thus it is enough to run `nix-build`.
|
||||
|
||||
## Docspell on NixOS {#nixos}
|
||||
# Docspell on NixOS {#nixos}
|
||||
|
||||
If you are running [NixOS](https://nixos.org), there is a module
|
||||
definition for installing Docspell as a service using systemd.
|
||||
@ -141,7 +142,7 @@ The modules files are only applicable to the newest version of
|
||||
Docspell. If you really need an older version, checkout the
|
||||
appropriate commit.
|
||||
|
||||
### NixOS Example
|
||||
## NixOS Example
|
||||
|
||||
This is a example system configuration that installs docspell with a
|
||||
postgres database. This snippet can be used to create a vm (using
|
||||
|
@ -3,6 +3,8 @@ title = "Prerequisites"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
# Prerequisites
|
||||
|
||||
The two components have one prerequisite in common: they both require
|
||||
Java to run. While this is the only requirement for the *REST server*,
|
||||
the *Joex* components requires some more external programs.
|
||||
@ -10,7 +12,7 @@ the *Joex* components requires some more external programs.
|
||||
The rest server and joex components are not required to "see" each
|
||||
other, though it is recommended.
|
||||
|
||||
# Java
|
||||
## Java
|
||||
|
||||
Very often, Java is already installed. You can check this by opening a
|
||||
terminal and typing `java -version`. Otherwise install Java using your
|
||||
@ -28,7 +30,7 @@ works on newer java versions. The provided docker images use JDK11.
|
||||
The next tools are only required on machines running the *Joex*
|
||||
component.
|
||||
|
||||
# External Programs for Joex
|
||||
## External Programs for Joex
|
||||
|
||||
- [Ghostscript](http://pages.cs.wisc.edu/~ghost/) (the `gs` command)
|
||||
is used to extract/convert PDF files into images that are then fed
|
||||
@ -57,7 +59,7 @@ The performance of `unoconv` can be improved by starting `unoconv -l`
|
||||
in a separate process. This runs a libreoffice/openoffice listener and
|
||||
therefore avoids starting one each time `unoconv` is called.
|
||||
|
||||
## Example Debian
|
||||
### Example Debian
|
||||
|
||||
On Debian this should install all joex requirements:
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
+++
|
||||
title = "Quickstart"
|
||||
title = "Getting started"
|
||||
weight = 0
|
||||
+++
|
||||
|
||||
# Getting started
|
||||
|
||||
To get started, here are some quick links:
|
||||
|
||||
- Using [docker and docker-compose](@/docs/install/docker.md). This
|
||||
@ -28,7 +30,7 @@ To get started, here are some quick links:
|
||||
thread](https://forums.unraid.net/topic/103425-docspell-hilfe/) in
|
||||
the German Unraid forum. Thanks for providing these!
|
||||
|
||||
Every [component](@/docs/intro/_index.md#components) (restserver,
|
||||
Every [component](@/docs/_index.md#components) (restserver,
|
||||
joex, dsc watch) can run on different machines and multiple times.
|
||||
Most of the time running all on one machine is sufficient and also for
|
||||
simplicity, the docker-compose setup reflects this variant.
|
||||
@ -39,7 +41,7 @@ file](@/docs/configure/_index.md). If this is not given, the default
|
||||
is used, which gets you started on a single machine, but it is very
|
||||
likely you want to change these to match your use-case/setup.
|
||||
|
||||
{% infobubble(mode="info", title="⚠ Please note") %}
|
||||
{% infobubble(title="Note") %}
|
||||
|
||||
Please have a look at the [configuration page](/docs/configure/) page,
|
||||
before making docspell publicly available. By default, everyone can
|
||||
|
@ -3,6 +3,8 @@ title = "Reverse Proxy"
|
||||
weight = 50
|
||||
+++
|
||||
|
||||
# Reverse Proxy
|
||||
|
||||
This contains examples for how to use docspell behind a reverse proxy.
|
||||
|
||||
For the examples below, assume the following:
|
||||
|
@ -1,8 +1,10 @@
|
||||
+++
|
||||
title = "Raspberry-Pi and Similiar"
|
||||
title = "Raspberry-Pi"
|
||||
weight = 40
|
||||
+++
|
||||
|
||||
# Raspberry Pi
|
||||
|
||||
Both components can run next to each other on a raspberry pi or
|
||||
similiar device.
|
||||
|
||||
|
@ -3,149 +3,8 @@ title = "Introduction"
|
||||
weight = 0
|
||||
description = "Gives a short introduction to the goals of docspell and an overview of the components involved."
|
||||
insert_anchor_links = "right"
|
||||
redirect_to = "/docs/"
|
||||
[extra]
|
||||
mktoc = true
|
||||
hidden = true
|
||||
+++
|
||||
|
||||
# Introduction
|
||||
|
||||
Docspell aims to be a simple yet effective document organizer that
|
||||
makes stowing documents away very quick and finding them later
|
||||
reliable (and also fast). It is a bit opinionated and more targeted
|
||||
for home use and small/medium organizations.
|
||||
|
||||
In contrast to many DMS, the main focus is not so much to provide all
|
||||
kinds of features to manually create organizational structures, like
|
||||
folder hierarchies, where you place the documents yourself. The
|
||||
approach is to leave it as a big pile of documents, but extract and
|
||||
attach metadata from each document. These are mainly properties that
|
||||
emerge from the document itself. The reason is that this is possible
|
||||
to automate. This makes it very simple to *add* documents, because
|
||||
there is no time spent to think about where to put it. And it is
|
||||
possible to apply different structures on top later, like show first
|
||||
all documents of a specific correspondent, then all with tag
|
||||
'invoice', etc. If these properties are attached to all documents, it
|
||||
is really easy to find a document. It even can be combined with
|
||||
fulltext search for the, hopefully rare, desperate cases.
|
||||
|
||||
Of course, it is also possible to add custom properties and arbitrary
|
||||
tags.
|
||||
|
||||
Docspell analyzes the text to find metadata automatically. It can
|
||||
learn from existing data and can apply
|
||||
[NLP](https://en.wikipedia.org/wiki/Natural_language_processing)
|
||||
techniques to support this. This metadata must be maintained manually
|
||||
in the application. Docspell looks for candidates for:
|
||||
|
||||
- Correspondents
|
||||
- Concerned person or things
|
||||
- A date and due date
|
||||
- Tags
|
||||
|
||||
For tags, it sets all that it thinks do apply. For the others, it will
|
||||
propose a few candidates and sets the most likely one to your item.
|
||||
|
||||
This might be wrong, so it is recommended to curate the results.
|
||||
However, very often the correct one is either set or within the
|
||||
proposals where you fix it by a single click.
|
||||
|
||||
Besides these properties, there are more metadata you can use to
|
||||
organize your files, for example custom fields, folders and notes.
|
||||
|
||||
Docspell is also for programmers. Everything is available via a REST
|
||||
or HTTP api and can be easily used within your own scripts and tools,
|
||||
for example using `curl`. There are also features for "advanced use"
|
||||
and many configuration options.
|
||||
|
||||
|
||||
# Components
|
||||
|
||||
Docspell consists of multiple components that run in separate
|
||||
processes:
|
||||
|
||||
- REST server
|
||||
- JOEX, short for *job executor*
|
||||
- Fulltext Search Index (optional, currently Apache SOLR)
|
||||
|
||||
The REST server provides the Api and the web application. The web
|
||||
application is a
|
||||
[SPA](https://en.wikipedia.org/wiki/Single-page_application) written
|
||||
in [Elm](https://elm-lang.org) and is a client to the REST api. All
|
||||
features are available via a http/rest api.
|
||||
|
||||
The *joex* is the component that does the “heavy work”, executing
|
||||
long-running tasks, like processing files or importing your mails
|
||||
periodically. While the joex component also exposes a small REST api
|
||||
for controlling it, the main user interface is all inside the rest
|
||||
server api.
|
||||
|
||||
The rest server and the job executor can be started multiple times in
|
||||
order to scale out. It must be ensured, that all connect to the same
|
||||
database. And it is also recommended (though not strictly required),
|
||||
that all components can reach each other.
|
||||
|
||||
The fulltext search index is another separate component, where
|
||||
currently only [SOLR](https://solr.apache.org) is supported.
|
||||
Fulltext search is optional, so the SOLR component is not required if
|
||||
docspell is run without fulltext search support.
|
||||
|
||||
|
||||
# Terms
|
||||
|
||||
In order to better understand the following pages, some terms are
|
||||
explained.
|
||||
|
||||
## Item
|
||||
|
||||
An *item* is roughly your document, only that an item may span
|
||||
multiple files, which are called *attachments*. An item has *meta
|
||||
data* associated:
|
||||
|
||||
- a *correspondent*: the other side of the communication. It can be
|
||||
an organization or a person.
|
||||
- a *concerning person* or *equipment*: a person or thing that
|
||||
this item is about. Maybe it is an insurance contract about your
|
||||
car.
|
||||
- *tag*: an item can be tagged with one or more tags (or labels). A
|
||||
tag can have a *category*. This is intended for grouping tags, for
|
||||
example a category `doctype` could be used to group tags like
|
||||
`bill`, `contract`, `receipt` etc. Usually an item is not tagged
|
||||
with more than one tag of a category.
|
||||
- a *folder*: a folder is similiar to a tag, but an item can only be
|
||||
in exactly one folder (or none). Furthermore folders allow to
|
||||
associate users, so that items are only visible to the users who are
|
||||
members of a folder.
|
||||
- an *item date*: this is the date of the document – if this is not
|
||||
set, the created date of the item is used.
|
||||
- a *due date*: an optional date indicating that something has to be
|
||||
done (e.g. paying a bill, submitting it) about this item until this
|
||||
date
|
||||
- a *direction*: one of "incoming" or "outgoing"
|
||||
- a *name*: some item name, defaults to the file name of the
|
||||
attachments
|
||||
- some *notes*: arbitrary descriptive text. You can use markdown
|
||||
here, which is properly formatted in the web application.
|
||||
|
||||
## Collective
|
||||
|
||||
The users of the application are part of a *collective*. A
|
||||
*collective* is a group of users that share access to the same
|
||||
items. The account name is therefore comprised of a *collective name*
|
||||
and a *user name*.
|
||||
|
||||
All users of a collective are equal; they have same permissions to
|
||||
access all items. The items don't belong to a user, but to the
|
||||
collective.
|
||||
|
||||
That means, to identify yourself when signing in, you have to give the
|
||||
collective name and your user name. By default it is separated by a
|
||||
slash `/`, for example `smith/john`. If your user name is the same as
|
||||
the collective name, you can omit one; so `smith/smith` can be
|
||||
abbreviated to just `smith`.
|
||||
|
||||
By default, all users can see all items of their collective. A
|
||||
*folder* can be used to implement other visibilities: Every user can
|
||||
create a folder and associate members. It is possible to put items in
|
||||
these folders and docspell shows only items that are either in no
|
||||
specific folder or in a folder where the current user is owner or
|
||||
member.
|
||||
|
@ -7,6 +7,8 @@ insert_anchor_links = "right"
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# File Processing
|
||||
|
||||
When uploading a file, it is only saved to the database together with
|
||||
the given meta information as a "job". The file is not visible in the
|
||||
ui yet. Then joex takes the next such job and starts processing it.
|
||||
@ -319,7 +321,7 @@ docspell.joex {
|
||||
}
|
||||
```
|
||||
|
||||
{% infobubble(mode="warning", title="Please note") %}
|
||||
{% warningbubble(title="Please note") %}
|
||||
|
||||
When this is changed, you must re-generate all preview images. Check
|
||||
the api for this, there is an endpoint to regenerate all preview
|
||||
|
@ -7,7 +7,8 @@ insert_anchor_links = "right"
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# Introduction
|
||||
# Joex
|
||||
## Introduction
|
||||
|
||||
Joex is short for *Job Executor* and it is the component managing long
|
||||
running tasks in docspell. One of these long running tasks is the file
|
||||
@ -30,7 +31,7 @@ compete on getting the next job from the queue. After a job finishes
|
||||
and no job is waiting in the queue, joex will sleep until notified
|
||||
again. It will also periodically notify itself as a fallback.
|
||||
|
||||
# Task vs Job
|
||||
## Task vs Job
|
||||
|
||||
Just for the sake of this document, a task denotes the code that has
|
||||
to be executed or the thing that has to be done. It emerges in a job,
|
||||
@ -39,7 +40,7 @@ up and executed eventually. A job maintains a state and other things,
|
||||
while a task is just code.
|
||||
|
||||
|
||||
# Scheduler and Queue
|
||||
## Scheduler and Queue
|
||||
|
||||
The scheduler is the part that runs and monitors the long running
|
||||
jobs. It works together with the job queue, which defines what job to
|
||||
@ -62,7 +63,7 @@ logged in, jobs are more important that those submitted when not
|
||||
logged in.
|
||||
|
||||
|
||||
# Scheduler Config
|
||||
## Scheduler Config
|
||||
|
||||
The relevant part of the config file regarding the scheduler is shown
|
||||
below with some explanations.
|
||||
@ -130,7 +131,7 @@ reach a joex component. This periodic wakup is just to ensure that
|
||||
jobs are eventually run.
|
||||
|
||||
|
||||
# Periodic Tasks
|
||||
## Periodic Tasks
|
||||
|
||||
The job executor can execute tasks periodically. These tasks are
|
||||
stored in the database such that they can be submitted into the job
|
||||
@ -139,7 +140,7 @@ something with a task. So a periodic task is never submitted twice. It
|
||||
is also not submitted, if a previous task has not finished yet.
|
||||
|
||||
|
||||
# Starting on demand
|
||||
## Starting on demand
|
||||
|
||||
The job executor and rest server can be started multiple times. This
|
||||
is especially useful for the job executor. For example, when
|
||||
@ -154,7 +155,7 @@ Once the files have been processced you can stop the additional
|
||||
executors.
|
||||
|
||||
|
||||
# Shutting down
|
||||
## Shutting down
|
||||
|
||||
If a job executor is sleeping and not executing any jobs, you can just
|
||||
quit using SIGTERM or `Ctrl-C` when running in a terminal. But if
|
||||
|
@ -1,10 +1,15 @@
|
||||
+++
|
||||
title = "JSON (mini) query"
|
||||
weight = 58
|
||||
template = "docs.html"
|
||||
page_template = "docs.html"
|
||||
|
||||
[extra]
|
||||
mktoc = true
|
||||
hidden = true
|
||||
+++
|
||||
|
||||
# JSON Miniquery
|
||||
|
||||
A "JSON mini query" is a simple expression that evaluates to `true` or
|
||||
`false` for any given JSON value.
|
||||
|
||||
|
@ -3,15 +3,14 @@ title = "Query Language"
|
||||
weight = 55
|
||||
description = "The query language is a powerful way to search for documents."
|
||||
insert_anchor_links = "right"
|
||||
[extra]
|
||||
mktoc = true
|
||||
template = "docs.html"
|
||||
+++
|
||||
|
||||
# Query Language
|
||||
|
||||
Docspell uses a query language to provide a powerful way to search for
|
||||
your documents. It is targeted at "power users" and it needs to be
|
||||
enabled explicitely in your user settings to be used on the search
|
||||
page.
|
||||
your documents. It currently needs to be enabled explicitely in your
|
||||
user settings to be used on the search page.
|
||||
|
||||
<div class="colums">
|
||||
|
||||
|
@ -6,6 +6,4 @@ insert_anchor_links = "right"
|
||||
template = "pages.html"
|
||||
redirect_to = "docs/tools/cli/"
|
||||
sort_by = "weight"
|
||||
[extra]
|
||||
mktoc = false
|
||||
+++
|
||||
|
@ -10,17 +10,22 @@ There is a simple Android App available to conveniently upload files
|
||||
from your android devices. Combined with a scanner app, this allows to
|
||||
very quickly scan single page documents like receipts.
|
||||
|
||||
<div class="columns is-vcentered is-centered">
|
||||
<div class="column">
|
||||
<div class="grid grid-cols-2 gap-8 divide-x ">
|
||||
<div class="flex items-center justify-center">
|
||||
<a href="https://f-droid.org/packages/org.docspell.docspellshare">
|
||||
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||
alt="Get it on F-Droid"
|
||||
style="height:120px;"/>
|
||||
class="w-56"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="column">
|
||||
Download the APK from <a href="https://github.com/docspell/android-client/releases/latest">here</a>
|
||||
<div class="flex items-center justify-center text-xl">
|
||||
<i class="fa fa-download mr-2"></i>
|
||||
<span>
|
||||
<a href="https://github.com/docspell/android-client/releases/latest">Download the APK</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -43,32 +48,30 @@ The app is very simple:
|
||||
- You can now either select an URL from the app, or the upload begins
|
||||
immediatly if you set a default URL.
|
||||
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="grid grid-cols-3 gap-4 mx-6 my-4">
|
||||
<div class="shadow dark:shadow-stone-600">
|
||||
{{ imgnormal(file="screenshot-create.jpg", width="") }}
|
||||
<p class="has-text-centered subtitle"> (A) </p>
|
||||
<p class="text-center font-mono"> (A) </p>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="box-shadow">
|
||||
{{ imgnormal(file="screenshot-choose.jpg", width="") }}
|
||||
<p class="has-text-centered subtitle"> (B) </p>
|
||||
<p class="text-center font-mono"> (B) </p>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="box-shadow">
|
||||
{{ imgnormal(file="screenshot-options.jpg", width="") }}
|
||||
<p class="has-text-centered subtitle"> (C) </p>
|
||||
<p class="text-center font-mono"> (C) </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="box-shadow">
|
||||
{{ imgnormal(file="screenshot-default.jpg", width="") }}
|
||||
<p class="has-text-centered subtitle"> (D) </p>
|
||||
<p class="text-center font-mono"> (D) </p>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="box-shadow">
|
||||
{{ imgnormal(file="screenshot-share.jpg", width="") }}
|
||||
<p class="has-text-centered subtitle"> (E) </p>
|
||||
<p class="text-center font-mono"> (E) </p>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="box-shadow">
|
||||
{{ imgnormal(file="screenshot-uploading.jpg", width="") }}
|
||||
<p class="has-text-centered subtitle"> (F) </p>
|
||||
<p class="text-center font-mono"> (F) </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,84 +0,0 @@
|
||||
+++
|
||||
title = "Browser Extension (Firefox)"
|
||||
description = "An extension for firefox to upload files from your browser via right-click → upload to docspell."
|
||||
weight = 40
|
||||
+++
|
||||
|
||||
The idea is to click on a file in firefox and send it to docspell. It
|
||||
is downloaded in the context of your current page. Then handed to an
|
||||
application that pushes it to docspell. There is a browser add-on
|
||||
implementing this in `tools/webextension`. This add-on only works with
|
||||
firefox.
|
||||
|
||||
Installation is a bit complicated, since you need to install external
|
||||
tools and the web extension. Both work together.
|
||||
|
||||
# Install `dsc`
|
||||
|
||||
First copy the [dsc](@/docs/tools/cli.md) tool somewhere in your
|
||||
`PATH`, maybe `/usr/local/bin`.
|
||||
|
||||
|
||||
# Install the native part
|
||||
|
||||
Then install the "native" part of the web extension:
|
||||
|
||||
Copy or symlink the `native.py` script into some known location. For
|
||||
example:
|
||||
|
||||
``` bash
|
||||
ln -s ~/docspell-checkout/tools/webextension/native/native.py /usr/local/share/docspell/native.py
|
||||
```
|
||||
|
||||
Then copy the `app_manifest.json` to
|
||||
`$HOME/.mozilla/native-messaging-hosts/docspell.json`. For example:
|
||||
|
||||
``` bash
|
||||
cp ~/docspell-checkout/tools/webextension/native/app_manifest.json ~/.mozilla/native-messaging-hosts/docspell.json
|
||||
```
|
||||
|
||||
See
|
||||
[here](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests#manifest_location)
|
||||
for details.
|
||||
|
||||
And you might want to modify this json file, so the path to the
|
||||
`native.py` script is correct (it must be absolute).
|
||||
|
||||
If the `dsc` tool is in your `$PATH`, then this should work. You need
|
||||
to provide a default source id in your `~/.config/dsc/config.toml` so
|
||||
that the upload command can be used without further arguments.
|
||||
|
||||
Otherwise, edit the `native.py` script and change the path to the tool
|
||||
and/or the arguments. Or create a file
|
||||
`$HOME/.config/docspell/dsc.cmd` whose content is the path to the
|
||||
`dsc` tool.
|
||||
|
||||
|
||||
# Install the extension
|
||||
|
||||
An extension file can be build using the `make-xpi.sh` script. But
|
||||
installing it in "standard" firefox won't work, because [Mozilla
|
||||
requires extensions to be signed by
|
||||
them](https://wiki.mozilla.org/Add-ons/Extension_Signing). This means
|
||||
creating an account and going through some process…. So here are two
|
||||
alternatives:
|
||||
|
||||
1. Open firefox and type `about:debugging` in the addressbar. Then
|
||||
click on *'Load Temporary Add-on...'* and select the
|
||||
`manifest.json` file. The extension is now installed. The downside
|
||||
is, that the extension will be removed once firefox is closed.
|
||||
2. Use Firefox ESR, which allows to install Add-ons not signed by
|
||||
Mozilla. But it has to be configured: Open firefox and type
|
||||
`about:config` in the address bar. Search for key
|
||||
`xpinstall.signatures.required` and set it to `false`. This is
|
||||
described on the last paragraph on [this
|
||||
page](https://support.mozilla.org/en-US/kb/add-on-signing-in-firefox).
|
||||
|
||||
When you right click on a file link, there should be a context menu
|
||||
entry *'Docspell Upload Helper'*. The add-on will download this file
|
||||
using the browser and then send the file path to the `native.py`
|
||||
script. This script will in turn call `dsc` which finally uploads it
|
||||
to your configured URLs.
|
||||
|
||||
Open the Add-ons page (`Ctrl`+`Shift`+`A`), the new add-on should be
|
||||
there.
|
@ -4,7 +4,8 @@ description = "A command line interface to."
|
||||
weight = 5
|
||||
+++
|
||||
|
||||
# Introduction
|
||||
# Docspell CLI
|
||||
## Introduction
|
||||
|
||||
The **d**oc**s**pell **c**lient, short
|
||||
[dsc](https://github.com/docspell/dsc), is a tool to use
|
||||
@ -17,7 +18,7 @@ directory.
|
||||
It is a work in progress; eventually most of the
|
||||
[api](@/docs/api/_index.md) will be covered.
|
||||
|
||||
# Usage
|
||||
## Usage
|
||||
|
||||
Download the binary for your architecture from the [release
|
||||
page](https://github.com/docspell/dsc/releases/latest) and rename it
|
||||
@ -86,11 +87,9 @@ you need to `login` again.
|
||||
|
||||
## Demo
|
||||
|
||||
<div class="columns is-centered is-full-width">
|
||||
<div class="column">
|
||||
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
||||
</div>
|
||||
</div>
|
||||
<figure>
|
||||
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
||||
</figure>
|
||||
|
||||
|
||||
# Use Cases / Examples
|
||||
|
@ -4,7 +4,9 @@ description = "Import your data from paperless."
|
||||
weight = 60
|
||||
+++
|
||||
|
||||
# Introduction
|
||||
# Import from Paperless
|
||||
|
||||
## Introduction
|
||||
|
||||
Coming from
|
||||
[paperless](https://github.com/the-paperless-project/paperless/), the
|
||||
@ -15,7 +17,7 @@ importing your data from paperless into docspell.
|
||||
|
||||
The script imports the files and also tags and correspondents.
|
||||
|
||||
{% infobubble(mode="info", title="⚠ Please note") %}
|
||||
{% infobubble(title="Note") %}
|
||||
|
||||
The script was written some while ago. It currently doesn't work out
|
||||
of the box, but is a good starting point as the issues are most
|
||||
@ -25,7 +27,7 @@ issue](https://github.com/eikek/docspell/issues/1241).
|
||||
|
||||
{% end %}
|
||||
|
||||
# Usage
|
||||
## Usage
|
||||
|
||||
Copy the script to the machine where paperless is running. Run it with
|
||||
the following arguments:
|
||||
|
@ -4,6 +4,8 @@ description = "Start a SMTP server that forwards all mails to docspell."
|
||||
weight = 50
|
||||
+++
|
||||
|
||||
# SMTP Gateway with Exim
|
||||
|
||||
One possible use case for the [integration
|
||||
endpoint](@/docs/api/upload.md#integration-endpoint) is a SMTP server
|
||||
that forwards all local mail to docspell. This way there is no
|
||||
|
@ -5,6 +5,7 @@ weight = 90
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# Auto-Tagging
|
||||
|
||||
Auto-Tagging must be enabled in the collective profile. Docspell can
|
||||
go through your items periodically and learn from your existing tags.
|
||||
@ -20,7 +21,7 @@ determined by looking at the text of the document. It would mean that
|
||||
Docspell could learn relationships that are not correct and then tag
|
||||
the next incoming items with `Done`.
|
||||
|
||||
{{ figure(file="collective-settings-autotag.png") }}
|
||||
{{ figure2(light="collective-settings-autotag.png", dark="collective-settings-autotag_dark.png") }}
|
||||
|
||||
That is why you need to specify what tags to learn. This is done by
|
||||
defining whitelist or a blacklist of tag categories. When defining a
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 12 KiB |
BIN
website/site/content/docs/webapp/bookmarks-01_dark.png
Normal file
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 84 KiB |
BIN
website/site/content/docs/webapp/bookmarks-02_dark.png
Normal file
After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
BIN
website/site/content/docs/webapp/bookmarks-03_dark.png
Normal file
After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 72 KiB |
BIN
website/site/content/docs/webapp/bookmarks-04_dark.png
Normal file
After Width: | Height: | Size: 76 KiB |
@ -5,6 +5,8 @@ weight = 35
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# Bookmarks
|
||||
|
||||
Bookmarks allow you to save queries under a name and refer to it from the search menu.
|
||||
|
||||
## Creating bookmarks
|
||||
@ -12,13 +14,13 @@ Bookmarks allow you to save queries under a name and refer to it from the search
|
||||
Bookmarks can be created from the search view. Apply some criteria to
|
||||
select items and then click on the top left menu.
|
||||
|
||||
{{ figure(file="bookmarks-02.png") }}
|
||||
{{ figure2(light="bookmarks-02.png", dark="bookmarks-02_dark.png") }}
|
||||
|
||||
This opens a small form right below the search bar where you can
|
||||
adjust the query and enter the name. You can also decide whether this
|
||||
bookmark is for all users or just for you.
|
||||
|
||||
{{ figure(file="bookmarks-03.png") }}
|
||||
{{ figure2(light="bookmarks-03.png", dark="bookmarks-03_dark.png") }}
|
||||
|
||||
The other way is to go to *Manage Data* where you can edit and delete
|
||||
existing bookmarks and also create new ones.
|
||||
@ -31,8 +33,8 @@ that shows you all your bookmarks as well as your shares. Clicking one
|
||||
"enables" it, meaning the query is used in conjunction with other
|
||||
criteria.
|
||||
|
||||
<div class="columns is-centered">
|
||||
{{ imgnormal(file="bookmarks-01.png", width="") }}
|
||||
<div class="flex items-center justify-center">
|
||||
{{ imgnormal2(light="bookmarks-01.png", dark="bookmarks-01_dark.png", width="") }}
|
||||
</div>
|
||||
|
||||
An active bookmark has a check icon next to its name.
|
||||
@ -47,7 +49,7 @@ registered users), expired shares are shown as well.
|
||||
The *Manage Data* page has a section for bookmarks. There you can
|
||||
delete and edit bookmarks.
|
||||
|
||||
{{ figure(file="bookmarks-04.png") }}
|
||||
{{ figure2(light="bookmarks-04.png", dark="bookmarks-04_dark.png") }}
|
||||
|
||||
The personal bookmarks are only visible to you. The collective
|
||||
bookmarks are visible to every user in the collective, which also
|
||||
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 156 KiB |
@ -3,11 +3,13 @@ title = "Curate Items"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
# Curate items
|
||||
|
||||
Curating the items meta data helps finding them later. This page
|
||||
describes how you can quickly go through those items and correct or
|
||||
amend with existing data.
|
||||
|
||||
# Select New items
|
||||
## Select New items
|
||||
|
||||
After files have been uploaded and the job executor created the
|
||||
corresponding items, they will show up on the main page. All items the
|
||||
@ -15,14 +17,14 @@ job executor has just created are initially marked as *New*. The
|
||||
option *Inbox* in the left search menu can be used to select only new
|
||||
items:
|
||||
|
||||
{{ figure(file="docspell-curate-1.png") }}
|
||||
{{ figure2(light="docspell-curate-1.png", dark="docspell-curate-1_dark.png") }}
|
||||
|
||||
Then you can go through all new items and check their metadata: Click
|
||||
on the first item to open the detail view. This shows the documents
|
||||
and the meta data in the header.
|
||||
|
||||
|
||||
# Modify if necessary
|
||||
## Modify if necessary
|
||||
|
||||
You can compare the data with the documents and change as you like.
|
||||
Since the item status is *New*, you'll see the suggestions docspell
|
||||
@ -31,7 +33,7 @@ select another one by clicking its name in the suggestion list. In
|
||||
state *New* the left menu is fully expanded so you see all suggestions
|
||||
immediatly.
|
||||
|
||||
{{ figure(file="docspell-curate-3.png") }}
|
||||
{{ figure2(light="docspell-curate-3.png", dark="docspell-curate-3_dark.png") }}
|
||||
|
||||
|
||||
When you change something in the form, it is immediatly applied.
|
||||
@ -39,13 +41,11 @@ When you change something in the form, it is immediatly applied.
|
||||
It is also possible to change tags and folders in the list view via
|
||||
drag&drop.
|
||||
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-narrow">
|
||||
{{ imgnormal(file="drop-tag.png", width="500px") }}
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
{{ imgnormal2(light="drop-tag.png", dark="drop-tag_dark.png", width="500px") }}
|
||||
</div>
|
||||
|
||||
# Confirm
|
||||
## Confirm
|
||||
|
||||
If everything looks good, click the *Confirm* button to confirm the
|
||||
current data. The *New* status goes away and also the suggestions are
|
||||
@ -54,10 +54,10 @@ before. You can always go back by clicking the *Unconfirm* button at
|
||||
the right of the menu bar.
|
||||
|
||||
|
||||
{{ figure(file="docspell-curate-5.png") }}
|
||||
{{ figure2(light="docspell-curate-5.png", dark="docspell-curate-5_dark.png") }}
|
||||
|
||||
|
||||
# Proceed with next item
|
||||
## Proceed with next item
|
||||
|
||||
To look at the next item in the search results, click the *Next*
|
||||
button in the menu (next to the *Edit* button). Clicking next, will
|
||||
@ -65,4 +65,4 @@ keep the current view, so you can continue checking the data. If you
|
||||
are on the last item, the view switches to the listing view when
|
||||
clicking *Next*.
|
||||
|
||||
{{ figure(file="docspell-curate-6.png") }}
|
||||
{{ figure2(light="docspell-curate-6.png", dark="docspell-curate-6_dark.png") }}
|
||||
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 84 KiB |
BIN
website/site/content/docs/webapp/custom-fields-01_dark.png
Normal file
After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 128 KiB |
BIN
website/site/content/docs/webapp/custom-fields-02_dark.png
Normal file
After Width: | Height: | Size: 135 KiB |
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 39 KiB |
BIN
website/site/content/docs/webapp/custom-fields-05_dark.png
Normal file
After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 100 KiB |
BIN
website/site/content/docs/webapp/custom-fields-06_dark.png
Normal file
After Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 133 KiB |
BIN
website/site/content/docs/webapp/custom-fields-07_dark.png
Normal file
After Width: | Height: | Size: 139 KiB |
@ -3,6 +3,8 @@ title = "Custom Fields"
|
||||
weight = 18
|
||||
+++
|
||||
|
||||
# Custom Fields
|
||||
|
||||
Custom fields allow to attach user defined metadata to items. For
|
||||
example, you may want to track the amount of each receipt or the
|
||||
invoice number etc. You can define fields that can be associated to
|
||||
@ -15,7 +17,7 @@ Custom fields can be deactivated in the user settings.
|
||||
Go to the _Manage Data_ page, that can be reached from the top right
|
||||
menu. One entry at the left shows _Custom Fields_:
|
||||
|
||||
{{ figure(file="custom-fields-01.png") }}
|
||||
{{ figure2(light="custom-fields-01.png", dark="custom-fields-01_dark.png") }}
|
||||
|
||||
Fields are defined per collective. They can also be created in the
|
||||
item edit menu (just like creating organizations). The `#Usage`
|
||||
@ -23,7 +25,7 @@ columns show how many items have a value for this field.
|
||||
|
||||
A field consists of a name, a format and optional a label:
|
||||
|
||||
{{ figure(file="custom-fields-02.png") }}
|
||||
{{ figure2(light="custom-fields-02.png", dark="custom-fields-02_dark.png") }}
|
||||
|
||||
The name and format is required. The name must be unique among all
|
||||
your fields and it is special in that it must be a valid _identifier_:
|
||||
@ -73,7 +75,7 @@ corresponding input field is shown asking for values. You can select
|
||||
multiple fields. Only one value is allowed to set per item and field.
|
||||
The example below shows a text field and a money field:
|
||||
|
||||
{{ figure(file="custom-fields-03.png") }}
|
||||
{{ figure2(light="custom-fields-03.png", dark="custom-fields-03_dark.png") }}
|
||||
|
||||
You can create new fields right here without going to the _Manage
|
||||
Data_ page, by clicking the plus icon (1). The format of each field is
|
||||
@ -83,14 +85,13 @@ As soon as a correct value is typed in, it is saved to the item and
|
||||
shown in the header next to the tags. If you click the trash-can icon
|
||||
next to an input, the value is removed from the item.
|
||||
|
||||
{{ figure(file="custom-fields-04.png") }}
|
||||
{{ figure2(light="custom-fields-04.png", dark="custom-fields-04_dark.png") }}
|
||||
|
||||
The item card also shows custom fields, in the same place as tags:
|
||||
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-one-quarter">
|
||||
{{ imgnormal(file="custom-fields-05.png", width=300) }}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-center">
|
||||
{{ imgnormal2(light="custom-fields-05.png", dark="custom-fields-05_dark.png", width=300) }}
|
||||
</div>
|
||||
|
||||
Adding values for custom fields in
|
||||
@ -102,13 +103,13 @@ Adding values for custom fields in
|
||||
The search menu shows the same dropdown for selecting a custom field.
|
||||
Then you can set values that are matched against your items.
|
||||
|
||||
{{ figure(file="custom-fields-06.png") }}
|
||||
{{ figure2(light="custom-fields-06.png", dark="custom-fields-06_dark.png") }}
|
||||
|
||||
Values are also validated in the search form. Only valid values are
|
||||
sent to the server for searching. There is one exception: you can use
|
||||
a wildcard at beginning and/or end to do a substring match:
|
||||
|
||||
{{ figure(file="custom-fields-07.png") }}
|
||||
{{ figure2(light="custom-fields-07.png", dark="custom-fields-07_dark.png") }}
|
||||
|
||||
For all numeric and money values, a little summary is displayed next
|
||||
to the overall item count at the top of the page.
|
||||
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 215 KiB |
BIN
website/site/content/docs/webapp/dashboards-01_dark.png
Normal file
After Width: | Height: | Size: 234 KiB |
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 137 KiB |
BIN
website/site/content/docs/webapp/dashboards-02_dark.png
Normal file
After Width: | Height: | Size: 140 KiB |
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 185 KiB |
BIN
website/site/content/docs/webapp/dashboards-03_dark.png
Normal file
After Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 123 KiB |
BIN
website/site/content/docs/webapp/dashboards-04_dark.png
Normal file
After Width: | Height: | Size: 127 KiB |
BIN
website/site/content/docs/webapp/dashboards-05_dark.png
Normal file
After Width: | Height: | Size: 228 KiB |
@ -5,18 +5,20 @@ weight = 5
|
||||
mktoc = true
|
||||
+++
|
||||
|
||||
# Dashboards
|
||||
|
||||
The main page shows a dashboard that can be configured to show some
|
||||
aspects of your documents. The following shows the default dashboard
|
||||
that is bundled in the application:
|
||||
|
||||
{{ figure(file="dashboards-01.png") }}
|
||||
{{ figure2(light="dashboards-01.png", dark="dashboards-01_dark.png") }}
|
||||
|
||||
It shows a predefined set of information, which can be customized. You
|
||||
can create multiple dashboards and switch between them, you can also
|
||||
define one as the "default" which is shown when the page loads.
|
||||
|
||||
|
||||
# Side menu
|
||||
## Side menu
|
||||
|
||||
The side menu contains a list of useful links. The first loads the
|
||||
default dashboard. All others (and more) are available through the
|
||||
@ -29,7 +31,7 @@ The _Settings_ section contains some links to useful settings and the
|
||||
_Manage_ section has links to metadata that can be managed separately.
|
||||
These links are fixed and cannot be changed.
|
||||
|
||||
# Dasbhoard properties
|
||||
## Dasbhoard properties
|
||||
|
||||
The main component on this page is the "dashboard". A dashboard has
|
||||
the following properties (all required):
|
||||
@ -57,7 +59,7 @@ removing boxes and the dashboard properties.
|
||||
|
||||
After clicking _Edit Dashboard_ the dashboard changes into a form:
|
||||
|
||||
{{ figure(file="dashboards-02.png") }}
|
||||
{{ figure2(light="dashboards-02.png", dark="dashboards-02_dark.png") }}
|
||||
|
||||
Note the message on the top: it indicates that this dashboard is the
|
||||
bundled one that is used only if there are no custom ones available.
|
||||
@ -72,19 +74,19 @@ reorder the boxes using the arrow buttons or drag and drop. When
|
||||
satisfied, click _Submit_. In the example, the last two boxes are
|
||||
removed and box decorations are enabled for the field overview box.
|
||||
|
||||
{{ figure(file="dashboards-03.png") }}
|
||||
{{ figure2(light="dashboards-03.png", dark="dashboards-03_dark.png") }}
|
||||
|
||||
When you now edit this dasbhoard again, the message is gone and you
|
||||
can change the dashboard and also delete it. You can also create a new
|
||||
dashboard or copy the current one.
|
||||
|
||||
{{ figure(file="dashboards-04.png") }}
|
||||
{{ figure2(light="dashboards-04.png", dark="dashboards-04_dark.png") }}
|
||||
|
||||
In this example, the dashboard was copied, then the message was
|
||||
changed and it was set to the default dashboard. This is how it looks
|
||||
now:
|
||||
|
||||
{{ figure(file="dashboards-05.png") }}
|
||||
{{ figure2(light="dashboards-05.png", dark="dashboards-05_dark.png") }}
|
||||
|
||||
When there is more than one dashboard, the side menu shows all of
|
||||
them. The little house icon indicates whether this is the default
|
||||
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 246 KiB |
BIN
website/site/content/docs/webapp/docspell-curate-3_dark.png
Normal file
After Width: | Height: | Size: 251 KiB |